1. 程式人生 > >算術表示式的語法分析及語義分析程式設計 —— LR分析法、輸出三元式

算術表示式的語法分析及語義分析程式設計 —— LR分析法、輸出三元式

1.系統描述

1.1目的

通過設計、編制、除錯一個算術表示式的語法及語義分析程式,加深對語法及語義分析原理的理解,並實現詞法分析程式對單詞序列的詞法檢查和分析。

1.2設計內容及步驟

1)根據要求構造相應的文法。
2)根據LR分析法的步驟在每個產生式的右部適當位置新增一個圓點構成專案。
3)構造識別活字首的NFA。
4)LR專案集規範族的構造。
5)LR分析表的構造。
6)構造詞法分析器。
7)模擬LR分析器的工作過程進行語法分析。
8)輸出分析過程及三元式。

2.系統的詳細設計

2.1 文法設計

本次設計具體文法需要滿足的條件如下:
1) A->V=E
2) E->E+T |E-T|T
3) T->T*F|T/F|F
4) F->i|(E)
5) V->i

拓廣文法:

0) A’->A; 1) A->V=E 2) E->E+T
3) E->E-T 4) E->T 5) T->T*F
6) T->T/F 7) T->F 8) F->i
9) F->(E) 10) V->i

2.2 文法專案

這裡寫圖片描述

2.3 識別所有活字首的DFA

FIRST和FOLLOW集如下:

A E T F V
FIRST() {i} {i,(} {i,(} {i,(} {i}
FOLLOW() {#} {#,),+,-} {#,),+,-,*,/} {#,),+,-,*,/} {=}

這裡寫圖片描述

2.4 構造LR分析表

這裡寫圖片描述

2.5 詞法分析器

從鍵盤輸入一個算數表示式,以“#”結束。對輸入的字元依次進行判別,每當開始識別一個單詞時,若掃視到的第一個字元為字母,則把後續輸入的字母或數字字元依次進行拼接,直至掃視到非字母、數字字元為止,以期獲得一個儘可能長的字母數字字串,然後以此字串查所謂保留字表(此保留字表已事先造好),若查到此字串,則取出相應的類別碼;反之,則表明該字串應為一識別符號。
採用上述策略後,針對表I中部分單詞可以構造一個如圖1所示的有限自動機(以狀態轉換圖表示)。在圖1中添加了當進行狀態轉移時,詞法分析程式應執行的語義動作。根據圖1,可用C++語言編寫出符合以上幾項要求的一個相應的掃描器程式。
圖1 識別表I所列語言中的部分單詞的DFA及相關的語義過程


圖1 識別表I所列語言中的部分單詞的DFA及相關的語義過程
鑑於本程式只用來進行算數表示式的語法分析,所以只對“+”、“-”、“*”、“/”、“(”、“)”、“=、“#”和變數(此處用i代替)的單獨表示種別碼,其餘全部歸為一類。具體如下:

其對應的儲存方式如下:

typedef struct code{
    string data;
    int num;
}Code;
Code code[MAX];

2.6 LR分析器

將詞法分析的輸出即單詞和種別碼作為LR分析器的輸入,構造狀態棧state、分析棧ana、剩餘輸入棧sys、動作棧(ACTION詞表、GOTO詞表)和產生式表。其對應的儲存方式分別為:

ACTION詞表:

typedef struct action{
    char para;
    int val;
}Action;

GOTO詞表:

vector<Gene> gene;

產生式表:

struct Gene{//產生式
    string left;
    char* right;
};
vector<Gene> gene;

分別將對應的ACTION詞表、GOTO詞表和產生式詞表用已有資料初始化。

根據LR分析法,將0入state棧,將“#”入ana棧,為了方便分析,sys棧直接有詞法分析得到的code棧代替。

然後根據state棧的棧頂元素和code棧的棧頂元素尋找對應的ACTION詞表(將state棧的棧頂元素和code棧的棧頂元素作為陣列下標),找到對應的動作。若動作的para為“S”,即移進,則將code棧的棧頂元素取出,入ana棧。同時將對應動作的val入state;若動作的para為“R”,即規約,則根據對應產生式的長度,分別從ana棧和state棧中移出相應數量的單詞。再根據state棧的棧頂元素和ana棧的最後一個元素查詢GOTO詞表(將state棧的棧頂元素和ana棧的最後一個元素作為陣列下標),將其入state棧。

迴圈此過程,直至遇到“a”,即acc,則表明分析成功,表示式正確;否則,報錯。

2.7 輸出三元式和分析過程

在LR分析過程中,每迴圈一次,就將對應的state棧、ana棧、sys棧、動作棧和產生式表一次輸出,即為分析過程。
在LR分析中,設定一個an棧,其操作與ana棧大致相同,不過只對含有規約所用的產生式中涉及到運算子時才會規約,其餘時候的規約都不會執行。目的是為了儲存原有運算元,方便三元式的輸出。每次規約的過程中,若規約所用的產生式涉及到了含運算子的產生式的規約,則對an棧的最後三個單詞進行調整(將運算子提前,第一運算數後移)輸出。其中需要注意所含運算子為“(”“)”的情形,此時,不需要輸出,但an棧還是要進行相應的規約。

3 用例分析

1)該用例是本分析程式的一個比較典型的簡單的輸入,得到結果如下:
這裡寫圖片描述
2)當表示式包含變數或字母時,程式的執行結果:
這裡寫圖片描述
3)當輸入文法無法識別的字元時,程式會進行報錯。程式的執行結果(這裡是輸入運算子“++”):
這裡寫圖片描述
4)當輸入的表示式不完整或不匹配時,程式會自動報錯。
這裡寫圖片描述
6)增加下難度,輸入複雜表示式,輸出結果如下(輸入表示式為“i=(2*(1+3)+2)/2#”):
這裡寫圖片描述

4.程式的評價

本程式最大的特點是先通過詞法分析對輸入的字串進行識別,區別出一個個單詞,並標以種別碼,然後將其作為LR分析器的輸入,由於是將輸入的單詞和運算子作為字串處理,所以可以識別超過10的數字的運算,同樣,由於狀態棧、分析棧、剩餘輸入棧都是以字串為單元來對輸入處理的,所以還可以識別包括變數在內的算數表示式。功能相對而言較為全面。
在剛剛開始分析程式時,由於詞法分析在上機實驗時就已經實現了,而語法分析上機時時通過自頂向下的方法實現的,並且由於對原理理解得不夠深刻,沒有找到將詞法分析的過程加入到語法分析中的方法。後來通過上網查詢資料,發現通過種別碼就可以將詞法分析中得到的單詞區分開來,同時將其作為語法分析參考的標準。但剛開始的時候在語法分析即LR分析時,是將得到的單詞當做一個字元來處理,這樣在分析棧和剩餘輸入棧中進、出棧時只需進出單個字元,比較好操作。但後來測試用例時,發現當輸入“i=11+2#”時,在語法分析中“11”被當成了兩個單獨的字元“1”處理,而出現錯誤。於是,將字串作為分析棧和剩餘輸入棧的基本單位,將字串作為一個整體進棧和出棧,這樣就能解決上述的錯誤,也能順便解決含變數的算數表示式的分析。

相關推薦

算術表示式語法分析語義分析程式設計 —— LR分析輸出三元(續)

#include<iostream> #include<string> #include<vector> #include<cmath> #define MAX 40 using namespace std; t

算術表示式語法分析語義分析程式設計 —— LR分析輸出三元

1.系統描述 1.1目的 通過設計、編制、除錯一個算術表示式的語法及語義分析程式,加深對語法及語義分析原理的理解,並實現詞法分析程式對單詞序列的詞法檢查和分析。 1.2設計內容及步驟 1)根據要求構造相應的文法。 2)根據LR分析法的步驟在每個

Java中StringStringBuilderStringBuffer常用源碼分析比較(二):StringBuilderStringBuffer源碼分析

string類型 character private 字符 代碼 less pri des over StringBuilder: 一、構造方法: /** * Constructs a string builder with no characters in i

Java中StringStringBuilderStringBuffer常用源碼分析比較(三):StringStringBuilderStringBuffer比較

val str 成員變量 相同 += let .get end art 看這篇隨筆之前請務必先看前面兩章: Java中String、StringBuilder、StringBuffer常用源碼分析及比較(一):String源碼分析 Java中String、StringBui

8.常量分析變量交換時空分析

color 時間 open lap closed define etc 常量 src 間接修改const常量 1 void main() 2 { 3 const int a = 99; 4 printf("%d\n", a); 5

android螢幕適配問題分析各種解決方案優缺點分析

序 從事android開發已有5年之久,專案中遇到的螢幕適配的問題也有n次了,可是有一個很奇怪也很讓人頭疼的現象讓從事多年開發的我很不爽。什麼問題呢,就是“適配虐我千萬遍,我見適配如初見”,真是想說一句fuck,這次我終於堅決的征服掉了她,下面就來具體講解征服她的全過程,一定要

R中季節性時間序列分析非季節性時間序列分析

序列分解 1、非季節性時間序列分解 移動平均MA(Moving Average) ①SAM(Simple Moving Average) 簡單移動平均,將時間序列上前n個數值做簡單的算術平均。 SMAn=(x1+x2+…xn)/n ②WMA(We

聚類分析R程式設計實現

目錄 什麼是聚類分析 ​聚類分析法的型別 聚類統計量 ​系統聚類法 R語言實現 最短距離法 最長距離法  中間距離法  類平均法  重心法  ward法 什麼是聚類分析 聚類分析法-cluster ana

併發程式設計(四)—— ThreadLocal原始碼分析記憶體洩露預防

今天我們一起探討下ThreadLocal的實現原理和原始碼分析。首先,本文先談一下對ThreadLocal的理解,然後根據ThreadLocal類的原始碼分析了其實現原理和使用需要注意的地方,最後給出了兩個應用場景。相信本文一定能讓大家完全瞭解ThreadLocal。 ThreadL

表示式語法分析——遞迴子程式法

Problem Description 遞迴子程式法是一種確定的自頂向下語法分析方法,要求文法是LL(1)文法。它的實現思想是對應文法中每個非終結符編寫一個遞迴過程,每個過程的功能是識別由該非終結

【java併發程式設計】執行緒池原理分析ThreadPoolExecutor原始碼實現

執行緒池簡介:  多執行緒技術主要解決處理器單元內多個執行緒執行的問題,它可以顯著減少處理器單元的閒置時間,增加處理器單元的吞吐能力。         假設一個伺服器完成一項任務所需時間為:T1 建立執行緒時間,T2 線上程中執行任務的時間,T3 銷燬執行緒時間。    

程式進度條分析程式設計

   在printf的實現中有一步呼叫write的操作。而write是一個系統呼叫,系統呼叫是軟中斷,頻繁呼叫會使核心頻繁陷入核心態,效率不是很高,所以printf的實現中在呼叫write之前,加了一個IO緩衝區。printf輸出資料的時候實際上是先往使用者空間的IO緩衝區寫,在滿足條件的情況下才會呼叫w

Java程式設計中漢字問題的分析解決

引:在基於Java語言的程式設計中,我們經常碰到漢字的處理及顯示的問題。一大堆看不懂的亂碼肯定不是我們願意看到的顯示效果,怎樣才能夠讓那些漢字正確顯示呢?Java語言預設的編碼方式是UNICODE,而我們中國人通常使用的檔案和資料庫都   在基於java語言的程式設計中,我們

Linux網路程式設計---ICMP協議分析ping程式實現

一、IP協議 IP協議是TCP/IP協議族所依賴的傳送機制,提供無連線不可靠的資料報服務。IP的無連線特性意味著每個IP報文都是獨立尋徑的,因此當一個源主機發送多個報文給同一目的主機時,這些報文可能出現錯序,丟失或者部分報文產生錯誤等現象,因此為了保證資料傳送的可靠性,必須

linux socket程式設計 出現訊號SIGPIPE,分析解決

在編寫一個仿QQ軟體,C/S模式。出現的問題:當客戶機關閉時,伺服器也隨著關閉,糾結很久之後,我gdb了下,出現下面提示資訊: Program received signal SIGPIPE, Broken pipe. 0x0012e416 in __kernel_vsyscall () 在 網上查了一

郭歆芮:黃金原油如期高開,早間行情走勢分析早間操作建議!

郭歆芮:黃金原油如期高開,早間行情走勢分析及早間操作建議! 在這個市場,有一個清醒的頭腦比有一個聰明的頭腦更重要,有一種良好的習慣比有一種熟練的技巧更實用。堅韌的才是長久的,真實的才是永恒的,做任何事情都是如此。當你刻意地追求時,它就像蝴蝶一樣振翅飛遠。當你專

使用sso(cas)的時候報單點登錄service不匹配問題分析解決

amp 多個 cas query xxx code util match 新版 最近在使用portal做企業門戶網站,其中使用了sso。在集成了多個應用之後在portal中點擊集成的應用報錯 2017-05-31 08:37:16,950 ERROR [org.jasig.

MySQL性能分析explain的使用

索引 pri ... ons data 接下來 rom possible 聯合 MySQL性能分析及explain用法的知識是本文我們主要要介紹的內容,接下來就讓我們通過一些實際的例子來介紹這一過程,希望能夠對您有所幫助。 1.使用explain語句去查看分析結果 如e

集群環境分析部署(基礎)

服務器 檢測 記錄 能力 健康 集群概念:由兩個或兩個以上的服務實體協調、配合完成一系列工作的模式,對外表現為一個整體。特點分配用戶請求故障轉移共享存儲結構:agent 負載調度器業務層 服務器池存儲 共享存儲1.垂直擴展為同樣的計算資源池加入更多資源,比如增加更多內存、磁盤或

AppStore IPv6-only審核被拒原因分析解決方案

穩定 eip ios 穩定性 only 應用服務器 http 一個 搭建 AppStore IPv6-only審核被拒原因分析及解決方案 http://www.jianshu.com/p/8edfdfa20b29 自2016年6月1日起,蘋果要求所有提交App St