作为一个侧面项目和学习实验,我编写自己的编程语言而没有额外的预制工具,例如LLVM。
我已经编写了自己的递归下降解析器,但是我在尝试解析这样一个语句的后勤时遇到了问题:
x()()[0]()
我无法想出一个很好的方法来制作一个解析树/ AST。我曾尝试阅读其他编程语言的语法(特别是Python和C#),但我无法弄清楚他们是如何做到的。
我如何写一些东西来解析上面的语法?
答案 0 :(得分:0)
从AST的角度来看,可能有助于想象你有某种"函数调用" node,其中一个子节点表示表示要调用的函数的表达式,一个子节点表示一个参数。例如,代码fn()()[0]()
可能如下所示:
+--------+
| call |
+--------+
function / \ args
/ (null)
/
+-----------+
| selection |
+-----------+
array / \ index
/ 0
/
+--------+
| call |
+--------+
function / \ args
/ (null)
/
+--------+
| call |
+--------+
function / \ args
fn 0
就如何解析这样的东西而言,我建议将函数调用视为后缀运算符,如数组选择(arr[index]
)或成员选择(object.field
)。这个CFG片段可能如下所示:
Expr --> Expr(ArgList) |
/* other expression types */
从递归下降的角度来看,在你解析了一个表达式之后,你要先做一个预测,看看它后面是否有一个开括号。如果是这样,那意味着你刚读到的任何内容都应该被视为函数调用表达式的函数组件,而你将要阅读的是参数列表。