1

我正在写一个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.cd.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)

有没有简单的方法来处理这些棘手的情况?

回答

0

你的方法的问题是,你把对象和它由.分开的两个独立的令牌成员。经典调车码算法对OOP一无所知,并且依靠单个令牌进行函数调用。因此,解决您的问题的第一种方法是使用一个令牌来调用对象成员 - 即整个a.b.c必须是单个令牌。

您也可以参考自动分析器生成你的问题的另一个解决方案。它们允许将目标语言(JavaScript)的完整语法定义为一组正式规则并自动生成解析器。常用工具列表包括用不同编程语言生成解析器的工具:ANTLR, Bison + Lex, Lemon + Ragel


--artem

+1

'.'与'+'一样是一个操作符。 – delnan 2011-01-14 16:50:20

+0

@delnan是对的。我们应该像普通的操作员那样对待点。 – mahdix 2017-12-04 10:37:25

0

(我看到这个问题还活着。我找到了解决方案,它自己。)

首先我威胁(...)[...]表达式作为一个令牌和扩大这些(在需要时递归)。然后我检测函数调用和数组下标。如果在加括号的标记之前没有中缀运算符,那么这是一个函数调用或数组下标,所以我在那里插入一个特殊的调用函数或访问运算符。通过这种修改,它就像魅力一样。

相关问题