解析器与词法分析器和XML

时间:2010-09-02 02:07:15

标签: xml parsing tokenize lexer dfa

我正在阅读有关编译器和解析器架构的内容,我想知道一件事...... 当您拥有XML,XHTML,HTML或任何基于SGML的语言时, 词法分析器的角色在哪里以及令牌是什么?

我已经读过,令牌就像一样,是为 lexer 解析而准备的。虽然我没有找到用于语言行C,C ++,Pascal等的令牌的问题,其中有关键字,名称,文字和其他由空格分隔的类似字符串的字符串,但是我有一个问题,因为它没有'任何话!它只是与标记(标记)交错的纯文本。

我心里想,可能是这些标签和纯文本片段都是令牌,类似于:[TXT][TAG][TAG][TXT][TAG][TXT][TAG][TAG][TXT]...。这是非常合理的,因为SGML不关心标记分隔符<>内部的内容(当它发现?或{{1时,它会识别特殊处理指令和定义)作为下一个字符;注释也属于该组),SGML tokenizer可以作为XML / HTML / XHTML解析器的基础。

然后我意识到标记中可能会有!个字符作为其他语法的一部分:属性值: - /即使将<个字符放在属性中也不是一个好主意值(最好使用<),许多浏览器和编辑器处理这些问题并将这些&lt;视为属性值的一部分,而不是标记分隔符。

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

你的看法是什么?从标签(标记)和纯文本制作标记是否合适?

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

那么解析类似SGML的语言的最佳方法是什么?那个词法分析器真的用在那里吗?如果是,那么什么字符串构成了令牌?

1 个答案:

答案 0 :(得分:12)

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

Lexemes一般应该是可识别的语言元素。

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

相对应
  • TAGBEGIN,&lt; NAME
  • 形式的东西
  • TAGEND,&gt;
  • 的形式
  • TAGCLOSE,格式为&lt; / NAME&gt;
  • TAGENDANDCLOSE格式 /&gt; (仅限XML)
  • ATTRIBUTENAME, NAME
  • EQUALSIGN,正是 =
  • ATTRIBUTEVALUE,是属性所代表的确切字符串的值,不管引号(或甚至没有引号,对于旧HTML)。如果属性中有转义的字符代码,则应将这些代码转换为实际的字符代码。
  • CONTENT,这是TAGEND和TAGBEGIN之间的文字。与ATTRIBUTEVALUES一样,任何转义字符都应转换,因此&lt; B&gt; foo&lt; bar&lt; / B&gt; 之间的内容将转换为文本 foo&lt; bar 如果您希望将实体调用保持为单独的令牌,则可以这样做,在TAGEND和TAGSTART之间生成CONTENT和ENTITYINVOCATION令牌流;取决于你的目标是什么。

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

如果我们忽略了DTD和XML的Schema的复杂性,那就是你真正需要的。

词法分析器如何生成这些更复杂;使用XML和HTML,与输入流中的转义有很多混乱,&lt; [CDATA ...]&gt; (如果我有这个权利)这只是一个有趣的引用,并在内容词汇产生时消失。要处理这一切,你需要一个非常复杂的词法引擎。 是的,作为实际问题,你需要不同的词汇状态(“模式”)来处理文本的不同部分。我几乎有一个主要模式来处理&lt; ... &gt; 中的内容,以及一个处理CONTENT的主要模式。