【发布时间】:2010-12-11 19:39:38
【问题描述】:
我正在为类似 javascript 的语言编写一个编译器,只是为了好玩。又名我正在学习轮子,所以我为自己制作了一个并试图找出所有内容,但现在我被卡住了。
我知道在解析简单的中缀表达式时,调车场算法是一个不错的算法。我能够弄清楚如何为前缀和后缀运算符扩展该算法,并且还能够解析简单的函数。
例如:2+3*a(3,5)+b(3,5) 变成2 3 <G> 3 5 a () * + <G> 3 5 b () +
(<G> 是一个保护令牌,它被压入堆栈,它将存储返回地址等。() 是调用命令,它调用堆栈顶部的函数,弹出必要数量的参数并在返回时推回结果。)
如果函数名只是一个标记,我可以简单地将其标记为函数符号,如果直接后跟一个括号。在此过程中,如果遇到函数符号,我将其压入操作符堆栈,并在完成参数转换后将其弹出。
到目前为止,这是有效的。
但是,如果我添加具有成员函数的选项,. 运算符。事情变得更加棘手。例如我想转换 a.b.c(12)+d.e.f(34) 我不能将 c 和 f 标记为函数,因为 a.b.c 和 d.e.f 是函数。如果我在这样的表达式上启动解析器,结果将是 a b . <G> 12 c () . d e . <G> 34 f () . 这显然是错误的。我希望它是<G> 12 a b . c . () <G> 34 d e . f. (),这看起来是正确的。
但是如果我添加一些括号,我可以让事情变得更复杂:(a.b.c)()。或者我创建一个函数,返回一个我再次调用的函数:f(a,b)(c,d)。
有没有简单的方法来处理这些棘手的情况?
【问题讨论】:
标签: parsing compiler-construction expression postfix-notation