為提高教學質量,我所在的學院正在籌畫編寫c語言教材。《用c語言寫直譯器》系列文章經整理後將收入書中「綜合實驗」一章。因此該系列的文章主要閱讀物件定為剛學完c語言的學生(不要求有資料結構等其他知識),所以行文比較羅嗦,請勿見怪。本人水平有限,如有描述不恰當或錯誤之處請不吝賜教!特此宣告。
比如將中綴表示式 5 * ((10 - 1) / 3) 轉換成字尾表示式為 5 10 1 - 3 / *。其中數字 5 10 1 3 仍然按照原先的順序排列,而操作符的順序變為 - / ×,這意味著減號最先計算、其次是除號、最後才是乘號。也許你還在擔心如何將操作符從兩個運算元的中間移到它們的後邊。其實不用擔心,在完成了排序工作後你就發現它已經跑到運算元的後面了 ^_^。
從中綴表示式 1+2×3+4 中逐個獲取操作符,依次是 + × +。如果當前操作符的優先順序不大於前面的操作符時,前面操作符就要先輸出。比如例子中的第二個加號,它前面是乘號,因此乘號從這個隊伍中跑到輸出的隊伍中當了「老大」;此時第二個加號再前面的加號比較,仍然沒有比它大,因此第乙個加號也排到新隊伍中去了;最後隊伍中只剩下加號自己了,所以它也走了。得到新隊伍裡的順序 × + + 就是所求解。下面的**中詳細展示每乙個步驟。
序號輸入
臨時空間輸出1
+2×+
3++ ×4
+ × +
5+ +×6
+× +
7× + +
相信你心裡還是牽掛著那些運算元。很簡單,如果碰到的是操作符就按上面的規則處理,如果是運算元就直接輸出!下面的**加上了運算元,將輸出完整的字尾表示式。
序號輸入
臨時空間輸出1
12+1
32+1
4×+1 253
+ ×1 26+
+ ×1 2 3
7+ × +
1 2 3
8+ +
1 2 3 ×94
+1 2 3 × +10+
1 2 3 × + 4
111 2 3 × + 4 +
得到最終結果 1 2 3 × + 4 + 就是所求的字尾表示式。下面是程式中的參考**(有刪減)。
另乙個是右括號,它本身和優先順序無關,它會將臨時空間裡的操作符乙個個輸出,直到碰到左括號為止。下面是本程式中中綴轉字尾的**(有刪減)。
在上面的**中你會看到乙個陌生的函式 next_taken() 。它會從中綴表示式中獲得乙個標記,方法類似從字串中提取單詞(參看課後習題)。在本程式中能識別的標記除了操作符,還有純數字、字串、變數名等運算元。唯一要注意的就是操作符和運算元之間可以存在零到多個空格。下面是參考**(有刪減)。
我的郵箱,歡迎來信([email protected])
我的blogger(子清行):http://redraiment.blogspot.com/
我的google sites(子清行):https://sites.google.com/site/redraiment
我的csdn部落格(夢婷軒):http://blog.csdn.net/redraiment
C 堆疊應用(三) 中綴表示式轉化為字尾表示式
將中綴表示式轉化為字尾表示式的過程中,需要對讀到的運算物件進行不同的處理 1 如遇到空格視為分隔符,不需要處理 2 如遇到運算數直接輸出 3 若是左括號,將其壓入至堆疊中 4 若遇到右括號,表明括號內的中綴表示式已經掃瞄完畢,將棧頂的運算子彈出並輸出,直到遇到左括號 出棧,但不輸出 5 若遇到運算子...
專題19 中綴轉化成字尾C語言(四)
複習到到佇列和棧時涉及到了不太清楚的 中綴轉化成字尾 的過程,專題中有寫,就記錄下來 參考 按運算子優先順序對所有運算子和它的運算數加括號,原本的括號不用加 把運算子移到對應的括號後 去掉括號 具體例如 a b c d e f g 加括號後式子變成 a b c d e f g 把運算子移動到對應括號...
論用C語言寫乙個PE直譯器(3)
可能在上篇文章中,有讀者會有疑問,可不可以用file檔案指標來進行操作呢?這麼簡單直接 理論上是可以的,但是需要知道的一點是,file其實是一種結構體,它包含了描述檔案的一些資訊。因此通過file來進行檔案操作其實會多出一些轉換。但這一點其實還好,比較重要的是,因為使用的指標是檔案指標,所以中間可能...