我当时正在考虑制作一个Pug解析器,但是众所周知,缩进是上下文敏感的(可以通过词法分析器反馈循环对其进行微不足道的修改,使其几乎不受上下文的限制,这是Python所采用的),否则会使它不是上下文无关的吗?
XML标记绝对不是上下文无关的,每个开始标记都需要匹配一个结束标记,但是Pug没有这样的限制,这让我怀疑我们是否可以将每个开始标识符解析为一个标记根
答案 0 :(得分:1)
Pug似乎缺少的主要内容(至少是从其网站的随意扫描中得出)是对其语法的正式描述。甚至是非正式的描述。也许我找的地方不对。
不过,根据示例,它看起来并不可怕。会有一些挑战。特别是,它没有统一的标记化上下文,因此扫描器将变得复杂,而不仅仅是因为缩进问题。 (我从空白部分得到的印象是,缩进规则比Python严格得多,但是我没有找到确切的规范。在我看来,两个字符的缩进后的前导空格是重要的空白。但这并不会使事情复杂化;甚至可以简化任务。)
有趣的是处理嵌入式JavaScript。您至少需要对嵌入式JS进行标记化,并且JS规范中的一些特殊情况使得无需解析就可以轻松地标记化。无论如何,仅令牌化还不足以知道嵌入式代码在哪里终止。 (对于词汇挑战,请考虑对正则表达式文字的正确标识。/=
可能是正则表达式的开始,或者可能是除法运算符;如何对后续的{
进行标记化取决于该决定。)模板字符串提出了另一个挑战(递归嵌入)。但是,JavaScript解析器确实存在,因此您也许可以利用它。
换句话说,识别标签嵌套并不是您项目中最具挑战性的部分。一旦确定给定令牌是标签,嵌套部分就变得微不足道了(并且没有上下文),因为它是由缩进精确定义的,因此DEDENT令牌将终止标签。
但是,值得注意的是,对于XML(或类似XML的HTML变体),标签解析并不是特别具有挑战性。如果您采用XML规则,即不能省略关闭标签(自关闭标签除外),那么关闭标签中的标签名不会影响正确输入的解析。 (如果close标记中的标记名与相应的open标记中的close标记不匹配,则输入无效。但是open和close标记之间的对应关系不会改变。)即使您采用HTML-5规则,除非有特殊情况下的特殊标记名列表,否则不能省略close标记,那么从理论上讲,您可以使用CFG进行解析。 (但是,HTML-5中的各种错误恢复规则远非上下文无关,因此仅适用于不需要关闭标签重新匹配的输入。)
艾拉·巴克斯特(Ira Baxter)正是在他在评论中引用的交叉链接文章中指出了这一点:您通常可以通过在解析过程中忽略它们并在随后的分析甚至是分析中检测它们,来实现语言的上下文相关方面。解析期间的语义谓词。打开和关闭标记名的正确匹配将属于此类别,在标识符的声明不影响解析的语言中,“使用前声明”规则也属于此类。 (不是C或C ++,而是其他许多语言。)
即使不能忽略这些方面(例如,对于C typedef
而言),最简单的解决方案也可能是使用模棱两可的CFG和产生所有可能解析的解析技术。生成解析林后,您可以遍历替代方案并拒绝不一致的替代方案。 (对于C语言,这将包括一个替代解析,在该解析中,先对类型名称进行类型定义,然后在类型名称无效的上下文中使用。)