當前位置:首頁 » 編程軟體 » 編譯原理表

編譯原理表

發布時間: 2024-04-06 22:42:18

編譯原理中pl/0符號表中oddsym是代表什麼符號


判斷一個表達式的結果是否為奇數,若為奇數返回真

② 編譯原理5:算符優先關系表構造

根據FIRSTVT和LASTVT構造算符優先關系表,規則簡單來講如下:

① 對於產生式形如 A→...ab... 則優先順序a=b

②對於產生式形如 A→...aBc...則優先順序a=c,a<FIRSTVT(B),LASTVT(B)>c

例:

③ 編譯原理——LR分析表

自底向上的語法分析

LR分析表的結構如上,其分為兩個部分 Action Goto

兩個參數狀態i,終結符號a(s(i)代表第i個狀態,r(i)代表第i條表達式)

Goto[i,A]=j

文法

容易得知這個文法可以推出 0 1 00 01 等的字元串。因為它是 左遞歸 。不適用於 LL 文法分析,只能使用 LR 分析。

因為本題入口有兩個—— S → L·L S → L ,所以需要構造額外的產生式 S'->S

2.1 第一次遍歷

我們從 [S -> . L·L] 開始,構造這個狀態的閉包,也就是加上所有能從這個產生式推出的表項。

首先,判斷 . 後面是否為 非終結符號A 。如果是,那我們就得找所有由 A-> 推出的產生式,並將它們添加進入 閉包 里(也就是State包里)。循環做即可。

因此我們可以得到 State 0 有

下一步,就是我的 . 往下一位移動。對每個符號X後有個 . 的項,都可以從 State 0 過渡到其他狀態。

由以上6條式子可以得知下一位符號可以是 S L B 0 1 。所以自然可以得到5個狀態。

State 1 是由 State 0 通過 S 轉移到這里的,所以我們找出所有 State 0 中在 S 前有 . 的項。

此狀態作為結束狀態 Accept ,不需要繼續狀態轉移了。

State 2 是由 State 0 通過 L 轉移到這里的,所以我們找出所有 State 0 中在 L 前有 . 的項。

S -> . L·L S -> . L L -> . LB

有3條式子,現在我們將 . 向後推一格,就得到 State 1 的項了。

但是 . 之後的符號分別是 · $ B , B 為非終結符號,我們得包含 B -> 的項

State 3 是由 State 0 通過 B 轉移到這里的,所以我們找出所有 State 0 中在 B 前有 . 的項。

因為 . 後沒有其他符號了,因此這個狀態不需要繼續轉移了。

State 4 是由 State 0 通過 0 轉移到這里的,所以我們找出所有 State 0 中在 0 前有 . 的項。

因為 . 後沒有其他符號了,因此這個狀態不需要繼續轉移了。

很簡單,同樣的道理找 State 5

State 5 是由 State 0 通過 1 轉移到這里的,所以我們找出所有 State 0 中在 1 前有 . 的項。

因為 . 後沒有其他符號了,因此這個狀態不需要繼續轉移了。

好的,現在我們第一次遍歷完成。

2.2 第二次遍歷

第二次遍歷自然從 State 2 開始。

我們回到 State2 ,可以看出 . 之後的符號有 · B 0 1 。

State 6 是由 State 2 通過 · 轉移到這里的,所以我們找出所有 State 2 中在 · 前有 . 的項。

S -> L. ·L 只有1條,我們往後移發現 L 又為非終結符號,參考 State 0 做的操作,我們得找出所有的式子。

共有5條式子,共同組成 State 6 ,由上面的式子可以看出我們還得繼續下一次遍歷。先不管著,我們進行下一次狀態查找。

State 7 是由 State 2 通過 B 轉移到這里的,所以我們找出所有 State 2 中在 B 前有 . 的項。

L -> L. B 也是只有1條,我們往後移發現沒有非終結符號了,那就不需要再繼續添加其他式子了。

這個狀態也不需要繼續進行轉移了。

接下來很關鍵,因為我們通過 State2 的 . 後的符號找出了 State 6 State 7 ,接下來還差符號 0 1 ,那麼是否像之前一樣按例添加狀態呢, 答案是不是的 ,因為我們發現通過 0 1 找到的閉包集分別是 B -> 0 B -> 1 ,這與我們的之前的 State 4 State 5 相同。所以我們得將其整合起來,相當於 State 2 通過 0 1 符號找到了 State 4 State 5 狀態。

2.3 第三次遍歷

回頭看第二次遍歷,可以看出只有 State 6 可以進行狀態轉移了。

那麼就將 State 6 作為第三次遍歷的源頭,可以看出 . 之後的符號有 L B 0 1 。

State 8 是由 State 6 通過 L 轉移到這里的,所以我們找出所有 State 6 在 L 前有 . 的項。

S -> L· .L L -> . LB 有兩條式子,往後移發現有非終結符號 B ,所以經過整合可以得到

可以看出 . 的後面還有一個符號,所以這里我們還得再進行一次遍歷。

接下來,又是遇到重復的包的情況,可以看出我們由 State 6 通過 B 0 1 得到的閉包分別是 L->B B->0 B->1 ,很明顯,這分別對應於 State 3 State 4 State 5 。

第三次遍歷也就結束了。

2.4 第四次遍歷

回看第三次遍歷,可以看出只有 State 8 可以進行狀態轉移,其 . 之後的符號分別是 B 0 1 。

誒,感覺很熟悉,就是上面幾行剛說的情況,也就是說通過這三個符號找到的閉包是我們之前遇到的狀態,分別是 State 3 State 4 State 5 。

做到這里,我們發現我們已經全部遍歷完畢!

總共有8個狀態,通過以上流程做成個圖是什麼樣子的?來看看!

這么一看就很清晰明了了,我們就可以通過這個圖做出我們的 LR分析表

其實就是我們之前呈現的表

在狀態 I2 和 I8 中,既有 移入 項目,也有 規約 項目,存在 移入 - 規約的沖突 ,所以不是 LR(0) 文法,但是因為 FOLLOW(S) {0, 1} = ∅,所以可以用 FOLLOW 集解決沖突,所以該文法是 SLR(1) 文法。

上表我們發現還有 r1,r2,r3 等。這個其實就是代表狀態停止轉移時為 第幾條表達式 ,r3代表第三條表達式 L -> LB 。

當我們構建了表之後,我們如何運用起來呢?

下面我們通過一個例子來說明

以上字元串是如何被SLR分析器識別的呢?

④ 編譯原理問題--優先關系表怎麼畫

先求出FIRSTVT和LASTVT。

找Firstvt的三條規則:如果要找A的Firstvt,A的候選式中出現:

A->a.......,即以終結符開頭,該終結符入Firstvt

A->B.......,即以非終結符開頭,該非終結符的Firstvt入A的Firstvt

A->Ba.....,即先以非終結符開頭,緊跟終結符,則終結符入Firstvt

找Lastvt的三條規則:如果要找A的Lastvt,A的候選式中出現:

A->.......a,即以終結符結尾,該終結符入Lastvt

A->.......B,即以非終結符結尾,該非終結符的Lastvt入A的Lastvt

A->.....aB,即先以非終結符結尾,前面是終結符,則終結符入Lastvt

然後逐條掃描文法規則。例題如下,參考這個例題能很好地理解如何構造優先關系表。

《編譯原理》(第4版)第三章例題4.12

⑤ 編譯原理對符號表進行操作有哪些

//----------------------------符號表---------------------------------------
//預定義
struct snode;
struct stable;
//符號表結點
struct snode
{
string text; //符號名稱
string type; //符號類型
union {int ival;double rval;}value; //值------------
int offset; //偏移量
snode *nextn; //指向下一個節點
stable *header; //指向下屬符號表的表頭
};
//符號表表頭
struct stable
{
stable *previous; //指向先前創建的符號表表頭
snode *firstnode; //指向第一個結點
stable *ifnoelements;//如果此表為空,則用它指向下一個表頭
};

//當前表頭
stable *currtab;
//建立新表,返回表頭指針
//參數:當前的節點的表頭
stable *mktable(stable *previous)
{
stable *newtable =new stable;
newtable->previous=previous;
newtable->ifnoelements=0;
newtable->firstnode=0;
if(previous->firstnode==0)
{
previous->ifnoelements=newtable;
}
else
{
snode* ininode=previous->firstnode;
while(ininode->nextn!=0)
{
ininode=ininode->nextn;
}
ininode->header=newtable;
}

currtab=newtable;
return newtable;
}
//在node指向的符號表中為text建立一個新表項,返回新建立的結點
//參數:node為當前的節點的表頭,text名稱,type類型,offset偏移
snode *enter(stable *table,string text,string type,int offset,double value)
{

//創建節點
snode *newnode = new snode;
newnode->text=text;
newnode->type=type;
newnode->offset=offset;
newnode->nextn=0;
newnode->header=0;
if(type=="int")
{
newnode->value.ival=value;
}
else if(type=="real")
{
newnode->value.rval=value;
}

//判斷此表是否無元素
if(currtab->firstnode==0)
{
currtab->firstnode=newnode;
currtab->ifnoelements=0;
}
else
{
snode* addnode=currtab->firstnode;
while(addnode->nextn!=0)
{
addnode=addnode->nextn;
}
addnode->nextn=newnode;
}

return newnode;
}
//初始化符號表,返回表頭節點
void inittab()
{
stable *initable = new stable;
initable->firstnode=0;
initable->previous=0;
initable->ifnoelements=0;
currtab=initable;
}
//查找指針,表示結果
snode *searchresult;
//查找變數,返回指向該變數的指針
//查找變數,返回指向該變數的指針
snode* search(string name)
{
//檢查表是否空
bool isempty=true;
stable* checktab=currtab;
if(checktab->firstnode!=0)
{isempty=false;}
while(checktab->previous!=0)
{
if(checktab->firstnode!=0)
{isempty=false;}
checktab=checktab->previous;
}
if(checktab->firstnode!=0)
{isempty=false;}
if(isempty)
{
return 0;
}
snode* lastnode;
if(currtab->firstnode==0)
{
//移到非空的表頭
stable* notnullhead=currtab;
while(notnullhead->firstnode==0)
{
notnullhead=notnullhead->previous;
}
snode* tmpnode=notnullhead->firstnode;
//移到最後的元素
while(tmpnode->nextn!=0)
{
tmpnode=tmpnode->nextn;
}
lastnode=tmpnode;
}
else
{
lastnode=currtab->firstnode;
while(lastnode->nextn!=0)
{
lastnode=lastnode->nextn;
}
}
//移到表頭
stable* fronttab=currtab;
while(fronttab->previous!=0)
{
fronttab=fronttab->previous;
}
snode* nownode=0;
while(nownode!=lastnode)
{
while(fronttab->ifnoelements!=0)
{
fronttab=fronttab->ifnoelements;
}
nownode=fronttab->firstnode;
while(nownode->nextn!=0)
{
if(nownode->text==name)
{
searchresult=nownode;
return searchresult;
}
nownode=nownode->nextn;
}
if(nownode->text==name)
{
searchresult=nownode;
return searchresult;
}
fronttab=nownode->header;
}
if(nownode->text==name)
{
searchresult=nownode;
return searchresult;
}
return 0;
}

//消毀符號表
void delNode()
{
//more codes here......
}

⑥ 編譯原理中LR(0)分析表中的r1、r2等等 是怎麼規則填寫的s1、s2…我明白了,但r規則看不懂

r表示規約 r5表示的就是用第五條產生式進行規約的 至於r填在哪裡嗎 我就舉個例子吧 比如I8 進行規約 就會在H的所有fellow集合上填上r5 希望你能看懂。。。。

⑦ [高分,急!]編譯原理LR(1)分析表題目

I0: S->.T,# T->.T(T),#
I1: S->T.,# T->T.(T),#
I2: S->T(.T),# T->.T(T),) T->.ε,)
I3: S->T(T.),# T->T.(T),)

(1,() 是s2
(1,#) 是acc (就是接受)
T下1 是1
T下3 是3

⑧ 編譯原理算符優先分析法中構造分析表的時候,井號和其他符號的優先順序怎麼判斷在線等。

首先,算符優先分析法只考慮終結符之間的優先關系。
其次,#和其他終結符之間的優先關系按如下方法來確定:
1)假設文法的開始符為E,則增加一個產生式E『-> #E#, E'不在原文法中出現
2)#<FIRSTVT(E) ; LASTVT(E)>#

⑨ 編譯原理,構造SLR分析表時,產生式中出現F的星閉包該怎麼處理

仔細分析你的文法
F->F*|a|b也就是說,寫成正則表達式的話 F就是[ab]*
同樣的T也是[ab]*

你的整個文法就是[ab]+ [ab\+]*第一個+是+closure,第二個+是符號+,所以用了\符號
個人感覺這個文法是有問題的,因為根本不需要用上下文無關文法表達,只需要正則表達式就可以了。

熱點內容
編程用箭頭 發布:2024-05-05 15:54:21 瀏覽:792
步驟條源碼 發布:2024-05-05 15:35:55 瀏覽:845
安卓拍光遇視頻如何高清 發布:2024-05-05 15:23:20 瀏覽:933
linuxo文件 發布:2024-05-05 15:19:12 瀏覽:944
手機伺服器地址或者域名 發布:2024-05-05 15:19:09 瀏覽:373
我的世界伺服器版如何登錄 發布:2024-05-05 15:17:28 瀏覽:794
綦江dns伺服器地址 發布:2024-05-05 15:04:11 瀏覽:556
山東省日照市監控伺服器地址 發布:2024-05-05 15:03:59 瀏覽:342
java提升教程 發布:2024-05-05 15:00:51 瀏覽:144
驅動編譯龍芯 發布:2024-05-05 14:41:31 瀏覽:957