編譯原理之文法推導

2021-09-26 18:13:26 字數 2658 閱讀 9837

已知文法g:

《表示式》 ::= 《項》 | 《表示式》+《項》

《項》 ::= 《因子》 | 《項》*《因子》

《因子》 ::= (《表示式》) | i

試給出下列表示式的推導。

(1) i (2) (i) (3) i*i (4) i*i+i

(5) i+(i+i) (6) i+i*i (7) (i+i)*i (8) i+i

(9) i*i+i*i (10)i*i*i

3. 演算法思想

描述的是大概的過程,具體實現的細節見**注釋。

(1)定義輸入字串e,儲存需要推導的句子;定義輸出字串out=」e」和kout=」e」,out用於輸出主推導(不是括號中表示式的推導 ) 時的推導過程,kout用於輸出括號推導時的推導過程;定義棧s,用於儲存括號中待推導的表示式。

(2)定義推導階段標誌kflag=0,kflag=0表示為主推導,kflag≠0表示為從右向左第kflag個括號推導。定義輸出函式print(),根據kflag的值選擇性輸出推導過程(具體實現可見源**),(3)中輸出均為呼叫print()函式。

(3)推導方法如下: 

① 掃瞄字串e,計算e中除去括號中的符號外「+」的個數,記錄每個「()」的位置(位置相對每個「()」為乙個整體來看)儲存到陣列pos,同時將「()」中的符號串壓入棧s。

② e中除去括號中的符號外有多少個「+」,就在e的末尾新增幾次「+i」(e→e+i),最後將e用i替換(e+i…→i+i…),同時輸出。如果沒有「+」,用i替換e(e→i),同時輸出。

③ 倒序(從右向左)掃瞄e,以「+」為分割點分成若干區間,從右向左依次掃瞄每個區間,計算區間內除去括號中的符號外有幾個「*」,從右向左掃瞄out(不重複掃瞄,每次接著上次的位置繼續向左掃瞄),記錄「i」的位置ipos,有幾個「*」就在out中ipos位置的『i』的後面插入「*t」(i→i*t),同時輸出。 

④ 倒序掃瞄e,將位置i=pos(pos陣列中任意某個值)的字元「i」或「t」替換成「(e)」(i→t,t→(e)),同時輸出。 

⑤當棧s不空,令e=s.top(),s棧頂出棧,推導階段標誌kflag++,重複②~⑤過程。直到s棧空,結束。

4. 不足之處

① 對於文法並沒有用相應的資料結構去儲存,推導過程僅僅只是依據輸入的表示式中的算符來判斷,並且只針對2.中給定的文法推導。

②輸入檢測不夠嚴謹,僅僅只對輸入能夠接受的字元進行了限制,並沒有檢查句子合法性。

③推導過於依賴「+*()」符號,所以整體不是最左推導也不是最右推導;並且對應存在巢狀括號(括號中還有括號)的表示式不能推導,能夠推導大部分的多級括號(式中有多個括號,但每個括號中無括號),但也有少部分不能推導。

#include#include#includeusing namespace std;

int kflag=0;//推導階段標誌,0為主推導,非0表示從右向左第幾個括號推導

string out,kout;//儲存括號推導過程,儲存全部推導過程

void shift()//儲存的字母輸出為漢字}}

kout.replace(kpos1+1,kpos2-kpos1-1,out);//將括號中字元替換為當前的括號推導

shift();//輸出}}

int main()

if(e[i]=='+') break;

}pos2=pos1;//記錄區間(以+為分界點)末端位置 ,是上乙個區間的開始位置

pos1=i;//記錄區間開始位置

if(i!=-1)//保證迴圈能夠結束

i--;

mul=0;

for(int j=pos1+1;j=0;m--)//倒序遍歷out字元

}if(mul!=0)//有乘號

if(out[i]=='t')}}

}for(i=out.length()-1;i>=0;i--)//倒序遍歷out

if(out[i]=='t')

}if(kflag==0)//如果是主推導

kout=out;//儲存總輸出

if(!s.empty())//當s棧不空,說明句子中有括號

else

cout<>choose;

kflag=0;//kflag清零,繼續推導其他句子

編譯原理之文法

文法 以有窮的集合描述無窮的計畫的工具。字母表 元素的非空有窮集合,其中的元素稱為符號,因此也叫符號集。符號串 由字母表中的元素組成的任何有窮序列,串中的元素個數叫做符號串的長度,空符號串 長度為0。符號串的運算 連線 符號串x ab,y cd,xy abcd 方冪 z xn,當n 0,z 當 n ...

編譯原理(2) 文法推導

這一篇講一講形式文法的推導,學習是乙個持之以恆的過程,尤其是像我這種初學者了。注 這一篇的例子來自於統計自然語言處理這本書 形式文法的推導比較好理解,即按文法g中的規則p推導 的符號串,且b c是p中的乙個產生式,那麼,abc adc。1 的傳遞閉包,即 n 上的符號串xi到xi 1至少經過一步推導...

編譯原理之文法一

一 先簡單介紹一下形式語言基本知識 1 字母表 符號的 非空有限 集合稱為字母表 2 符號串 由某一字母表中的符號組成的 有限符號串行 稱為該字母表的符號串 二 非形式化的語言 語言l和 m的合併 lum 語言l和 m的連線 lm 語言l的kleene 閉包,l 語言l 的正閉包,l 解釋 前面 都...