在其中我对解析和语法有看法。

主要观点、关键信息和重要细节总结:

  • 介绍:作者自青少年时期就对解析感兴趣,设计并实现过编程语言的解析器,对解析器生成技术有深入研究和实践,此文旨在表达关于解析的诸多观点。
  • 上下文无关文法不如期望的那样声明式

    • 上下文无关文法是指定语言语法的标准,但并非总能实现声明式编程的理想,如在 C 语言中编写文法时需考虑实现细节,易出现错误。
    • 简单的语法概念写成 CFG 可能变复杂,如 C 语言中for语句、if-else歧义等情况,要写出无歧义的 CFG 需引入额外复杂性。
    • CFG 必须适应解析器技术,不同的解析器生成策略对文法规则的写法有不同要求,如 LL 解析工具支持一些正则表达式类似的操作,LR 则需保持多种可能性在最后时刻,且左右递归等写法在不同解析器中含义不同。
  • 可能想手写生产解析器

    • 自动化解析器生成器虽有优势,但对于严肃的工具,如广泛使用的 GCC,最终会切换到手写解析器,因为手写解析器更灵活,能更好地处理语言规范的变化,且能写出更好的错误消息。
    • 自动化解析器在生成错误消息方面表现不佳,难以准确指出错误原因,而手写解析器可根据上下文写出更易理解的错误消息。
    • 自动化解析器在语言设计阶段很有用,能快速得到解析器,但在生产编译器中通常不使用。
  • 在语言规范中指定解析器生成技术

    • 语言规范中使用上下文无关文法时,应明确说明该文法与哪种解析技术兼容,最好以机器可读的形式提供文法,便于自动转换和测试。
    • 测试语言的参考文法可确保文法无错误,也可通过解析器生成测试用例,检查手写解析器的正确性。
  • 在语言设计中使用 LR 解析器生成器

    • LR 解析器生成器在语言设计阶段非常有用,能指出设计错误,如 C 语言中逗号运算符和函数参数的歧义,可通过限制为 LR 文法来避免。
    • LR 解析器生成器还能生成测试用例,检查手写解析器的正确性,但%prec等特性会影响测试用例的生成。
  • 停止使用 LALR

    • LR 解析技术中的 LALR 会引入“神秘冲突”,其实是生成算法的 bug,David Pager 的 PGM 技术可避免该问题,构造出几乎与 LALR 一样小的解析表且无错误。
    • PGM 有弱和强两种算法,弱算法简单但可能保守,强算法更精确但复杂。
  • 文法应兼具合成性和分析性

    • 上下文无关文法的术语暗示其是合成性的,但实际应用中多为分析性的,可通过文法生成测试用例和进行语法到抽象语法树的转换。
    • 避免使用歧义文法和%prec等特性,以保证文法的合成性和可靠性。
  • 应做的事情

    • 考虑将实际写的文法与用于自动化的无歧义文法分离,用宏库或文法编译器生成繁琐部分,或处理输入文法生成完全不同的无歧义 CFG。
    • 扩展上下文无关文法的概念,为每个操作符添加优先级等注释,使 LR 解析器能处理歧义,还可实现动态重配置操作符等功能。
  • 处理非 LR 语言的方法

    • 对于一些不能用正统 LR 策略解析的语言,如 C 语言的类型名歧义、C++的尖括号与移位运算符、有显著空白的语言等,可通过“LR 带属性”的方法或在 lexer 和 parser 之间插入“过滤器”层来处理。
  • 结论:上下文无关文法和自动化解析器生成虽有优势,但在实际生产中仍存在不足,很难说应如何改进它们的设计。

总之,作者对上下文无关文法和解析器生成技术进行了深入探讨,指出了它们的优点和不足,并提出了一些改进的想法和方法。

阅读 12
0 条评论