1、给出LL(1)文法

2、FIRST集和FOLLOW集

3、构造分析表

1、分析器代码表示

2、运行函数

# 实验题目

（1）E→E+T | E-T | T

（2）T→T*F | T/F | F

（3）F→P^F | P

（4）P→(E) | i

# 实验步骤

## 1、给出LL(1)文法

（1）E->TE'

（2）E'->+TE'|-TE'|e

（3）T->FT'

（4）T'->*FT'|/FT'|e

（5）F->PF'

（6）F'->^F|e

（7）p->(E)|i

e表示空。

## 2、FIRST集和FOLLOW集

 FIRST集 FOLLOW集 E (,i ),# E' +,-,e ),# T (,i +,-,),# T' *,/,e +,-,),# F (,i *,/,+,-,),# F' ^,e *,/,+,-,),# P (,i ^,*,/,+,-,),#

## 3、构造分析表

 ( i + - * / ^ ) # E TE' TE' E' +TE' -TE' e e T FT' FT' T' e e *FT' /FT' e e F PF' PF' F' e e e e ^F e e P (E) i

# 代码步骤

## 1、分析器代码表示

//使用X、Y、Z 代替 E'、T'、F'
//非终结符
char non_terminal[7] ={'E','X','T','Y','F','Z','P'};

//终结符
char terminal[9]={'(','i','+','-','*','/','^',')','#'};

//分析表
string analystate[7][19]={
{"TX","TX","NULL","NULL","NULL","NULL","NULL","NULL","NULL"},
{"NULL","NULL","+TX","-TX","NULL","NULL","NULL","e","e"},
{"FY","FY","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL"},
{"NULL","NULL","e","e","*FY","/FY","NULL","e","e"},
{"PZ","PZ","NULL","NULL","NULL","NULL","NULL","NULL","NULL"},
{"NULL","NULL","e","e","e","e","^F","e","e"},
{"(E)","i","NULL","NULL","NULL","NULL","NULL","NULL","NULL"}
};

//输入串
string input;

//当前输入符号
int nowchar=0;

//分析栈
vector<char> analystack;

## 2、运行函数

//读取栈顶非终结符时，获取此非终结符的index以便查询分析表
int indexN(char N){
int i=0;
for(i;i<7;i++){
if(non_terminal[i]==N)return i;
}
}
//读取当前输入符号时，获取此终结符index以便查询分析表
int indexT(char T){
int i=0;
for(i;i<9;i++){
if(terminal[i]==T)return i;
}
}

//当栈顶是非终结符时进行的推导
//NULL报错、e只抛出不进栈、其他逆序进栈
void operstack(int i,int j){
string formula=analystate[i][j];
analystack.pop_back();//栈顶元素出栈
if(formula=="NULL"){
cout<<"error at ";
int  k=0;
for(k;k<nowchar;k++){
cout<<input[k];
}
cout<<"!"<<endl;
exit(0);
}

if(formula!="e"){//产生式结果为e，只抛出不进栈
int k=formula.length()-1;
for(k;k>=0;k--){
analystack.push_back(formula[k]);//产生式结果逆序进栈
}
}
}
//打印分析过程
void print(){
int i;
for(i=0;i<analystack.size();i++)
cout<<analystack[i];
cout<<'\t'<<'\t';//输出符号栈

cout<<input[nowchar]<<'\t'<<'\t';//输出当前输入符号

for(i=nowchar+1;i<input.length() ;i++){//输出输入串
cout<<input[i];
}
cout<<endl;
}
int main(){

cin>>input;//输入字符串 以#结尾
analystack.push_back('#');
analystack.push_back('E');//初始化符号栈

cout<<"符号栈"<<'\t'<<'\t'<<"当前输入符号"<<'\t'<<"输入串"<<endl;
print();
while(!analystack.empty()) {//当栈不为空时

while(analystack.back()!=input[nowchar]){//当栈顶元素与输入不匹配时递推
operstack(indexN(analystack.back()),indexT(input[nowchar]));
print();
}
analystack.pop_back();//匹配成功，弹出栈顶符号
if(nowchar<input.length()-1)nowchar++;//输入符号后移
print();
}
cout<<"success";
return 0;
}

# 实验结果

①输入i*(i+i)^i#判断结果：

可以试试根据分析结果画出语法树，可以看出分析结果与熟知的有理运算各符号的运算优先级是一样的，没有二义性。

②输入错误语句i--i#判断结果：

• 1
点赞
• 0
评论
• 13
收藏
• 打赏
• 扫一扫，分享海报

06-15

12-11 3178
12-18 1万+
05-10 5万+
08-11 7290
08-07 786
12-24
07-14 690
02-21 2746
06-09
05-30 850
05-10
05-23
11-14 9251
04-06 1万+

kan木

¥2 ¥4 ¥6 ¥10 ¥20

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、C币套餐、付费专栏及课程。