哈工大 威海 编译原理 实验二 语法分析
编译原理语法分析实验

break;
default:
printf("ERR \n");
}
}
if(status_top=='2')
{
switch(*p)
{
case ',':
PushSymbol(&symbol,*p);
PushStatus(&status,'5');
p++;
default:
printf("ERR \n");
}
}
if(status_top=='6')
{
switch(*p)
{
case '#':
PopSymbol(&symbol,&temp_symbol);
PopSymbol(&symbol,&temp_symbol);
PushSymbol(&symbol,'L');
{
if(s->top>=MaxStackSize)
printf("堆栈已满!\n");
else
{
s->stack[s->top]=x;
s->top++;
}
}
void PopSymbol(SymbolStack *s,char* x)
{
if(s->top<=0)
printf("堆栈为空\n");
else
PopStatus(&status,&temp_status);
编译原理实验词法分析语法分析

本代码只供学习参考:词法分析源代码:#include<iostream>#include<fstream>#include<string>using namespace std;string key[8]={"do","end","for","if","printf","scanf","then","while"}; string optr[4]={"+","-","*","/"};string separator[6]={",",";","{","}","(",")"};char ch;//判断是否为保留字bool IsKey(string ss) {int i;for(i=0;i<8;i++)if(!strcmp(key[i].c_str(),ss.c_str()))return true;return false;}//字母判断函数bool IsLetter(char c) {if(((c>='a')&&(c<='z'))||((c>='A')&&(c<='Z')))return true;return false;}//数字判断函数bool IsDigit(char c) {if(c>='0'&&c<='9')return true;return false;}//运算符判断函数bool IsOptr(string ss) {int i;for(i=0;i<4;i++)if(!strcmp(optr[i].c_str(),ss.c_str()))return true ;return false;}//分界符判断函数bool IsSeparator(string ss) {int i;for(i=0;i<6;i++)if(!strcmp(separator[i].c_str(),ss.c_str()))return true;return false;}void analyse(ifstream &in) {string st="";char ch;int line=1,row=0;while((in.get(ch))) {st="";if((ch==' ')||(ch=='\t')){} //空格,tab健elseif(ch=='\n') {line++;row=0; } //换行行数加一处理elseif(IsLetter(ch)) //关键字、标识符的处理{row++;while(IsLetter(ch)||IsDigit(ch)){st+=ch;in.get(ch);}in.seekg(-1,ios::cur);//文件指针(光标)后退一个字节if(IsKey(st)) //判断是否为关键字查询关键字表;cout<<st<<"\t("<<st<<","<<1<<")"<<'\t'<<'\t'<<"关键字"<<'\t'<<"("<<line<<","<<row<<")"<<endl;else //否则为标示符cout<<st<<"\t("<<st<<","<<2<<")"<<'\t'<<'\t'<<"标识符"<<'\t'<<"("<<line<<","<<row<<")"<<endl;}elseif(IsDigit(ch)) //无符号整数处理{row++;while(IsDigit(ch)){st+=ch;ch=in.get();}in.seekg(-1,ios::cur);cout<<st<<"\t("<<st<<","<<3<<")"<<'\t'<<'\t'<<"常数"<<'\t'<<"("<<line<<","<<row<<")"<<endl;// break;}else{st="";st+=ch;if(IsOptr(st)) //运算符处理{row++;cout<<st<<"\t("<<st<<","<<4<<")"<<'\t'<<'\t'<<"运算符"<<"("<<line<<","<<row<<")"<<endl;}elseif(IsSeparator(st))//分隔符处理{ row++;cout<<st<<"\t("<<st<<","<<5<<")"<<'\t'<<'\t'<<"分界符"<<'\t'<<"("<<line<<","<<row<<")"<<endl;}else{switch(ch){row++;case'=' : {row++;cout<<"="<<"\t("<<"="<<","<<"6"<<")"<<'\t'<<"\t关系运算符"<<'\t'<<"("<<line<<","<<row<<")"<<endl;}case'>' :{row++;ch=in.get();if(ch=='=')cout<<">="<<'\t'<<"("<<">="<<","<<"6"<<")"<<'\t'<<"\t关系运算符"<<'\t'<<"("<<line<<","<<row<<")"<<endl;else {cout<<">"<<"\t("<<">"<<","<<"6"<<")"<<'\t'<<"\t关系运算符"<<'\t'<<"("<<line<<","<<row<<")"<<endl;in.seekg(-1,ios::cur);}} break;case'<' :{row++;ch=in.get();if(ch=='=')cout<<"<="<<'\t'<<"("<<"="<<","<<"6"<<")"<<"\t关系运算符"<<'\t'<<"("<<line<<","<<row<<")"<<endl;else if(ch=='>') cout<<"<>"<<'\t'<<"("<<"<>"<<","<<"6"<<")"<<'\t'<<"\t关系运算符"<<'\t'<<"("<<line<<","<<row<<")"<<endl;else{cout<<"<"<<"\t("<<"<"<<","<<"6"<<")"<<"\t"<<"\t关系运算符"<<'\t'<<"("<<line<<","<<row<<")"<<endl;in.seekg(-1,ios::cur);}}break;default :{row++; cout<<ch<<'\t'<<"\t$无法识别字符"<<'\t'<<"("<<line<<","<<row<<")"<<endl;}}}}}}int main(){ifstream in;in.open("test.txt",ios::in);cout<<"关键字-》1 标识符-》2 常数-》3 运算符-》4 分隔符-》5"<<endl;if(in.is_open()){analyse(in);in.close();system("pause");}elsecout<<"文件操作出错"<<endl;}语法分析实验源代码LL#include<iostream>using namespace std;const int MaxLen=20; //初始化栈的长度const int Length=20;//初始化数组长度char Vn[5]={'E','G','T','S','F'};//非终结符数组char Vt[8]={'i','(',')','+','-','*','/','#'};//终结符数组char ch,X;//ch读当前字符,X获取栈顶元素char strToken[Length];//存储规约表达式struct LL//ll(1)分析表的构造字初始化{char*c;};LL E[8]={"TG","TG","error","error","error","error","error","error"};LL G[8]={"error","error","null","+TG","-TG","error","error","null"};LL T[8]={"FS","FS","error","error","error","error","error","error"};LL S[8]={"error","error","null","null","null","*FS","/FS","null"};LL F[8]={"i","(E)","error","error","error","error","error","error"};class stack//栈的构造及初始化{public:stack();//初始化bool empty() const;//是否为空bool full() const;//是否已满bool get_top(char &c)const;//取栈顶元素bool push(const char c);//入栈bool pop();//删除栈顶元素void out();//输出栈中元素~stack(){}//析构private:int count;//栈长度char data[MaxLen];//栈中元素};stack::stack(){count=0;}bool stack::empty() const{if(count==0)return true;return false;}bool stack::full() const{if(count==MaxLen)return true;return false;}bool stack::get_top(char &c)const{if(empty())return false;else{c=data[count-1];return true;}}bool stack::push(const char c){if(full())return false;data[count++]=c;return true;}bool stack::pop(){if(empty())return false;count--;return true;}void stack::out(){for(int i=0;i<count;i++)cout<<data[i];cout<<'\t';}int length(char *c){int l=0;for(int i=0;c[i]!='\0';i++)l++;return l;}void print(int i,char*c)//剩余输入串的输出{for(int j=i;j<Length;j++)cout<<c[j];cout<<'\t';}void run(){bool flag=true;//循环条件int step=0,point=0;//步骤、指针int len;//长度cout<<"输入规约的字符串:"<<endl;cin>>strToken;ch=strToken[point++];//读取第一个字符stack s;s.push('#');//栈中数据初始化s.push('E');s.get_top(X);//取栈顶元素cout<<"步骤\t"<<"分析栈\t"<<"剩余输入串\t\t"<<"所用产生式\t"<<"动作"<<endl;cout<<step++<<'\t';s.out();print(point-1,strToken);cout<<'\t'<<"初始化"<<endl;while(flag){if((X==Vt[0])||(X==Vt[1])||(X==Vt[2])||(X==Vt[3])||(X==Vt[4])||(X==Vt[5])||(X==Vt[6])) //判断是否为终结符(不包括#){if(X==ch)//终结符,识别,进行下一字符规约{s.pop();s.get_top(X);ch=strToken[point++];cout<<step++<<'\t';s.out();print(point-1,strToken);cout<<'\t'<<"GETNEXT(I)"<<endl;}else{flag=false;}}else if(X=='#')//规约结束{if(X==ch){cout<<step++<<'\t';s.out();print(point-1,strToken);cout<<X<<"->"<<ch<<'\t'<<"结束"<<endl;s.pop();flag=false;}else{flag=false;}}else if(X==Vn[0]) //非终结符E{for(int i=0;i<8;i++)//查分析表if(ch==Vt[i]){if(strcmp(E[i].c,"error")==0)//出错{flag=false;}else{ //对形如X->X1X2的产生式进行入栈操作s.pop();len=length(E[i].c)-1;for(int j=len;j>=0;j--)s.push(E[i].c[j]);cout<<step++<<'\t';s.out();print(point-1,strToken);cout<<X<<"->"<<E[i].c<<'\t'<<"POP,PUSH(";for(int j=len;j>=0;j--)cout<<E[i].c[j];cout<<")"<<endl;s.get_top(X);}}}else if(X==Vn[1]) //同上,处理G{for(int i=0;i<8;i++)if(ch==Vt[i]){if(strcmp(G[i].c,"null")==0){s.pop();cout<<step++<<'\t';s.out();print(point-1,strToken);cout<<X<<"->"<<"ε"<<'\t'<<"POP"<<endl;s.get_top(X);}else if(strcmp(G[i].c,"error")==0){flag=false;}else{s.pop();len=length(G[i].c)-1;for(int j=len;j>=0;j--)s.push(G[i].c[j]);cout<<step++<<'\t';s.out();print(point-1,strToken);cout<<X<<"->"<<G[i].c<<'\t'<<"POP,PUSH(";for(int j=len;j>=0;j--)cout<<G[i].c[j];cout<<")"<<endl;s.get_top(X);}}}else if(X==Vn[2]) //同上处理T{for(int i=0;i<8;i++)if(ch==Vt[i]){if(strcmp(T[i].c,"error")==0){flag=false;}else{s.pop();len=length(T[i].c)-1;for(int j=len;j>=0;j--)s.push(T[i].c[j]);cout<<step++<<'\t';s.out();print(point-1,strToken);cout<<X<<"->"<<T[i].c<<'\t'<<"POP,PUSH(";for(int j=len;j>=0;j--)cout<<T[i].c[j];cout<<")"<<endl;s.get_top(X);}}}else if(X==Vn[3])//同上处理S{for(int i=0;i<8;i++)if(ch==Vt[i]){if(strcmp(S[i].c,"null")==0){s.pop();cout<<step++<<'\t';s.out();print(point-1,strToken);cout<<X<<"->"<<"ε"<<'\t'<<"POP"<<endl;s.get_top(X);}else if(strcmp(S[i].c,"error")==0){flag=false;}else{s.pop();len=length(S[i].c)-1;for(int j=len;j>=0;j--)s.push(S[i].c[j]);cout<<step++<<'\t';s.out();print(point-1,strToken);cout<<X<<"->"<<S[i].c<<'\t'<<"POP,PUSH(";for(int j=len;j>=0;j--)cout<<S[i].c[j];cout<<")"<<endl;s.get_top(X);}}}else if(X==Vn[4]) //同上处理F{for(int i=0;i<7;i++)if(ch==Vt[i]){if(strcmp(F[i].c,"error")==0){flag=false;}else{s.pop();len=length(F[i].c)-1;for(int j=len;j>=0;j--)s.push(F[i].c[j]);cout<<step++<<'\t';s.out();print(point-1,strToken);cout<<X<<"->"<<F[i].c<<'\t'<<"POP,PUSH(";for(int j=len;j>=0;j--)cout<<F[i].c[j];cout<<")"<<endl;s.get_top(X);}}}else //出错处理{flag= false;}}}int main(){cout<<"实验二"<<endl;run();system("pause");return 0;}语法实验源代码LR#include<iostream>using namespace std;const int MaxLen=20; //初始化栈的长度const int Length=20;//初始化数组长度char ch,Y;//全局变量,ch用于读当前字符,Y用于获取栈顶元素char strToken[Length];//存储规约表达式bool flag=true;//循环条件int point=0,step=1;//步骤、指针class stack//栈的构造及初始化{public:stack();//初始化bool empty() const;//是否为空bool full() const;//是否已满bool get_top(char &c)const;//取栈顶元素bool push(const char c);//入栈bool pop();void out();//输出栈中元素void out1();~stack(){}//析构private:int count;//栈长度char data[MaxLen];//栈中元素};stack l,r;//l代表符号栈,r代表状态栈stack::stack(){count=0;}bool stack::empty() const{if(count==0)return true;return false;}bool stack::full() const{if(count==MaxLen)return true;return false;}bool stack::get_top(char &c)const{if(empty())return false;else{c=data[count-1];return true;}}bool stack::push(const char c){if(full())return false;data[count++]=c;return true;}bool stack::pop(){if(empty())return false;count--;return true;}void stack::out(){for(int i=0;i<count;i++)cout<<data[i];cout<<'\t';}void stack::out1(){for(int i=0;i<count;i++)cout<<int(data[i]);cout<<'\t';}void print(int i,char*c)//剩余输入串的输出{for(int j=i;j<Length;j++)cout<<c[j];cout<<'\t';}void Goto(int i,char c)//状态转换函数,对应于表中GOTO {if(i==0){if(c=='E'){r.push(1);cout<<",GOTO(0,E)=1入栈"<<endl;}else if(c=='T'){r.push(2);cout<<",GOTO(0,T)=2入栈"<<endl;}else if(c=='F'){r.push(3);cout<<",GOTO(0,F)=3入栈"<<endl;}elseflag=false;}else if(i==4){if(c=='E'){r.push(8);cout<<",GOTO(4,E)=8入栈"<<endl;}else if(c=='T'){r.push(2);cout<<",GOTO(4,T)=2入栈"<<endl;}else if(c=='F'){r.push(3);cout<<",GOTO(4,F)=3入栈"<<endl;}elseflag=false;}else if(i==6){if(c=='T'){r.push(9);cout<<",GOTO(6,T)=9入栈"<<endl;}else if(c=='F'){r.push(3);cout<<",GOTO(6,F)=3入栈"<<endl;}elseflag=false;}else if(i==7){if(c=='F'){r.push(10);cout<<",GOTO(7,F)=10入栈"<<endl;}elseflag=false;}elseflag=false;}void Action0()//状态0时{if(ch=='i')//下一个操作符为i ,移进{cout<<step++<<'\t';r.out1();l.out();print(point-1,strToken);cout<<"ACTION[0,i]=S5,状态5入栈"<<endl;r.push(5);l.push(ch);ch=strToken[point++];}else if(ch=='(')//下一个操作符为( ,移进{cout<<step++<<'\t';r.out1();l.out();print(point-1,strToken);cout<<"ACTION[0,(]=S4,状态4入栈"<<endl;r.push(4);l.push(ch);ch=strToken[point++];}elseflag=false;}void Action1()//状态1{if(ch=='+')//下一个操作符为i ,移进{cout<<step++<<'\t';r.out1();l.out();print(point-1,strToken);cout<<"ACTION[1,+]=S6,状态6入栈"<<endl;r.push(6);l.push(ch);ch=strToken[point++];}else if(ch=='#')//分析成功{flag=false;cout<<step++<<'\t';r.out1();l.out();print(point-1,strToken);cout<<"Acc:分析成功"<<endl;}elseflag=false;}void Action2() //状态2{if(ch=='*')//下一个操作符为* ,移进{cout<<step++<<'\t';r.out1();l.out();print(point-1,strToken);cout<<"ACTION[2,*]=S7,状态7入栈"<<endl;r.push(7);l.push(ch);ch=strToken[point++];}else if((ch=='+')||(ch==')')||(ch=='#'))//下一个操作符为+,),#规约{cout<<step++<<'\t';r.out1();l.out();l.pop();l.push('E');print(point-1,strToken);cout<<"r2: E→T归约";r.pop();r.get_top(Y);Goto(int(Y),'E');}elseflag=false;}void Action3()//状态3{if((ch=='+')||(ch=='*')||(ch==')')||(ch=='#'))//下一个操作符为+,*,),#规约{cout<<step++<<'\t';r.out1();l.out();l.pop();l.push('T');print(point-1,strToken);cout<<"r4: T→F归约";r.pop();r.get_top(Y);Goto(int(Y),'T');}elseflag=false;}void Action4_6_7(int x)//状态4,6,7{if(ch=='i')//下一个操作符为i ,移进{cout<<step++<<'\t';r.out1();l.out();print(point-1,strToken);cout<<"ACTION[";cout<<x<<",i]=S5,状态5入栈"<<endl;r.push(5);l.push(ch);ch=strToken[point++];}else if(ch=='(')//下一个操作符为(,移进{cout<<step++<<'\t';r.out1();l.out();print(point-1,strToken);cout<<"ACTION[";cout<<x<<",(]=S4,状态4入栈"<<endl;r.push(4);l.push(ch);ch=strToken[point++];}elseflag=false;}void Action5()//状态5{if((ch=='+')||(ch=='*')||(ch==')')||(ch=='#'))//下一个操作符为+,*,),#规约{cout<<step++<<'\t';r.out1();l.out();l.pop();l.push('F');print(point-1,strToken);cout<<"r6: F→i归约";r.pop();r.get_top(Y);Goto(int(Y),'F');}elseflag=false;}void Action8()//状态8{if(ch=='+')//下一个操作符为+ ,移进{cout<<step++<<'\t';r.out1();l.out();print(point-1,strToken);cout<<"ACTION[8,+]=S6,状态6入栈"<<endl;r.push(6);l.push(ch);ch=strToken[point++];}else if(ch==')')//下一个操作符为),移进{cout<<step++<<'\t';r.out1();l.out();print(point-1,strToken);cout<<"ACTION[8,)]=S11,状态11入栈"<<endl;r.push(11);ch=strToken[point++];}elseflag=false;}void Action9()//状态9{if(ch=='*')//下一个操作符为* ,移进{cout<<step++<<'\t';r.out1();l.out();print(point-1,strToken);cout<<"ACTION[9,*]=S7,状态7入栈"<<endl;r.push(7);l.push(ch);ch=strToken[point++];}else if((ch=='+')||(ch==')')||(ch=='#'))//下一个操作符为+,,),#规约{cout<<step++<<'\t';r.out1();l.out();l.pop();l.pop();l.pop();l.push('E');print(point-1,strToken);cout<<"r1: E→E+T归约";r.pop();r.pop();r.pop();r.get_top(Y);Goto(int(Y),'E');}elseflag=false;}void Action10()//状态10{if((ch=='+')||(ch=='*')||(ch==')')||(ch=='#'))//下一个操作符为+,*,),#规约{cout<<step++<<'\t';l.out();l.pop();l.pop();l.pop();l.push('T');print(point-1,strToken);cout<<"r3: T→T*F归约";r.pop();r.pop();r.pop();r.get_top(Y);Goto(int(Y),'T');}elseflag=false;}void Action11()//状态11{if((ch=='+')||(ch=='*')||(ch==')')||(ch=='#'))//下一个操作符为+,*,),#规约{cout<<step++<<'\t';r.out1();l.out();l.pop();l.pop();l.pop();l.push('F');print(point-1,strToken);cout<<"r5: F→(E)归约";r.pop();r.pop();r.pop();r.get_top(Y);Goto(int(Y),'F');}elseflag=false;}void run()//规约{cout<<"请输入要规约的字符串:"<<endl;cin>>strToken;cout<<"步骤\t"<<"状态栈\t"<<"符号栈\t"<<"输入串\t\t"<<"动作说明"<<endl;ch=strToken[point++];//读取第一个字符l.push('#');r.push(0);r.get_top(Y);while(flag)//循环规约{if(int(Y)==0)Action0();else if(int(Y)==1)Action1();else if(int(Y)==2)Action2();else if(int(Y)==3)Action3();else if((int(Y)==4)||(int(Y)==6)||(int(Y)==7))Action4_6_7(int(Y));else if(int(Y)==5)Action5();else if(int(Y)==8)Action8();else if(int(Y)==9)Action9();else if(int(Y)==10)Action10();else if(int(Y)==11)Action11();elseflag=false;r.get_top(Y);}}int main(){cout<<"实验三"<<endl;run();system("pause");return 0;}。
哈工大威海c语言实验报告

哈工大威海c语言实验报告
哈工大威海C语言实验报告
在哈工大威海的C语言实验中,学生们通过实验课程深入了解了C语言的基本
概念和编程技巧。
本次实验报告将介绍实验的内容、过程和结果,以及学生们
的收获和体会。
实验内容主要包括C语言的基本语法、数据类型、运算符、控制语句、函数和
数组等内容。
学生们在实验课上通过实际编程操作,掌握了C语言的基本编程
技巧和方法,深入理解了C语言的特点和应用。
在实验过程中,学生们通过编写简单的程序,如求解两个数的和、差、积、商等,加深了对C语言基本语法和运算符的理解;通过编写控制语句和循环语句,如if语句、switch语句、while循环、for循环等,加深了对程序流程控制的理解;通过编写函数和数组,加深了对模块化编程和数据结构的理解。
实验结果表明,学生们在实验课上取得了较好的成绩,通过实际操作和编程练习,加深了对C语言的理解和掌握,提高了编程能力和解决问题的能力。
通过本次实验,学生们不仅学到了C语言的基本知识和技能,还培养了团队合
作精神和创新意识,提高了解决问题的能力和实际操作的能力。
实验课程的设
计和实施,为学生们提供了一个良好的学习平台,促进了他们的综合素质和能
力的提高。
总之,哈工大威海C语言实验报告是一次成功的实验课程,学生们通过实际操
作和编程练习,深入理解了C语言的基本概念和编程技巧,取得了较好的成绩,提高了编程能力和解决问题的能力。
这将为他们今后的学习和工作打下坚实的
基础。
编译原理实验报告语法分析程序的设计

编译原理实验报告语法分析程序的设计Last updated on the afternoon of January 3, 2021实验5语法分析程序的设计(2)一、实验目的通过设计、编制、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析中算法优先分析方法。
二、实验内容设计一个文法的算法优先分析程序,判断特定表达式的正确性。
三、实验要求1、给出文法如下:G[E]E->T|E+T;T->F|T*F;F->i|(E);可以构造算符优先表如下:+ * ( ) i+*()i22)为优先关系建立优先函数,这里由学生自己选择一种方式;1、给出算符优先分析算法如下:k:=1;S[k]:=‘#’;REPEAT把下一个输入符号读进a中;IFS[k]∈V T THENj:=kELSEj:=k-1;WHILES[j]aDOBEGINREPEATQ:=S[j];IFS[j-1]∈V T THENj:=j-1ELSEj:=j-2 UNTILS[j]Q把S[j+1]…S[k]归约为某个N ; k:=j+1; S[k]:=N;ENDOFWHILE;IFS[j]aORS[j]aTHENBEGINk:=k+1;S[k]:=a ENDELSEERROR UNTILa=‘#’ 1、根据给出算法,利用适当的数据结构实现算符优先分析程序;2、 利用算符优先分析程序完成下列功能:1)手工将测试的表达式写入文本文件,每个表达式写一行,用“;”表示结束;2)读入文本文件中的表达式;3)调用实验2中的词法分析程序搜索单词;4)把单词送入算法优先分析程序,判断表达式是否正确(是否是给出文法的语言),若错误,应给出错误信息;5)完成上述功能,有余力的同学可以对正确的表达式计算出结果。
四、实验环境PC 微机DOS 操作系统或Windows 操作系统TurboC 程序集成环境或VisualC++程序集成环境五、实验步骤1、 分析文法中终结符号的优先关系;2、 存放优先关系或构造优先函数;3、利用算符优先分析的算法编写分析程序;4、写测试程序,包括表达式的读入和结果的输出;5、程序运行效果,测试数据可以参考下列给出的数据。
编译原理实验报告5_语法分析程序的设计(2)

实验5 语法分析程序的设计(2)一、实验目的通过设计、编制、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析中算法优先分析方法。
二、实验内容设计一个文法的算法优先分析程序,判断特定表达式的正确性。
三、实验要求1、给出文法如下:G[E]E->T|E+T;T->F|T*F;F->i|(E);2、计算机中表示上述优先关系,优先关系的机内存放方式有两种1)直接存放,2)为优先关系建立优先函数,这里由学生自己选择一种方式;1、给出算符优先分析算法如下:k:=1; S[k]:=‘#’;REPEAT把下一个输入符号读进a中;IF S[k]∈V T THEN j:=k ELSE j:=k-1;WHILE S[j] a DOBEGINREPEATQ:=S[j];IF S[j-1]∈V T THEN j:=j-1 ELSE j:=j-2UNTIL S[j] Q把S[j+1]…S[k]归约为某个N;k:=j+1;S[k]:=N;END OF WHILE;IF S[j] a OR S[j] a THENBEGINk:=k+1;S[k]:=aENDELSE ERRORUNTIL a=‘#’1、根据给出算法,利用适当的数据结构实现算符优先分析程序;2、利用算符优先分析程序完成下列功能:1)手工将测试的表达式写入文本文件,每个表达式写一行,用“;”表示结束;2)读入文本文件中的表达式;3)调用实验2中的词法分析程序搜索单词;4)把单词送入算法优先分析程序,判断表达式是否正确(是否是给出文法的语言),若错误,应给出错误信息;5)完成上述功能,有余力的同学可以对正确的表达式计算出结果。
四、实验环境PC微机DOS操作系统或 Windows 操作系统Turbo C 程序集成环境或 Visual C++ 程序集成环境五、实验步骤1、分析文法中终结符号的优先关系;2、存放优先关系或构造优先函数;3、利用算符优先分析的算法编写分析程序;4、写测试程序,包括表达式的读入和结果的输出;5、程序运行效果,测试数据可以参考下列给出的数据。
编译原理实验二-语法分析器的设计

班级:学号: 实验集美大学计算机工程学院实验报告课程名称:编译原理指导教师:实验项目编号:实验二实验项目名称:语法分析器的设计 一、 实验目的通过完成预测分析法的语法分析程序,了解预测分析法和递归子程序法的区 别和联系。
使了解语法分析的功能,掌握语法分析程序设计的原理和构造方法, 训练掌握开发应用程序的基本方法。
二、 实验容♦根据某一文法编制调试LL ( 1 )分析程序,以便对任意输入的符号串 进行分析。
♦构造预测分析表,并利用分析表和一个栈来实现对上述程序设计语言的分 析程序。
♦分析法的功能是利用LL (1)控制程序根据显示栈栈顶容、向前看符号以 及LL (1)分析表,对输入符号串自上而下的分析过程。
三、 实验要求1、 编程时注意编程风格:空行的使用、注释的使用、缩进的使用等。
2、 如果遇到错误的表达式,应输出错误提示信息。
四、 实验设计方案1、设计思想(1)、LL (1)文法的定义LL(1)分析法属于确定的自顶向下分析方法。
LL(1)的含义是:第一个L 表明 自顶向下分析是从左向右扫描输入串,第2个L 表明分析过程中将使用最左推导, 1表明只需向右看一个符号便可决定如何推导,即选择哪个产生式(规则)进行推 导。
LL(1)文法的判别需要依次计算FIRST 集、FOLLOW 集和SELLECT 集,然后判 断是否为LL(1)文法,最后再进行句子分析。
需要预测分析器对所给句型进行识别。
即在LL(1)分析法中,每当在符号栈 的栈顶出现非终极符时,要预测用哪个产生式的右部去替换该非终极符;当出现 终结符时,判断其与剩余输入串的第一个字符是否匹配,如果匹配,则继续分析, 否则报错。
LL(1)分析方法要求文法满足如下条件:对于任一非终极符A 的两个 不同产生式都要满足下面条件:SELECT(A->a) ASELECT(A->p)=0(2)、预测分析表构造LL(1)分析表的作用是对当前非终极符和输入符号确定应该选择用哪个产生式进行推导。
实验2 语法分析(算符优先分析)

实验2 语法分析(算符优先分析)一、实验任务:算术表达式的文法:E→ E+T | E-T | TT→ T*F | T/F | FF→(E)| i根据算符优先分析法,将表达式进行语法分析,判断一个表达式是否正确。
二、实验时间:上机2次。
三、实验过程和指导:(一)准备:1.确定算术表达式的文法,设计出算符优先关系表;2.考虑好设计方案,设计出模块结构、测试数据;3.初步编制好程序。
(二)上机实验:上机调试,发现错误,分析错误,逐渐修改完善。
(三)程序要求:程序输入/输出示例:如参考C语言的运算符。
输入如下表达式(以分号为结束)和输出结果:(1)10输出:正确(2)1+2*(15-6)输出:正确(3)(1+2)/3+4- (11+6/7)输出:正确(4)((1-2)/3+4输出:错误,出错位置是(5)1+2-3+(*4/5)输出:错误,出错位置是注意:1.为降低难度,表达式中不含变量(只含无符号整数);2.可以直接调用此法分析程序,取得单词;3.如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好,最好有详细的出错位置和出错性质说明);4.测试用的表达式事先放在文本文件中,一行存放一个表达式,同时以分号分割。
同时将预期的输出结果写在另一个文本文件中,以便和输出进行对照;5.对学有余力的同学,可增加功能:当判断一个表达式正确时,输出计算结果,计算过程用浮点表示,但要注意不要被0除。
(四)练习该实验的目的和思路:程序比较复杂,需要利用到大量的编译原理,也用到了大量编程技巧和数据结构,通过这个练习可极大提高编程能力。
程序规模大概为300行。
通过练习,掌握对表达式进行处理的一种方法。
(五)为了能设计好程序,注意以下事情:1.模块设计:将程序分成合理的多个模块(函数),每个模块做具体的同一事情。
2.写出(画出)设计方案:模块关系简图、流程图、全局变量、函数接口等。
3.编程时注意编程风格:空行的使用、注释的使用、缩进的使用、变量合理命名等。
实验二 语法分析(算符优先)

华北水利水电大学North China Institute of Water Conservancy and Hydroelectric Power编译原理实验二词法分析院系信息工程专业计算机科学与技术姓名学号指导教师实验二语法分析算符优先分析程序1.实验要求⑴选择最有代表性的语法分析方法算符优先法;⑵选择对各种常见程序语言都用的语法结构,如赋值语句(尤指表达式)作为分析对象,并且与所选语法分析方法要比较贴切。
⑶实习时间为4学时。
2.实验内容及要求(1)根据给定文法,先求出FirstVt和LastVt集合,构造算符优先关系表(要求算符优先关系表输出到显示器或者输出到文件);(2)根据算法和优先关系表分析给定表达式是否是该文法识别的正确的算术表达式(要求输出归约过程)(3)给定表达式文法为:G(E’): E’→#E#E→E+T | TT→T*F |FF→(E)|i(4)分析的句子为:(i+i)*i和i+i)*i实验源码:#include<stdio.h>#include<iostream.h>#include<string.h>#define MAX 100char *SR;char SY[MAX];char S[MAX];char grammer[10][30];char chanshengshi[20][10];char feizhongjie[10];char zhongjie[15];int numf=0;int num=0;int M=0;char Relation[6][6];int FIRSTVT[3][6];int LASTVT[3][6];void fristvt();int type(char s){int len=strlen(zhongjie);int tp=-1;for(int i=0;i<len;i++){if(s==zhongjie[i]){tp=i;break;}}return tp;}int type_fei(char s){int len=strlen(feizhongjie);int tp=-1;for(int i=0;i<len;i++){if(s==feizhongjie[i]){tp=i; break;}}return tp;}void transproduct(int n)//原始产生式处理{int x=0,y=0;for(int i=0;i<n;i++){for(int j=0;grammer[i][j]!='\0';j++){if(grammer[i][0]<'A'||grammer[i][0]>'Z'){ cout<<"该文法不是算符文发!"<<endl;return;}else{if(type_fei(grammer[i][0])<0)feizhongjie[numf++]=grammer[i][0];}if(grammer[i][j]>='A'&&grammer[i][j]<='Z'){if(grammer[i][j+1]>='A'&&grammer[i][j+1]<='Z'){cout<<"该文法不是算符文发!"<<endl;return;}}}}for(i=0;i<n;i++){for(int j=0;grammer[i][j]!='\0';j++){if((grammer[i][j]>'Z'||grammer[i][j]<'A')&&grammer[i][j]!='-'&&grammer[i][j]!='>'&&gram mer[i][j]!='|'){if(type(grammer[i][j])<0) zhongjie[num++]=grammer[i][j];//获取终结符符号}}}zhongjie[num]='#';zhongjie[num+1]='\0'; x=1;for(i=0;i<n;i++)//转换产生式从第二行开始存{chanshengshi[x][y]=grammer[i][0]; y++;for(int j=1;grammer[i][j]!='\0';j++){if(grammer[i][j]=='|'){ chanshengshi[x][y]='\0';x++;y=0;chanshengshi[x][y]=grammer[i][0]; y++;chanshengshi[x][y++]='-';chanshengshi[x][y++]='>';}else{ chanshengshi[x][y]=grammer[i][j]; y++; }}chanshengshi[x][y]='\0'; x++; y=0;}chanshengshi[0][0]=feizhongjie[0];chanshengshi[0][1]='-';chanshengshi[0][2]='>';chanshengshi[0][3]='#';chanshengshi[0][4]=feizhongjie[0];chanshengshi[0][5]='#';chanshengshi[0][6]='\0';M=x;cout<<"转换后产生式如下:"<<endl;for(int j=0;j<x;j++){cout<<chanshengshi[j]<<endl;}cout<<"产生式包含的终结符有:";for(i=0;i<=num;i++){cout<<zhongjie[i]<<" ";}cout<<endl; cout<<"产生式包含的非终结符有:";for(i=0;i<numf;i++){cout<<feizhongjie[i]<<" ";}cout<<endl;}void fristvt(){int r1,x,y;for(int i=0;i<numf;i++){for(int j=0;j<num;j++)FIRSTVT[i][j]=0; }for(i=1;i<=M;i++){r1=type_fei(chanshengshi[i][0]);x=type(chanshengshi[i][3]);y=type(chanshengshi[i][4]);if(x>=0){FIRSTVT[r1][x]=1;}else{if(y>=0)FIRSTVT[r1][y]=1;}}for(i=M;i>=1;i--){int y=type(chanshengshi[i][3]);if(y<0){int m=type_fei(chanshengshi[i][0]);int m1=type_fei(chanshengshi[i][3]);if(m!=m1){ for(int t=0;t<num;t++)if(FIRSTVT[m1][t]!=0){FIRSTVT[m][t]=FIRSTVT[m1][t];}}}}cout<<"非终结符的firstvt集:"<<endl;for(i=0;i<numf;i++){cout<<feizhongjie[i]<<" ";for(int j=0;j<num;j++){if(FIRSTVT[i][j]!=0){cout<<zhongjie[j]<<" ";}}cout<<endl;}}void lastvt(){int d=0, r1,x,y;for(int i=0;i<numf;i++){ for(int j=0;j<num;j++) LASTVT[i][j]=0; }for(i=1;i<=M;i++){ r1=type_fei(chanshengshi[i][0]);for(int cl=0;chanshengshi[i][cl]!='\0';cl++){d=cl;}x=type(chanshengshi[i][d]); y=type(chanshengshi[i][d-1]);if(x>=0){LASTVT[r1][x]=1;}else{if(y>=0) LASTVT[r1][y]=1;}}for(i=M;i>=1;i--){int y=type(chanshengshi[i][3]);if(y<0){int m=type_fei(chanshengshi[i][0]);int m1=type_fei(chanshengshi[i][3]);if(m!=m1){ for(int t=0;t<num;t++)if(LASTVT[m1][t]!=0){LASTVT[m][t]=LASTVT[m1][t];}}}}cout<<"非终结符的lastvt集:"<<endl;for(i=0;i<numf;i++){ cout<<feizhongjie[i]<<" ";for(int j=0;j<num;j++){ if(LASTVT[i][j]!=0){cout<<zhongjie[j]<<" ";}}cout<<endl;}}void creatRelation(){ int a=strlen(feizhongjie),b=strlen(zhongjie),c=strlen(*chanshengshi),x,x1,y,y1,f;for(int i=0;i<=c;i++){ int j=strlen(chanshengshi[i]);for(int v=3;v<j;v++){x=type(chanshengshi[i][v]);x1=type_fei(chanshengshi[i][v]);y=type(chanshengshi[i][v+1]);y1=type_fei(chanshengshi[i][v+1]);f=type(chanshengshi[i][v+2]);if((x>=0)&&(y>=0)){Relation[x][y]='=';}if((v<=(j-2))&&x>=0&&f>=0&&y<0){ Relation[x][f]='=';}if(x>=0&&y<0){ for(int h=0;h<b;h++)if(FIRSTVT[y1][h]==1){Relation[x][h]='<';}}if(x<0&&y>=0){ for(int g=0;g<b;g++){ if(LASTVT[x1][g]==1){Relation[g][y]='>';}}}}}}char charcomplete(char a,char b){char ret='$';int x=type(a),y=type(b);if(x>=0&&y>=0)ret=Relation[x][y];return ret;}void deelSY(){int i,j; i=strlen(SY);for(j=0;j<i;j++){SY[j]=SY[j+1];}SY[i-1]='\0';}void main(){ int numP=0;cout<<"请输入产生式规则数:";cin>>numP; cout<<"请输入产生式:"<<endl;for(int i=0;i<numP;i++){cin>>grammer[i];}transproduct(numP);fristvt();lastvt();creatRelation();cout<<"产生式的终结符对应的优先关系如下:"<<endl;FILE*fp;char str[20];cout<<" 请输入原文件名(包括后缀名):";while(true){cin>>str;if((fp=fopen(str,"r"))==NULL)cout<<"输入错误,请检查文件名"<<endl;elsebreak;}fseek(fp,0,SEEK_END);int n=ftell(fp),p=0;char ch;SR=new char [n];fseek(fp,0,SEEK_SET);while(ch!=EOF){ch=fgetc(fp);SR[p]=ch;SY[p]=ch;p++;}char a,Q,N,B;int step=0;cout<<"步骤"<<"\t"<<"符号栈"<<"\t\t"<<"输入串"<<"\t\t\t"<<"动作"<<endl;int k=1,j=0,m=1,R,r=strlen(*chanshengshi);S[k]='#';a=SR[k];B=charcomplete(S[k],a);deelSY();cout<<step<<"\t"<<S[k]<<"\t\t"<<SY<<"\t\t"<<"预备"<<endl;do{a=SR[m];m++;if(type(a)>=0) j=k;else j=k-1;B=charcomplete(S[j],a);while(B=='>'){ do{ Q=S[j];if(type(S[j-1])>=0) j--;else j=j-2;B=charcomplete(S[j],Q);}while(B!='<');for(int w=j+1;w<=k;w++) //将S[j+1]。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
哈尔滨工业大学(威海)计算机学院
编译原理实验报告
姓名 院系 计算机学院 学号
任课教师 指导教师 闫健恩
实验地点 宋健二楼机房 实验时间
实验名称
实验二LR语法分析技术
同组人 无
预习报告(对实验主要内容的认识) 得分
(1)给出主要数据结构:分析栈、符号表、语法分析树;
(2)将扫描器作为一个子程序,每次调用返回一个TOKEN;
(3)程序界面:表达式输入、语法分析树的表示结果(文件或者图形方式);
实验内容(问题,思路,程序,结果) 得分
(1)开发环境:vs2010
(2)输入:在运行打开的软件下(win32格式),输入相应的代码(即要进行
词法分析的字符串)
(3)输出:在输入字符串后,按回车键后,既可以得到相应的词法分析的结果
(4)在相应的运行程序的文件夹中生成一个txt文件,用来存储生成的Token
链表
(5)系统功能:
1、词法分析:将输入的字符串进行单词级别的分析并且生成且输
出Token表
2、语法生成器:可以将语法生成相应的状态,在这个实验中共有
语法如下:
3、CLOSURE生成
4、LR项集族的生成
6、 Goto表的生成
7、 Scaner词法分析器将Token表输出
8、语法分析器对Token表的分析,得出结果
(2) 开发平台(操作系统、设计语言):
1、操作系统:windows 7
2、设计语言:c++
3、编译器:vs2010
(3) 设计方案;
1) 主数据流图;
开始
读取构造的文法(grammar.txt)
构造item.txt 集族
构造action表,写入文档
进行语法的匹配(自底向上RL(1))
匹配时出现错误?
查找action表继续进行匹配
如果代码分析还未完成,继续
结束
Y
N
2) 主要数据结构:符号表、TOKEN串表等。
//符号表
class symTable
{
private:
char* symName;
char* symStyle;
int symLength;
public: symTable *next;
public:
symTable();
symTable(char* sysName,char* sysStyle,int sysLength);
symTable(symTable &s);
char* getName();
char* getStyle();
int getLength();
void symAdd(symTable* symFirst);
void print();
};
char G[30][30]; //use a matrix to store grammar G
//存放 文法,用来分析作为输入
int length[30]; //length use to store each formula's length
int number = 0;
bool tempofinput[150]; //buffer of input
//输入???
char str_vn[30]; //put all vn into it
int size_vn = 0;
char str_vt[150]; //put all vt into it
int size_vt = 0;
bool first_vn[30][150];
char buffer[50];
//用来存放生成CLOSURE(I)时需要的first_set 也用来读入用户的输入串^_^
int bsize = 0;
struct thri{
int beg;
int nex;
char ch;
};
thri trans[200];
int size_trans = 0;
//定义项目集的形式
struct proj{
int formula_numb;
int part;
char expc;
};
/*项目集*/
proj items[200][200];
int Ccount = 0;
int size_item[200];
/*状态转换表*/
struct action{
char ch;
int nxt_sta;
};
action action_table[200][200];
int size_act_table[200];
ifstream G_ifile;
ifstream input_ifile;
ofstream items_ofile;
ofstream act_ofile;
(4) 具体设计过程(包括主控程序、各个功能模块的具体实现)。
1、主控程序
简介:主控制流程主要包括下面的几部分:
(1) 词法分析器的子函数修改
(2) 对于输入grammar,输出集族
(3) 输入集族,可以构造出相应的action表
(4) 根据得到的action表生成相应的语法分析策略
2、对于词法的分析
简介:主要实现和在实验一中的功能相同,只是将现在的实现包装到一个
函数里面,这样就是为了对代码进行重复的快捷的利用,只是需要将得到
的程序代码作为输入,词法分析函数就会自动的生成相应的token表和相
应的符号表。
3、对于item生成
简介:自己通过分析课本上的实验伪代码,以及yacc文法代码生成工具
的研究,编写相依的item集族的生成工具,生成的I状态共有105中,
具体的实现以及生成的状态在文档中(见于:item.txt)
4、对于action生成(action+goto)
简介:通过生成的item表,构建一个action生成工具就可以得到相应的
action表格,这个表格可以进行重复的利用(只要写到函数中即可,不
需要每次都进行读入内存,然后在进行生成)
5、语法分析分析
根据LR的自底向上的方法进行语句与文法(在action中描述)进行匹
配,若匹配成功,这该语句正确,分析下一条语句,否者错误提示输出。
实验结论 得分
本次试验我学习到了一下内容:
(1)编写了一个文法分析器,参照yacc可以输入文法(按照相应的
格式),然后生成一个item项用来存放规范LR(0)项集族。输入的相应的格
式在实验内容中已经给出。(相应的生成的item表格在上文中已经给出,并且在工程的文档中也有给处)
(2)编写了一个Action表以及Goto表的生成程序(一个程序生成两
个表格归并成为一个),并且放到相应的txt中,可以适用于任何其他想要使
用这个文法的语法分析器。
(相应的生成的Action表格在上文中已经给出,并且在工程的文档中也有给处)
(3)综合了第一个实验的词法分析器,并且修正了词法分析器中一些
鲁棒性不是很好的地方。
(4)所有函数的算法思想以及实现方案,都可以在相应的源码的注释
处找到。
教师评价 总分 实际得分