如何将方法调用转换为后缀表示法?

我正在编写一个类似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)
。 处理这些棘手的情况有一个简单的方法吗?     
已邀请:
您的方法的一个问题是您将对象及其成员视为由
.
分隔的两个单独的标记。经典的分流码算法对OOP一无所知,并且依赖单个令牌进行函数调用。因此解决问题的第一种方法是使用一个令牌来调用对象成员 - 即整个
a.b.c
必须是单个令牌。 您也可以参考自动解析器生成器来解决您的问题。它们允许将目标语言(JavaScript)的完整语法定义为一组正式规则并自动生成解析器。流行工具列表包括使用不同编程语言生成解析器的工具:ANTLR,Bison + Lex,Lemon + Ragel。 --artem     
(我看到这个问题仍然存在。我自己找到了解决方案。) 首先,我威胁将
(...)
[...]
表达式作为一个标记,并在需要时(递归地)扩展它们。然后我检测函数调用和数组下标。如果在带括号的标记之前没有中缀运算符,那么这是函数调用或数组下标,所以我在那里插入一个特殊的调用函数或访问运算符。通过这种修改,它就像魅力一样。     

要回复问题请先登录注册