为编程语言编写解析器:输出

nap*_*pco 3 c++ parsing lexer output

我正在尝试用C++编写一个简单的解释型编程语言.我读过很多人使用像Lex/Flex Bison这样的工具来避免"重新发明轮子",但由于我的目标是了解这些小动物是如何改善我的知识的,所以我决定写出Lexer和从头开始解析.目前我正在研究解析器(词法分析器已完成),我问自己它的输出应该是什么.一颗树?带有"深度"或"移位"参数的语句的线性向量?我该如何管理循环和if语句?我应该用隐形goto语句替换它们吗?

小智 7

解析器几乎总是输出AST.从最广泛的意义上讲,AST简单地表示了程序的句法结构.Function成为包含函数体AST的AST节点.An if成为包含条件和主体的AST的AST节点.运算符的使用成为包含每个操作数的AST的AST节点.整数文字,变量名等成为叶AST节点.运算符优先级等在节点的关系中是隐含的:Both 1 * 2 + 3(1 * 2) + 3表示为Add(Mul(Int(1), Int(2)), Int(3)).

AST中的内容的许多细节取决于您的语言(显然)以及您想要对树做什么.如果要分析和转换程序(即在最后拆分更改的源代码),您可以保留注释.如果需要详细的错误消息,可以添加源位置(如,此整数文字位于第5行第12列).

编译器将继续将AST转换为不同的格式(例如,带有gotos 的线性IR 或数据流图).通过AST仍然是一个好主意,因为精心设计的AST在面向语法方面具有良好的平衡,但只存储对理解程序很重要的内容.解析器可以专注于解析,同时保护以后的转换免受不相关的细节,例如空白量和运算符优先级.请注意,这样的"编译器"也可能输出稍后解释的字节码(Python的参考实现会这样做).

相对纯粹的解释器可能会解释AST.关于这一点已经写了很多; 它是执行解析器输出的最简单方法.这种策略从AST中获益的方式与编译器非常相似; 特别是大多数解释只是自上而下的AST遍历.