LL(1)文法解析

2021-10-07 07:12:43 字數 4401 閱讀 3619

一、 問題描述

給定上下文無關文法,對其進行解析,得出first集和follow集。在有能力的情況下,可以求出ll(1)分析表。

二、 演算法設計

本程式主要分成三塊內容,第一是文法的讀入解析,第二是first集的求解,第三為follow集的求解。

文法的解析需要根據整行讀入的文法,生成rulelist 表,儲存文法的左部和右部,num為產生式的條數。start list表儲存非終結符,startnum為非終結符個數,endlist儲存終結符,endnum為終結符個數。

first集求解過程偽**:

first函式seq:

初始化flag表,記錄first集是否已求解

遍歷start list表,do

if (flag[n]==0) getfirst(n);

endfirst函式end

getfirst函式seq:

if (flag[n]1) return;

遍歷rulelist表,do:

若是非終結符為startlist[n]的產生式s:

if (s」#」) 將#加入first[n]

elif (以終結符開頭)

將終結符加入first[n]

else

遍歷s,do:

if (s[i]為非終結符)

getfirst(s[i]對應位置);//遞迴

將s[i]的first集加入first[n]

若s[i]的first集不包含#,則推出迴圈

elif (s[i]為終結符) 將終結符加入first集,退出迴圈

end if

若整個產生是遍歷完均含#,則first集加入#

getfirst函式end

follow集求解過程偽**:

follow函式 seq:

遍歷rulelist表,do:

str=rulist[i].tuidao

遍歷str,do

if (str[i]為非終結符)

while(str[x]是非終結符),do

follow[str[j]]+=first[str[x]]-#

若first[str[x]]不含# 則退出迴圈

若str[x]為空

f[n]記錄下該產生式的右部對應非終結符

若為終結符,將終結符壓入follow[str[j]]

else

若是終結符或#,則continue;

for(n屬於[0,startnum ))

getfirst(n);

follow函式end

getfollow函式seq:

if(flag[n]==2) return ;

while(f[n]不為空)

求出f[n]包含的所有非終結符的follow集//遞迴呼叫getfollow函式

將求得follow集加入follow[n]

flag[n]=2;

getfollow函式end

ll(1)分析偽**:

llanalyze函式seq:

遍歷rulelist表,do:

a=rulelist[i].ssymbol在startlist表的位置

str=rulelist[i].tuidao

if(str[0]為非終結符)

對所有a屬於first[str[0]],table[a][a]=i;

if(#屬於first[str[0]])

對所有a屬於follow[a],table[a][a]=i;

else if(為#)

對所有a屬於follow[a],table[a][a]=i;

else

a=終結符對應endlist位置

table[a][a]=i;

llanalyze函式end

三、 實驗**

#include

#include

#include

#include

#include

#include

#define maxnum 10

using

namespace std;

//定義文法結構體

struct rule

;vector> first;

vector> follow;

int flag[maxnum]

;stack<

int> f[maxnum]

;vector rulelist;

char startlist[maxnum]=;

string endlist[maxnum]=;

vector

int>> table;

int endnum =0;

int startnum =0;

//非終結符個數

int num =0;

intstrsearch

(string token)

return-1

;}intsearch

(char s)

return-1

;}intcheck

(string s)

}return location;

}void

getfirst

(int n)

else

else

else

}else

flag1 =1;

}}if(flag1==

0) first[n]

.push_back

("#");

}}}}

flag[n]=1

;}void

first()

}void

getfollow

(int n)

else

flag[n]=2

;}}void

follow()

else

x++;}

if(search

(str[x])!=

-1)continue

;else

if(str[x]

==null

)else

}else

if(str[j]

=='#'

)continue

;else}}

for(

int n =

0; n < startnum; n++

)getfollow

(n);

}void

llanalyze()

}else}}

else

if(str[0]

=='#')}

else}}

void

displayfirst()

cout <<

"}\n";}

}void

displayfollow()

cout <<

"}\n";}

}void

displayll()

cout << endl;

for(

int i =

0; i < startnum; i++)*/

} cout << endl;}}

intmain()

}//cout << num << " " << startnum;

for(

int i =

0; i < num; i++)}

if(!token.

empty()

&&strsearch

(token)==-

1)endlist[endnum++

]= token;

} endlist[endnum++]=

"$";

first.

resize

(startnum)

; follow.

resize

(startnum)

; table.

resize

(startnum)

;for

(int i =

0; i < startnum; i++

)first()

;follow()

;llanalyze()

;displayfirst()

;displayfollow()

;for

(int j =

0; j < num; j++

)displayll()

;}

四、 測試結果

輸入文法如下所示,得到的結果如圖1所示。

LL 1 文法判斷

ll 1 文法判斷 題型 1.判斷該文法是否是ll 1 文法?2.若是,給出它的ll 1 分析表,否則說明理由。概念 對於產生式 a 1.如果 均不能推導出 空語句 則 first first 2.和 至多有乙個能推導出 3.如果 經過0步或多步可以推導出 則 first follow a 關鍵 求...

編譯原理實驗 LL(1)文法

目標任務 實現 ll 1 分析中控制程式 表驅動程式 完成以下描述算術表示式的 ll 1 文法的 ll 1 分析程式。g e e te e ate t ft t mft f e i a m 說明 終結符號 i 為使用者定義的簡單變數,即識別符號的定義。compiler3.cpp 定義控制台應用程式的...

簡易c語言LL 1 文法

程式 宣告 函式 宣告 a 宣告 函式宣告 a 標頭檔案 巨集定義 宣告 宣告 null 標頭檔案 標頭檔案 標頭檔案 標頭檔案 標頭檔案 null 巨集定義 define b 巨集定義 null b 字串 c c 字串 數字 字串 變數名 函式宣告 返回值型別 函式名 形參 函式宣告 null 形...