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

(我看到這個問題還活着。我找到了解決方案,它自己。)

首先我威脅(...)[...]表達式作爲一個令牌和擴大這些(在需要時遞歸)。然後我檢測函數調用和數組下標。如果在加括號的標記之前沒有中綴運算符,那麼這是一個函數調用或數組下標,所以我在那裏插入一個特殊的調用函數或訪問運算符。通過這種修改,它就像魅力一樣。

相關問題