表示式解析趣談

2021-04-06 14:03:10 字數 1899 閱讀 6818

**的編譯是電腦科學的一大命題,其博大精深,難以盡數。這裡

,我們撿著乙個小命題娛樂一下。

程式**中,總是少不了數**算,其實對於我們來說很熟悉的數學計

算,在計算機裡也是要做一些編譯處理的。

例如,4+9*3+7-2這樣乙個簡單的四則運算

,對於人來說就是:

4+9*3+7-2

=4+27+7-2

=31+7-2

=38-2

=36這裡面,我們實際上已經在下意識裡做了很多思考。首先

,大腦會按照運算子劃分開各個子算式,然後找出運算優先順序的子式

,按順序計算完後,將結果填充給下一級,依次遞迴

,直至整個算式完成。

計算機的編譯/解釋過程,其實跟這個很像,也是先找出最高優先順序的

子式,然後依次遞迴構造出乙個語法解析樹,呼叫數**算指令計算每

個節點,返回結果。對於每個單步運算,計算機裡面呼叫一次+、-

、*、/的時候,其實是一次函式操作,每個運算子執行對應的函式

,比如1+1,其實就是+(1, 1)。在編譯時,通常會把這樣的運算翻譯為字尾表示式,+(1, 1)就變成了1 1 -,這樣的好處是計算機逐次讀入每乙個詞,遇到運算元就壓棧

,遇到操作符就把所需個數的運算元從棧裡彈出來計算

,然後再把結果壓進去,這個過程以輕鬆匹配複雜表示式。不過—

—這麼看起來是不很累?特別是複雜算式,就看不清層次了

。我們把它用括號包起來,就成了(1 1 -),這樣清晰一些了吧,我們現在按這種方式把開頭的那個式子寫成

: (((4 (9 3 *)+) 7+) 2 -)

現在,我們用乙個表示堆疊,左邊是棧頂,右邊是棧底

。現在我們模擬計算機的解釋過程。

(((4 (9 3 *)+) 7+) 2 -)

=>[4]                         

4入棧

=>[9 4]                         9入棧

=>[3 9 4]                      3入棧

=>* (9 3) [4]                  讀到*,彈出最上面兩個數3和9——需要注意,因為堆疊的後入先出

特性,實際上棧頂的元素反而在參數列的右邊

=>[27 4]                       把相乘以後的結果27重新壓入棧

=>+ (4 27)                  讀到+,彈出最上面兩個數27和4

=>[31]                          把相加結果31入棧

=>[7 31]                        7入棧

=>+ (31 7)                  讀到+,彈出最上面兩個數7和31

=>[38]                          把相加以後的結果38入棧

=>[2 38]                       2入棧

=>- (38 2)                   讀到-,彈出最上面兩個數2和38

=>[36]                          把相減結果36入棧

=>36                            檢測到運算過程已經完成,把結果從堆疊中彈出返回

以上這個過程對計算機是很方便,但是對於我們讀起來還是有點彆扭

,把運算子放前面不是更好懂麼?編譯原理中,字首表示式也是一種常

見的寫法,於是:

(((4 (9 3 *)+) 7+) 2 -)=>(-(+(+ 4 (* 9 3)) 7) 2)

這個麼,應該有朋友已經發現了,這不就是一段lisp**麼?!

我有很長時間不能很好的理解lisp**,直到有位朋友說

,lisp就是語法解析樹的字首表達……

以此文向他致敬!

表示式解析

1 本文目標 分析用堆疊解析算術表示式的基本方法。給出的示例 能解析任何包括 和0到9數字組成的算術表示式。2 中綴表示式和字尾表示式 中綴表示式就是通常所說的算術表示式,比如 1 2 3 4。字尾表示式是指通過解析後,運算子在運算數之後的表示式,比如上式解析成字尾表示式就是12 3 4 這種表示式...

查詢表示式解析

查詢表示式解析 1 ienumerablequery from s in names where s.length 5 orderby s select s.toupper 在語義上等同於如下 方法風格 基於方法 的查詢 ienumerablequery names where s s.length...

解析算術表示式

現有字串形式的算術表示式,求計算其值。string str1 2000 600 3 300 2 string str2 2000 600.389895334 2 300 2 6 100 求解方法如下 讀取公式,返回結果。param express 算術公式 return 結果字串 保留兩位小數 pu...