編譯原理表
① 編譯原理中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,第二個+是符號+,所以用了\符號
個人感覺這個文法是有問題的,因為根本不需要用上下文無關文法表達,只需要正則表達式就可以了。