当前位置:
文档之家› 编译原理(语法分析程序设计)
编译原理(语法分析程序设计)
}
}
void error(inti,intj,char *&a)//error处理函数
{
switch(j)
{
case 1://期望输入id或左括号,但是碰到+,*,或$,就假设已经输入id了,转到状态5
cout<<"error:缺少运算对象id"<<endl;
symbol.push('i');//必须有这个,如果假设输入id的话,符号栈里必须有....
break;
case 4:
A='T',b=1;
cout<<"reduce by T->F"<39;F',b=3;
cout<<"reduce by F->(E)"<<endl;
break;
case 6:
A='F',b=1;
cout<<"reduce by F->id"<<endl;
{0,0,0},
{0,0,0},
{0,0,0}
};
void action(inti,char *&a,char&how,int&num,char&A,int&b)//action函数[i,a]
{
int j;
switch(*a)
{
case 'i':
j=0;break;
case '+':
j=1;break;
实验方案
1、说明:该程序使用实现对算术表达式自底向上的语法分析,并且在对输入表达式进行分析的过程中,输出分析动作,移进或者用哪个产生式进行规约,该程序使用的是LR语法分析程序,手动构造了识别所有活前缀的DFA,为给定文法构造LR分析表,并通过预测分析表对输入的表达式进行分析,并将栈顶状态和预测分析过程详细输出,如果匹配成功则接受,如果匹配不成功则返回错误信息。
case '*':
j=2;break;
case '(':
j=3;break;
case ')':
j=4;break;
case '#':
j=5;break;
default:
j=-1;break;
}
printf("%c\t\t",*a);
if(j!=-1)
{
how=sym[i][j];
num=snum[i][j];
state.push(11);
printf("11\t\t");
break;
case 5:
a++;
cout<<"error:*号无效,应该输入+号!"<<endl;
case 6:
a++; } }
int main()
{
int s;
char *a;
char how;
intnum;
int b;
char A;
if(how=='r')
{
switch(num)
{
case 1:
A='E',b=3;
cout<<"reduce by E->E+T"<<endl;
break;
case 2:
A='E',b=1;
cout<<"reduce by E->T"<<endl;
break;
case 3:
A='T',b=3;
cout<<"reduce by T->T*F"<<endl;
}
return 0;
}
实验记录
程序测试:
1、输入的表达式(i+i)*i#正确则不报错并接受:
2、输入错误的表达式i*(i+i*i#报错并进行恢复:
实验总结
通过对语法分析程序的设计和编写,使自己获得了很大的收获,并且使自己对语法分析程序的功能有了更进一步认识。虽然在程序的设计和编写过程中出现了一些错误,但是经过同学的帮助和指导,顺利的将程序中存在的错误顺利解决,从而顺利完成了本程序的设计和编写。
编译原理实验报告
学 号
2012061321
姓 名
王勇军
实验名称
语法分析程序设计
实验目的
1、了解预测分析法和递归子程序发的区别和联系。了解语法分析的功能。训练掌握开发应用程序的基本方法。
2、本次实验主要用到LL(1)分析(第1个“L”指的是由左向右地处理输入,第2个“L”指的是它为输入串描绘出一个最左推导,数字1意味着它仅使用输入中的一个符号来预测分析的方向)。
cout<<"请输入表达式(以i表示标识符,以#结束):"<<endl;
while(1)
{
cin>>sen;
a=sen;
state.push(0);//先输入0状态
printf("\t\t-------分析过程-------\n");
printf("符号栈栈顶\t状态栈栈顶\t当前读入符号\t分析动作\n"); printf(" \t\t0\t\t");
{'r','r','r','r','r','r'}
};
char snum[12][6]={//数字表
{5,1,1,4,2,1},
{3,6,5,3,2,0},
{2,2,7,2,2,2},
{4,4,4,4,4,4},
{5,1,1,4,2,1},
{6,6,6,6,6,6},
{5,1,1,4,2,1},
{5,1,1,4,2,1},
给定文法的产生式为:E->E+T | T T->T*F | F F-> id | (E)
2、程序源代码:
#include<iostream>
#include<stack>
using namespace std;
stack<char> symbol;
stack<int> state;
charsen[50];
char sym[12][6]={//符号表
{'s','e','e','s','e','e'},
{'e','s','e','e','e','a'},
{'r','r','s','r','r','r'},
{'r','r','r','r','r','r'},
{'s','e','e','s','e','e'},
{'r','r','r','r','r','r'},
{'s','e','e','s','e','e'},
{'s','e','e','s','e','e'},
{'e','s','e','e','s','e'},
{'r','r','s','r','r','r'},
{'r','r','r','r','r','r'},
state.push(num);
printf("%d\t\t",num);
a++;
}
else if(how=='r')//规约
{
for(inti=0;i<b;i++)
{
if(!state.empty())
state.pop();
if(!symbol.empty())
symbol.pop();
}
int t=state.top();
printf("i\t\t");
state.push(5);
printf("5\t\t");
break;
case 2://从输入中删除右括号
a++;
cout<<"error:不配对的右括号"<<endl;
break;
case 3://期望碰到+,但是输入id或左括号,假设已经输入算符+,转到状态6