9

我现在正在阅读有关编译器和解析器架构的信息,我想知道一件事……当您拥有 XML、XHTML、HTML 或任何基于 SGML 的语言时,词法分析器在这里的作用是什么,令牌是什么?

我读过令牌就像为lexer解析准备的单词。虽然我在查找 C、C++、Pascal 等语言的标记方面没有问题,其中有关键字、名称、文字和其他由空格分隔的类似单词的字符串,但使用 XML 我有问题,因为没有没有任何话!它只是与标记(标签)交错的纯文本。

我心想,这些标签和纯文本片段可能是标记,类似于:[TXT][TAG][TAG][TXT][TAG][TXT][TAG][TAG][TXT].... 这是相当合理的,因为 SGML 不关心标记分隔符内的内容,<并且>(好吧,它在找到?!作为下一个字符时识别特殊处理指令和定义;注释也属于该组),并且 SGML 标记器可以成为 XML/HTML/XHTML 解析器的基础。

但是后来我意识到,<作为其他语法的一部分,标记中可以填充字符:属性值:-/ 即使将<字符放在属性值中并不是一个好主意(最好使用&lt;它),许多浏览器和编辑器处理它并将它们<视为属性值的一部分,而不是标签分隔符。

它使事情变得有点复杂,因为我看不到通过词法分析器中的简单确定性有限自动机 (DFA) 来识别这样的标记的方法。当自动机在标签内时,它看起来需要一个单独的上下文,当它遇到属性值时需要另一个上下文。我认为这需要一堆状态/上下文,所以 DFA 可能无法处理。我对吗?

你有什么看法?从标签(标记)和纯文本制作标记是否很好?

在这里:http://www.antlr.org/wiki/display/ANTLR3/Parsing+XML
使用了某种不同的技术:它们将<and >(以及</and />)视为单独的标记,并在它们GENERIC_ID用作标记的标签内等.他们通常将大部分工作转移到解析器。但是他们还必须更改标记器的上下文:他们在纯文本中使用不同的上下文,并且在标记中使用不同的上下文(但我认为他们忘记了属性值上下文,因为第一次出现 of>将在他们的词法分析器中结束标记)。

那么解析类 SGML 语言的最佳方法是什么?词法分析器真的在那里使用吗?如果是,哪些字符串构成了标记?

4

1 回答 1

13

构建了 XML 和 HTML 解析器后,我有意见。

一般来说,词素应该是可识别的语言元素。

对于 XML 和 HTML,这些基本上对应于

  • TAGBEGIN,<NAME形式的东西
  • TAGEND,形式为>
  • TAGCLOSE,形式为</NAME>
  • TAGENDANDCLOSE 表单/> (仅限 XML)
  • ATTRIBUTENAME,NAME形式
  • EQUALSIGN,精确地=
  • ATTRIBUTEVALUE,是由属性表示的确切字符串的值,与引号无关(对于旧版 HTML,甚至没有引号)。如果属性内有转义字符代码,则应将这些代码转换为其实际字符代码。
  • CONTENT,即 TAGEND 和 TAGBEGIN 之间的文本。与 ATTRIBUTEVALUS 一样,应转换任何转义字符,因此 <B>foo<bar</B>之间的 CONTENT将转换为文本foo<bar 如果要将实体调用保留为单独的标记,则可以这样做,产生TAGEND 和 TAGSTART 之间的 CONTENT 和 ENTITYINVOCATION 令牌流;取决于你的目标是什么。

我们可以争论是否要为 HTML/XML 注释生成令牌。如果你这样做,你就会这样做。

如果我们忽略 DTD 和 XML 模式的复杂性,那么这就是您真正需要的。

词法分析器如何产生这些更复杂;对于 XML 和 HTML,输入流中的转义有很多混乱,<[CDATA ... ]>(如果我有这个权利)这只是一种有趣的引用,当 CONTENT 词位是时消失了产生。要处理所有这些,您需要一个非常复杂的词法分析器引擎。是的,实际上,您需要不同的词汇状态(“模式”)来处理文本的不同部分。我几乎有一种主要模式来处理< ... >里面的东西,还有一种主要模式来处理内容。

于 2010-09-02T02:35:22.903 回答