语法分析器源代码

合集下载

编译器设计中的语法分析和中间代码优化

编译器设计中的语法分析和中间代码优化

编译器设计中的语法分析和中间代码优化在编译器的设计中,语法分析和中间代码优化是两个重要的阶段。

语法分析是将输入的源代码转化为语法树的过程,而中间代码优化则是对生成的中间代码进行改进,以提高目标代码的执行效率和代码质量。

一、语法分析语法分析是编译器设计中的一个重要环节,它的主要任务是将输入的源代码转化为一棵语法树。

语法树是编译器在进一步处理代码之前生成的一种数据结构,它以树的形式表示代码的语法结构。

在语法分析阶段,编译器会对源代码进行词法分析,并根据语法规则构建语法树。

1. 词法分析词法分析是将源代码分解为一个个的词法单元(Token)的过程。

每个Token代表着源代码中的一个有意义的单词,如变量名、操作符、关键词等等。

编译器会通过词法分析器识别出这些词法单元,并将其传递给语法分析器进行后续处理。

2. 语法规则语法规则定义了源代码中各种语句和表达式的结构和组织方式。

在语法分析阶段,编译器会根据这些语法规则来构建语法树。

语法规则一般使用上下文无关文法(Context-Free Grammar)来描述。

3. 构建语法树通过词法分析和语法规则,编译器可以逐步构建语法树。

语法树是一种树状数据结构,以根节点表示整个代码块,每个内部节点表示一个语法单元,叶节点表示一个词法单元。

编译器可以根据语法树进行后续的语义分析和代码生成。

二、中间代码优化中间代码优化是编译器设计的另一重要环节,它的主要目标是改进生成的中间代码,以提高目标代码的执行效率和代码质量。

在中间代码优化阶段,编译器会对生成的中间代码进行分析和改进。

1. 常量传播常量传播是一种中间代码优化技术,它的目标是将程序中的常量表达式计算出实际的结果,并将结果用于后续的代码生成。

常量传播可以减少运行时的计算量,提高程序的执行效率。

2. 冗余代码消除冗余代码是指程序中不会被执行的代码,它们不会对程序的结果产生任何影响。

冗余代码消除可以通过分析中间代码的控制流来判断哪些代码是冗余的,并将其消除掉。

软件开发中的语法分析器技术

软件开发中的语法分析器技术

软件开发中的语法分析器技术在软件开发中,语法分析器技术是一项十分重要的技术,它负责将代码进行解析和翻译,从而进行编译或执行。

语法分析器技术可以帮助开发人员识别并纠正代码中的错误,提高编程效率和代码质量。

本文将介绍语法分析器技术的相关知识和应用。

什么是语法分析器?语法分析器是一种翻译器,其作用是将源代码转换为目标代码或解释执行。

它的主要任务是进行句法分析和语义分析,检查代码的正确性和逻辑性,同时生成代码树以生成目标代码或解释执行。

语法分析器可以划分为两种类型:自下而上语法分析器和自上而下语法分析器。

自下而上语法分析器是一种逆向分析方式,它从最小的语法单元开始,将其组合成较大的语法单元,最终生成一棵代码树。

自上而下语法分析器则是先由代码的上层结构进行分析,逐级分解为更小的语法单元,最后得到一颗代码树。

语法分析器的作用语法分析器在软件开发中具有非常重要的作用,它可以提高代码的正确性和可读性,同时能够检测并纠正代码中的错误,加快软件开发过程。

具体来说,语法分析器能够:1.检查代码的正确性语法分析器能够在编译或执行代码之前检查代码的正确性。

它能够检查代码中的语法错误、类型错误、语义错误等,在代码编写过程中及时发现并及时纠正错误,提高代码的质量和可维护性。

2.加快编译及执行速度语法分析器能够将源代码转换为目标代码或解释执行,加快程序的执行速度。

它能够分析代码逻辑,优化相关代码的执行流程,同时减少代码执行的时间。

3.提高代码可读性语法分析器能够将代码转换成易于理解和维护的代码,同时增强代码的可读性。

例如,它可以将代码中重复的部分统一,提高代码的可读性和可维护性。

语法分析器的应用语法分析器在软件开发中广泛应用,具体包括以下方面:1.编译器编译器是一种将源代码转换为目标代码的软件。

编译过程包括词法分析、语法分析、代码生成等,其中语法分析器起着非常重要的作用,它能够将代码转换为目标代码或解释执行。

2.解析器解析器是一种将指定格式的文本转换为结构化数据的软件。

语法分析程序的设计与实现

语法分析程序的设计与实现

◆词法分析 用户必须提供一个词法分析器来读取输入流并把记号(带有值, 如果需要的话)传达到解析器。词法分析器使叫做 yylex 的整数值的 函数。这个函数返回一个整数的记号编号,它表示读取的记号的种类。 如果这个记号关联着一个值,应当把它赋予外部变量 yylval。 为使通信得以发生,解析器和词法分析器必须在记号编号上达成 一致。编号可以由 Yacc 或用户来选择。在这两种情况下,使用 C 语 言的“# define”机制允许词法分析器使用符号来返回这些编号。例如, 假定在 Yacc 规定文件的声明段中已经定义记号名字 DIGIT。 它的意图是返回一个 DIGIT 记号编号,和等于这个数字的数值 的一个值。倘若词法分析器代码位于规定文件的程序段,标识符 DIGIT 将被定义为与记号 DIGIT 关联的记号编号。 这种机制导致清晰的、易于修改的词法分析器;唯一的缺点是在 文法中需要避免使用任何在 C 语言或解析器中保留的或有意义的记 号名字;例如,使用记号名字 if 或 while 就一定会导致编译词法分 析器时出现严峻的困难。记号名字 error 保留给错误处理,不应该随 便使用。 同上所述,记号编号可以由 Yacc 或用户来选择。在缺省的条件 下,编号由 Yacc 选择。文字字符的缺省记号编号是它在本地字符集 中的字符数值。其他名字赋予从 257 开始的记号编号。 要把一个记号编号赋予一个记号(包括文字),可以在声明段中记 号或文字的第一次出现时直接跟随着一个非负整数。这个整数被接受
第四:YACC 内部名称: ................................................................................................ 7 第五:运行结果(源代码见附录).............................................................................. 8 第六:实验总结 ............................................................................................................... 8 第七:附录 ..................................................................................................................... 10

PL0语言语法分析器实验报告

PL0语言语法分析器实验报告

PL0语言语法分析器实验报告一、引言编译器是一种用于把高级语言程序转换成机器可执行代码的软件工具。

编译器由多个组件构成,其中语法分析器是编译器中的重要组成部分,其主要功能是对输入的源代码进行解析,并生成一个语法树。

本实验旨在通过使用BNF(巴科斯范式)描述PL0语言的语法规则,并通过实现PL0语言的语法分析器,来深入理解语法分析的原理和过程。

二、PL0语言的语法规则1.程序结构:<程序>::=[<常量说明部分>][<变量说明部分>][<过程说明部分>]<语句>2.常量说明部分:<常量说明部分> ::= const <常量定义> { , <常量定义> };<常量定义>::=<标识符>=<无符号整数>3.变量说明部分:<变量说明部分> ::= var <标识符> { , <标识符> };4.过程说明部分:<过程说明部分>::=<过程首部><分程序>;<过程首部> ::= procedure <标识符> ;5.语句:<语句> ::= <赋值语句> , <if语句> , <while语句> , <调用语句> , <复合语句> , <读语句> , <写语句> , <空><赋值语句>::=<标识符>:=<表达式><if语句> ::= if <条件> then <语句> else <语句><while语句> ::= while <条件> do <语句><调用语句> ::= call <标识符><复合语句> ::= begin <语句> { ; <语句> } end<读语句> ::= read ( <标识符> )<写语句> ::= write ( <表达式> )6.表达式:<表达式>::=[+,-]<项>{(+,-)<项>}<项>::=<因子>{(*,/)<因子>}<因子>::=<标识符>,<无符号整数>,(<表达式>)7.条件:<条件>::=<表达式><关系运算符><表达式><关系运算符>::==,<>,<,<=,>,>=三、PL0语言的语法分析器设计与实现1.设计思路本次实验中,我们将使用自顶向下的递归下降分析法,来对PL0语言进行语法分析。

编译原理实验词法分析语法分析

编译原理实验词法分析语法分析

本代码只供学习参考:词法分析源代码:#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;}。

编译原理-语法分析器-仅供参考,不可滥用!

编译原理-语法分析器-仅供参考,不可滥用!

青岛理工大学课程实验报告
(2).递归下降分析程序示意图(左)语法串分析程序示意图(右)
(4)statement 语法分析程序流程图(左)expression表达式分析函数示意图(右)
(3)term分析函数示意图(左)factor分析过程示意图(右)
调试过程及实验1.测试一
输入begin x:=9; x:=2*3; b:=a+x;end ;# 后经语法分析输出如图所示:


2.测试二
输入x:=a+b*c end # 后经语法分析输出如图所示:
3.测试三
输入 begin q:=6; d:=4; end #,经语法分析输出如图所示:
4.测试四
输入 begin a:=4;b:=5;c:=a*b+a #,经语法分析输出如图所示:
总结
通过本次试验,我们设计出了一个比较符合要求的语法分析器,同时了解了语法分析的过程,其主程序大致流程为:“置初值”→调用wordScanAnalyse函数读下一个单词符号→调用IrParse→结束。

分析程序的各个判断条件可以知道,需要调用函数factor();expression();yucu();term();statement();lrparser();其中嵌套了条件语句
使得拥有较为全面的处理机制,当程序不以“begin”开头,或不以“end #”。

编译-词法分析器-语法分析器实验报告

编译-词法分析器-语法分析器实验报告

一、目的编译技术是理论与实践并重的课程,而其实验课要综合运用一、二年级所学的多门课程的内容,用来完成一个小型编译程序。

从而巩固和加强对词法分析、语法分析、语义分析、代码生成和报错处理等理论的认识和理解;培养学生对完整系统的独立分析和设计的能力,进一步培养学生的独立编程能力。

二、任务及要求基本要求:1.词法分析器产生下述小语言的单词序列这个小语言的所有的单词符号,以及它们的种别编码和内部值如下表:单词符号种别编码助记符内码值DIMIFDO STOP END标识符常数(整)=+***,()1234567891011121314$DIM$IF$DO$STOP$END$ID$INT$ASSIGN$PLUS$STAR$POWER$COMMA$LPAR$RPAR------内部字符串标准二进形式------对于这个小语言,有几点重要的限制:首先,所有的关键字(如IF﹑WHILE等)都是“保留字”。

所谓的保留字的意思是,用户不得使用它们作为自己定义的标示符。

例如,下面的写法是绝对禁止的:IF(5)=x其次,由于把关键字作为保留字,故可以把关键字作为一类特殊标示符来处理。

也就是说,对于关键字不专设对应的转换图。

但把它们(及其种别编码)预先安排在一张表格中(此表叫作保留字表)。

当转换图识别出一个标识符时,就去查对这张表,确定它是否为一个关键字。

再次,如果关键字、标识符和常数之间没有确定的运算符或界符作间隔,则必须至少用一个空白符作间隔(此时,空白符不再是完全没有意义的了)。

例如,一个条件语句应写为IF i>0 i= 1;而绝对不要写成IFi>0 i=1;因为对于后者,我们的分析器将无条件地将IFI看成一个标识符。

这个小语言的单词符号的状态转换图,如下图:2.语法分析器能识别由加+ 减- 乘* 除/ 乘方^ 括号()操作数所组成的算术表达式,其文法如下:E→E+T|E-T|TT→T*F|T/F|FF→P^F|Pp→(E)|i使用的算法可以是:预测分析法;递归下降分析法;算符优先分析法;LR分析法等。

词法分析器(含完整源码)

词法分析器(含完整源码)
}//error
void Scanner(char ch[],int chLen,Table table[Max],int nLine) {
int chIndex = 0;
while(chIndex < chLen) //对输入的字符扫描 { /**************************处理空格和 tab ************************/
六、总结:
词法分析是构造编译器的起始阶段,也是相应比较简单的一个环节。词法分析的主要任 务是:根据构造的状态转换图,从左到右逐个字符地対源程序进行扫描,识别开源程序中具 有独立含义的最小语法单位——符号或单词,如变量标识符,关键字,常量,运算符,界符 等。
然后将提取出的标识符以内码的形式表示,即用 int 类型的数字来表示其类型和在 display 表中的位置,而无须保留原来标识符本身的字符串,这不仅节省了内存空间,也有 利于下一阶段的分析工作。
typedef struct DisplayTable {
int Index; //标识符所在表的下标 int type; //标识符的类型 int line; //标识符所在表的行数 char symbol[20]; //标识符所在表的名称 }Table;
int TableNum = 0; //display 表的下标 char Word[WordMaxNum][20]; //标识符表 char Digit[WordMaxNum][20]; //数字表 int WordNum = 0; //变量表的下标 int DigNum = 0; //常量表的下标 bool errorFlag = 0; //错误标志
当然,在扫描源程序串的同时,进行一些简单的处理,如删除空格、tab、换行等无效 字符,也进行了一些基本的错误处理,如变量长度的判别,有些不合词法规则的标识符判别 等。总之,严格说来,词法分析程序只进行和词法分析相关的工作。

编译原理词法分析和语法分析报告+代码(C语言版)[1]

编译原理词法分析和语法分析报告+代码(C语言版)[1]

词法分析一、实验目的设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。

二、实验要求2.1 待分析的简单的词法(1)关键字:begin if then while do end所有的关键字都是小写。

(2)运算符和界符:= + - * / < <= <> > >= = ; ( ) #(3)其他单词是标识符(ID)和整型常数(SUM),通过以下正规式定义:ID = letter (letter | digit)*NUM = digit digit*(4)空格有空白、制表符和换行符组成。

空格一般用来分隔ID、SUM、运算符、界符和关键字,词法分析阶段通常被忽略。

2.2 各种单词符号对应的种别码:输入:所给文法的源程序字符串。

输出:二元组(syn,token或sum)构成的序列。

其中:syn为单词种别码;token为存放的单词自身字符串;sum为整型常数。

例如:对源程序begin x:=9: if x>9 then x:=2*x+1/3; end #的源文件,经过词法分析后输出如下序列:(1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)……三、词法分析程序的算法思想:算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。

3.1 主程序示意图:主程序示意图如图3-1所示。

其中初始包括以下两个方面:⑴关键字表的初值。

关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。

如能查到匹配的单词,则该单词为关键字,否则为一般标识符。

关键字表为一个字符串数组,其描述如下:Char *rwtab[6] = {“begin”, “if”, “then”, “while”, “do”, “end”,};图3-1(2)程序中需要用到的主要变量为syn,token和sum3.2 扫描子程序的算法思想:首先设置3个变量:①token用来存放构成单词符号的字符串;②sum用来整型单词;③syn用来存放单词符号的种别码。

编译原理语法分析器实验报告

编译原理语法分析器实验报告

编译原理语法分析器实验报告西安邮电大学编译原理实验报告学院名称:计算机学院****:***实验名称:语法分析器的设计与实现班级:计科1405班学号:04141152时间:2017年5月12日把SELECT (i)存放到temp中结果返回1;1.构建好的预测分析表2.语法分析流程图一.实验结果正确运行结果:错误运行结果:二.设计技巧和心得体会这次实验编写了一个语法分析方法的程序,但是在LL(1)分析器的编写中我只达到了最低要求,就是自己手动输入的select集,first集,follow集然后通过程序将预测分析表构造出来,然后自己编写总控程序根据分析表进行分析。

通过本次试验,我能够设计一个简单的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析方法。

还能选择最有代表性的语法分析方法,如LL(1) 语法分析程序、算符优先分析程序和LR分析分析程序。

三.源代码package com.LL1;import java.util.ArrayDeque;import java.util.Deque;/*** LL1文法分析器,已经构建好预测分析表,采用Deque实现* Created by HongWeiPC on 2017/5/12.*/public class LL1_Deque {//预测分析表private String[][] analysisTable = new String[][]{{"TE'", "", "", "TE'", "", ""},{"", "+TE'", "", "", "ε", "ε"},{"FT'", "", "", "FT'", "", ""},{"", "ε", "*FT'", "", "ε", "ε"},{"i", "", "", "(E)", "", ""}};//终结符private String[] VT = new String[]{"i", "+", "*", "(", ")", "#"};//非终结符private String[] VN = new String[]{"E", "E'", "T", "T'", "F"};//输入串strTokenprivate StringBuilder strToken = new StringBuilder("i*i+i");//分析栈stackprivate Deque<String> stack = new ArrayDeque<>();//shuru1保存从输入串中读取的一个输入符号,当前符号private String shuru1 = null;//X中保存stack栈顶符号private String X = null;//flag标志预测分析是否成功private boolean flag = true;//记录输入串中当前字符的位置private int cur = 0;//记录步数private int count = 0;public static void main(String[] args) {LL1_Deque ll1 = new LL1_Deque();ll1.init();ll1.totalControlProgram();ll1.printf();}//初始化private void init() {strToken.append("#");stack.push("#");System.out.printf("%-8s %-18s %-17s %s\n", "步骤", "符号栈", "输入串", "所用产生式");stack.push("E");curCharacter();System.out.printf("%-10d %-20s %-20s\n", count, stack.toString(), strToken.substring(cur, strToken.length()));}//读取当前栈顶符号private void stackPeek() {X = stack.peekFirst();}//返回输入串中当前位置的字母private String curCharacter() {shuru1 = String.valueOf(strToken.charAt(cur));return shuru1;}//判断X是否是终结符private boolean XisVT() {for (int i = 0; i < (VT.length - 1); i++) {if (VT[i].equals(X)) {return true;}}return false;}//查找X在非终结符中分析表中的横坐标private String VNTI() {int Ni = 0, Tj = 0;for (int i = 0; i < VN.length; i++) {if (VN[i].equals(X)) {Ni = i;}}for (int j = 0; j < VT.length; j++) {if (VT[j].equals(shuru1)) {Tj = j;}}return analysisTable[Ni][Tj];}//判断M[A,a]={X->X1X2...Xk}//把X1X2...Xk推进栈//X1X2...Xk=ε,不推什么进栈private boolean productionType() {return VNTI() != "";}//推进stack栈private void pushStack() {stack.pop();String M = VNTI();String ch;//处理TE' FT' *FT'特殊情况switch (M) {case "TE'":stack.push("E'");stack.push("T");break;case "FT'":stack.push("T'");stack.push("F");break;case "*FT'":stack.push("T'");stack.push("F");stack.push("*");break;case "+TE'":stack.push("E'");stack.push("T");stack.push("+");break;default:for (int i = (M.length() - 1); i >= 0; i--) {ch = String.valueOf(M.charAt(i));stack.push(ch);}break;}System.out.printf("%-10d %-20s %-20s %s->%s\n", (++count), stack.toString(), strToken.substring(cur, strToken.length()), X, M);}//总控程序private void totalControlProgram() {while (flag) {stackPeek(); //读取当前栈顶符号令X=栈顶符号if (XisVT()) {if (X.equals(shuru1)) {cur++;shuru1 = curCharacter();stack.pop();System.out.printf("%-10d %-20s %-20s \n", (++count), stack.toString(), strToken.substring(cur, strToken.length()));} else {ERROR();}} else if (X.equals("#")) {if (X.equals(shuru1)) {flag = false;} else {ERROR();}} else if (productionType()) {if (VNTI().equals("")) {ERROR();} else if (VNTI().equals("ε")) {stack.pop();System.out.printf("%-10d %-20s %-20s %s->%s\n", (++count), stack.toString(), strToken.substring(cur, strToken.length()), X, VNTI());} else {pushStack();}} else {ERROR();}}}//出现错误private void ERROR() {System.out.println("输入串出现错误,无法进行分析");System.exit(0);}//打印存储分析表private void printf() {if (!flag) {System.out.println("****分析成功啦!****");} else {System.out.println("****分析失败了****");}}}。

编译原理中的语法分析与中间代码生成

编译原理中的语法分析与中间代码生成

编译原理中的语法分析与中间代码生成编译原理是计算机科学中一门非常重要的学科,主要研究将高级语言翻译成机器语言的方法和技术。

其中,语法分析和中间代码生成是编译器实现的两个重要步骤。

一、语法分析语法分析是编译器将源代码转换成抽象语法树的过程。

在这个阶段,编译器会检查源代码的语法是否符合语言规范,并将代码转化为一系列的语法结构。

一个好的语法分析器能够快速准确地识别代码中的语言结构,同时能够在出现语法错误的时候给出有意义的错误报告。

常见的语法分析方法包括LL(1)分析、LR分析等。

LL(1)分析器通过构造预测分析表来实现分析,而LR分析器则采用自底向上的分析方法,通过状态迁移来实现分析。

在语法分析的过程中,编译器还需要处理语法的优先级,如算术运算符的优先级,逻辑运算符的优先级等。

对于不同的语言规范,将有不同的算法来处理语法。

例如,C语言中的运算符优先级和结合性与其他语言不同,因此需要特殊的处理方式。

二、中间代码生成中间代码生成是语法分析后的下一步,它的作用是将抽象语法树转化为中间表示,通常是三地址码或四地址码。

中间代码可以看作是目标代码的前一步,它是一种更加抽象的代码形式,方便后续的优化和翻译。

中间代码的生成方法有很多种,最常用的是遍历抽象语法树并根据语法结构生成中间代码。

不同的语言规范会对中间代码的生成方式有不同的要求。

例如,Java语言规范对着重于类型检查和异常处理的中间代码生成,而C语言的中间代码生成则着重于指针和数组的处理等。

在生成中间代码的过程中,编译器还需要考虑优化问题。

编译器能够在生成中间代码的时候进行一些基本的优化,例如删除冗余代码、常量合并等等,这样可以减少目标代码的大小和程序的运行时间。

总之,语法分析和中间代码生成是编译器实现的两个关键步骤。

它们需要一个好的算法和优秀的实现方式,以便在编译过程中产生高效、可靠的目标代码。

编译原理语法分析器

编译原理语法分析器

编译原理语法分析器编译原理语法分析器是编译器中的重要组成部分,它负责将源代码解析成抽象语法树,为后续的语义分析和代码生成做准备。

本文将介绍语法分析器的原理、分类和常用算法。

一、语法分析器的原理语法分析器的主要任务是根据给定的文法定义,将源代码解析成一个个语法单元,并构建出一棵抽象语法树。

它通过递归下降、预测分析和LR分析等算法来实现。

1. 递归下降法递归下降法是一种基于产生式的自顶向下分析方法。

它从文法的开始符号出发,通过不断地推导和回溯,逐步地构建抽象语法树。

递归下降法易于理解和实现,但对左递归和回溯有一定的局限性。

2. 预测分析法预测分析法也是自顶向下的分析方法,它通过预测下一个输入符号来选择适当的产生式进行推导。

为了提高效率,预测分析法使用预测分析表来存储各个非终结符和终结符的关系。

3. LR分析法LR分析法是一种自底向上的分析方法,它使用LR自动机和LR分析表来进行分析。

LR自动机是一个有限状态控制器,通过状态转移和规约动作来解析源代码。

LR分析表存储了状态转移和规约的规则。

二、语法分析器的分类根据语法分析器的特性和实现方式,可以将其分为LL分析器和LR 分析器。

1. LL分析器LL分析器是基于递归下降法和预测分析法的一类分析器。

它从左到右、从左到右地扫描源代码,并根据预测分析表进行推导。

常见的LL分析器有LL(1)分析器和LL(k)分析器。

2. LR分析器LR分析器是基于LR分析法的一类分析器。

它先通过移进-归约的方式建立一棵语法树,然后再进行规约操作。

LR分析器具有强大的语法处理能力,常见的LR分析器有LR(0)、SLR(1)、LR(1)和LALR(1)分析器。

三、常用的语法分析算法除了递归下降法、预测分析法和LR分析法,还有一些其他的语法分析算法。

1. LL算法LL算法是一种递归下降法的改进算法,它通过构造LL表和预测分析表实现分析过程。

LL算法具有很好的可读性和易于理解的特点。

2. LR算法LR算法是一种自底向上的分析方法,它通过建立LR自动机和构造LR分析表来进行分析。

编译原理词法分析和语法分析报告+代码[C语言版]

编译原理词法分析和语法分析报告+代码[C语言版]

词法分析一、实验目的设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。

二、实验要求2.1 待分析的简单的词法(1)关键字:begin if then while do end所有的关键字都是小写。

(2)运算符和界符:= + - * / < <= <> > >= = ; ( ) #(3)其他单词是标识符(ID)和整型常数(SUM),通过以下正规式定义:ID = letter (letter | digit)*NUM = digit digit*(4)空格有空白、制表符和换行符组成。

空格一般用来分隔ID、SUM、运算符、界符和关键字,词法分析阶段通常被忽略。

2.2 各种单词符号对应的种别码:表2.1 各种单词符号对应的种别码2.3 词法分析程序的功能:输入:所给文法的源程序字符串。

输出:二元组(syn,token或sum)构成的序列。

其中:syn为单词种别码;token为存放的单词自身字符串;sum为整型常数。

例如:对源程序begin x:=9: if x>9 then x:=2*x+1/3; end #的源文件,经过词法分析后输出如下序列:(1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)……三、词法分析程序的算法思想:算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。

3.1 主程序示意图:主程序示意图如图3-1所示。

其中初始包括以下两个方面:⑴关键字表的初值。

关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。

如能查到匹配的单词,则该单词为关键字,否则为一般标识符。

关键字表为一个字符串数组,其描述如下:Char *rwtab[6] = {“begin”, “if”, “then”, “while”, “do”, “end”,};是图3-1(2)程序中需要用到的主要变量为syn,token和sum3.2 扫描子程序的算法思想:首先设置3个变量:①token用来存放构成单词符号的字符串;②sum用来整型单词;③syn用来存放单词符号的种别码。

c++ 源代码解析

c++ 源代码解析

c++ 源代码解析要解析C++源代码,您可以使用诸如libclang、gcc或者自定义的解析器。

这些工具可以帮助您获取源代码的词法分析、语法分析和语义分析等信息。

一种常见的方法是使用libclang——C语言家族的强大分析引擎。

libclang提供了一个C接口,可以方便地集成到C++程序中。

使用libclang,您可以遍历源代码,访问每个标记(tokens)和语法元素,并获取其相关信息,如类型、位置、依赖关系等。

同时,还可以使用libclang进行代码补全、重构等功能。

另一个选择是使用GNU Compiler Collection (GCC),它是一个广泛使用的编译器套件,包含了C、C++和其他语言的编译器。

GCC提供了一个非常强大的前端抽象语法树(Abstract Syntax Tree,AST)来表示源代码,并提供了一系列的API来操作和分析这些AST。

除了使用现有的工具外,您还可以尝试自己实现一个简单的C++源代码解析器。

解析C++源代码需要经历以下几个步骤:1. 词法分析(Lexical Analysis):将源代码划分为若干个词法单元(tokens),例如关键字、标识符、运算符、常量等。

2. 语法分析(Syntax Analysis):根据语法规则建立抽象语法树(AST),表示源代码的结构。

可以使用自顶向下(Top-down)或自底向上(Bottom-up)的方法来构建AST。

3. 语义分析(Semantic Analysis):在AST的基础上进行后续的语义检查,如类型检查、作用域分析等。

这一步可以用于检测潜在的错误和问题。

4. 语义处理(Semantic Processing):根据AST进行进一步的处理,如符号表生成、代码优化等。

值得注意的是,C++是一门复杂的语言,其语法和语义规则都非常庞大,因此实现一个完整的C++解析器是一项非常复杂的任务。

如果您只是想获取一些特定的信息,可以考虑使用现有的工具来简化开发过程。

实验5-LL(1)语法分析程序的设计与实现(C语言)

实验5-LL(1)语法分析程序的设计与实现(C语言)

实验五LL(1)文法识别程序设计一、实验目的通过LL(1)文法识别程序的设计理解自顶向下的语法分析思想。

二、实验重难点FIRST集合、FOLLOW集合、SELECT集合元素的求解,预测分析表的构造。

三、实验内容与要求实验内容:1.阅读并理解实验案例中LL(1)文法判别的程序实现;2.参考实验案例,完成简单的LL(1)文法判别程序设计。

四、实验学时4课时五、实验设备与环境C语言编译环境六、实验案例1.实验要求参考教材93页预测分析方法,94页图5.11 预测分析程序框图,编写表达式文法的识别程序。

要求对输入的LL(1)文法字符串,程序能自动判断所给字符串是否为所给文法的句子,并能给出分析过程。

表达式文法为:E→E+T|TT→T*F|FF→i|(E)2.参考代码为了更好的理解代码,建议将图5.11做如下标注:/* 程序名称: LL(1)语法分析程序 *//* E->E+T|T *//* T->T*F|F *//* F->(E)|i *//*目的: 对输入LL(1)文法字符串,本程序能自动判断所给字符串是否为所给文法的句子,并能给出分析过程。

/********************************************//* 程序相关说明 *//* A=E' B=T' *//* 预测分析表中列号、行号 *//* 0=E 1=E' 2=T 3=T' 4=F *//* 0=i 1=+ 2=* 3=( 4=) 5=# *//************************************/#include"iostream"#include "stdio.h"#include "malloc.h"#include "conio.h"/*定义链表这种数据类型参见:*/struct Lchar{char char_ch;struct Lchar *next;}Lchar,*p,*h,*temp,*top,*base;/*p指向终结符线性链表的头结点,h指向动态建成的终结符线性链表节点,top和base分别指向非终结符堆栈的顶和底*/char curchar; //存放当前待比较的字符:终结符char curtocmp; //存放当前栈顶的字符:非终结符int right;int table[5][6]={{1,0,0,1,0,0},{0,1,0,0,1,1},{1,0,0,1,0,0},{0,1,1,0,1,1},{1,0,0,1,0,0}};/*存放预测分析表,1表示有产生式,0表示无产生式。

编译原理名词解释

编译原理名词解释

编译原理名词解释1. 词法分析器(Lexer):也称为扫描器(Scanner),用于将源代码分割成一个个单词(Token)。

2. 语法分析器(Parser):将词法分析器生成的单词序列转换成语法树(Parse Tree)或抽象语法树(Abstract Syntax Tree)。

3. 语法树(Parse Tree):表示源代码的语法结构的树状结构,它由语法分析器根据语法规则生成。

4. 抽象语法树(Abstract Syntax Tree):比语法树更加简化和抽象的树状结构,用于表示源代码的语义结构。

5. 语义分析器(Semantic Analyzer):对抽象语法树进行语义检查,并生成中间代码或目标代码。

6. 中间代码(Intermediate code):一种介于源代码和目标代码之间的中间表示形式,可以被不同的优化器和代码生成器使用。

7. 目标代码生成器(Code Generator):将中间代码转换成特定目标平台的机器代码。

8. 优化器(Optimizer):用于对中间代码进行优化,以提高代码的执行效率和资源利用率。

9. 符号表(Symbol Table):用于存储程序中的标识符(变量、函数等)的信息,包括名称、类型等。

10. 语言文法(Grammar):定义了一种语言的语法规则,常用的形式包括上下文无关文法和正则文法。

11. 上下文无关文法(Context-free Grammar):一种形式化的语法表示方法,由产生式和非终结符组成,描述一种语言的句子结构。

12. 语言解释器(Interpreter):将源代码逐行解释执行的程序,不需要生成目标代码。

13. 回溯法(Backtracking):一种递归式的算法,用于在语法分析过程中根据产生式进行选择。

14. 正则表达式(Regular Expression):用于描述一类字符串的表达式,可以用于词法分析中的模式匹配。

15. 自顶向下分析(Top-down Parsing):从文法的起始符号开始,按照语法规则逐步构建语法树的过程。

编译原理实验报告词法分析器语法分析器

编译原理实验报告词法分析器语法分析器

编译原理实验报告实验一一、实验名称:词法分析器的设计二、实验目的:1,词法分析器能够识别简单语言的单词符号2,识别出并输出简单语言的基本字.标示符.无符号整数.运算符.和界符。

三、实验要求:给出一个简单语言单词符号的种别编码词法分析器四、实验原理:1、词法分析程序的算法思想算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。

2、程序流程图(1)主程序(2)扫描子程序3五、实验内容:1、实验分析编写程序时,先定义几个全局变量a[]、token[](均为字符串数组),c,s( char型),i,j,k(int型),a[]用来存放输入的字符串,token[]另一个则用来帮助识别单词符号,s用来表示正在分析的字符。

字符串输入之后,逐个分析输入字符,判断其是否‘#’,若是表示字符串输入分析完毕,结束分析程序,若否则通过int digit(char c)、int letter(char c)判断其是数字,字符还是算术符,分别为用以判断数字或字符的情况,算术符的判断可以在switch语句中进行,还要通过函数int lookup(char token[])来判断标识符和保留字。

2 实验词法分析器源程序:#include <>#include <>#include <>int i,j,k;char c,s,a[20],token[20]={'0'};int letter(char s){if((s>=97)&&(s<=122)) return(1);else return(0);}int digit(char s){if((s>=48)&&(s<=57)) return(1);else return(0);}void get(){s=a[i];i=i+1;}void retract(){i=i-1;}int lookup(char token[20]){if(strcmp(token,"while")==0) return(1);else if(strcmp(token,"if")==0) return(2);else if(strcmp(token,"else")==0) return(3);else if(strcmp(token,"switch")==0) return(4);else if(strcmp(token,"case")==0) return(5);else return(0);}void main(){printf("please input string :\n");i=0;do{i=i+1;scanf("%c",&a[i]);}while(a[i]!='#');i=1;j=0;get();while(s!='#'){ memset(token,0,20);switch(s){case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':case 'g':case 'h':case 'i':case 'j':case 'k':case 'l':case 'm':case 'n':case 'o':case 'q':case 'r':case 's':case 't':case 'u':case 'v':case 'w':case 'x':case 'y':case 'z':while(letter(s)||digit(s)){token[j]=s;j=j+1;get();}retract();k=lookup(token);if(k==0)printf("(%d,%s)",6,token);else printf("(%d,-)",k);break;case '0':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':while(digit(s)){token[j]=s;j=j+1;get();}retract();printf("%d,%s",7,token);break;case '+':printf("('+',NULL)");break;case '-':printf("('-',null)");break; case '*':printf("('*',null)");break;case '<':get();if(s=='=') printf("(relop,LE)");else{retract();printf("(relop,LT)");}break;case '=':get();if(s=='=')printf("(relop,EQ)");else{retract();printf("('=',null)");}break;case ';':printf("(;,null)");break;case ' ':break;default:printf("!\n");}j=0;get();} }六:实验结果:实验二一、实验名称:语法分析器的设计二、实验目的:用C语言编写对一个算术表达式实现语法分析的语法分析程序,并以四元式的形式输出,以加深对语法语义分析原理的理解,掌握语法分析程序的实现方法和技术。

语法分析器的源代码

语法分析器的源代码

using System;using System.IO;using System.Collections.Generic;using ponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;namespace WindowsFormsApplication3{public partial class Form1 : Form{public Form1(){InitializeComponent();}struct pronode{public char leftch;public string midch;public string rightch;public string select;}struct unnifo{public char ch;public string first;public string follow;}unnifo[] firstfollow = new unnifo[20];//放first 和follow;pronode[] proNode = new pronode[30];//产生式pronode[,] table1 = new pronode[15, 15];//分析表string vnstr;//非终结符string vtstr;//终结符string kong;//含有空的终结符int lenvn;//定义非终结符的个数int lenwenfa;//定义产生式的数目public void getvnstr()//取非终结符函数{int i;int len = proNode.Length;for (i = 0; i < len; i++){if (vnstr == null){vnstr += proNode[i].leftch;}else{int lenth = vnstr.Length;int j;for (j = 0; j < lenth; j++){if (proNode[i].leftch == vnstr[j]){break;}}if (j == lenth){vnstr += proNode[i].leftch;}}}}public void getvtstr()//取终结符函数{bool flag;int i;int len = proNode.Length;for (i = 0; i < lenwenfa; i++){int lenth = proNode[i].rightch.Length;int j;for (j = 0; j < lenth; j++){flag = true;if (isvn(proNode[i].rightch[j])){flag = false;}else{if (proNode[i].rightch[j] == '?'){flag = false;if (kong == null){kong += proNode[i].leftch;}else{int k;int leng = kong.Length;for (k = 0; k < leng; k++){if (proNode[i].rightch[j] == kong[k]){break;}}if (k == leng + 1){kong += proNode[i].leftch;}}}else{if (flag){if (vtstr == null){vtstr += proNode[i].rightch[j];}else{int h;int lenvt = vtstr.Length;for (h = 0; h < lenvt; h++){if (proNode[i].rightch[j] == vtstr[h]){break;}}if (h == lenvt){vtstr += proNode[i].rightch[j];}}}}}}}}public void createfirf()//定义first和follow 集函数{int i;int len = vnstr.Length;for (i = 0; i < len; i++){firstfollow[i].ch = vnstr[i];firstfollow[i].first = "";firstfollow[i].follow = "";}}public void getlenvn()//取终结符个数函数{lenvn = vnstr.Length;}public Boolean isvn(char ch)//比较是非终结符{int i;string vn;vn = textBox1.Text;for (i = 0; i < vn.Length; i++){if (vn[i] == ch){return true;}}return false;}public Boolean isvt(char ch)//比较是终结符函数{int i;string vt;vt = textBox2.Text;for (i = 0; i < vt.Length; i++){if (vt[i] == ch){return true;}}return false;}public string addchar(string vtstrch, char ch)//在字符串中加字符{bool flag = true;int temlen = vtstrch.Length;for (int i = 0; i < temlen; i++){if (vtstrch[0] == ch){flag = false;break;}}if (flag){vtstrch = vtstrch + ch;}return vtstrch;}public Boolean iskongch(char ch)//判断字符为能推出空集的非终结符;{int i;string temkong;temkong = textBox3.Text;for (i = 0; i < temkong.Length; i++){if (ch == temkong[i]){return true;}}return false;}public string addchtoch(string chstr, string otherarr)//在字符串终结字符串函数{int otherlen = otherarr.Length;for (int j = 0; j < otherlen; j++){bool flag = true;int tmlen = chstr.Length;for (int i = 0; i < tmlen; i++){if (chstr[i] == otherarr[j]){flag = false;break;}}if (flag){if (otherarr[j] != '?'){chstr = chstr + otherarr[j].ToString();}}}return chstr;}public void first1()//求first集的第一步骤{int i;for (i = 0; i < lenvn; i++){for (int j = 0; j < lenwenfa; j++){if (firstfollow[i].ch == proNode[j].leftch){int lenth = firstfollow[i].first.Length;int k;for (k = 0; k < lenth; k++){if (firstfollow[i].first[k] == proNode[j].rightch[0]){break;}}if (k == lenth){firstfollow[i].first += proNode[j].rightch[0].ToString();}}}}}public void first2()//求first集的第二步骤{int i;for (i = 0; i < lenvn; i++){int j;char ch;int lenth = firstfollow[i].first.Length;for (j = 0; j <= lenth - 1; j++){if (isvn(firstfollow[i].first[j]) == true)//判断first集中是否有非终结符;{ch = firstfollow[i].first[j];for (int h = 0; h < lenvn; h++){if (firstfollow[h].ch == ch){firstfollow[i].first = firstfollow[i].first.Remove(j, 1);firstfollow[i].first = addchtoch(firstfollow[i].first, firstfollow[h].first);}}lenth = firstfollow[i].first.Length;j = 0;}}}}public void follow1()//求follow 集的第一步{int i;firstfollow[0].follow = addchar(firstfollow[0].follow, '#');//开始符要先加‘#’;for (i = 0; i < lenvn; i++){for (int j = 0; j < lenwenfa; j++){int k;for (k = 0; k < proNode[j].rightch.Length; k++){if (proNode[j].rightch[k] == firstfollow[i].ch)//判断右边的字符串中的非终结符有等于等于要求follow集的非终结符;{if (k + 1 == proNode[j].rightch.Length)//判断要求follow集的非终结符为右边字符串的最后一个字符;{int lenth2 = firstfollow[i].follow.Length;if (lenth2 == 0){firstfollow[i].follow = firstfollow[i].follow + proNode[j].leftch;//将该文法产生式的左边字符加到follow集中}else{for (int m = 0; m < lenth2; m++){if (firstfollow[i].follow[m] != proNode[j].leftch){firstfollow[i].follow = firstfollow[i].follow + proNode[j].leftch;}}}}if (k + 1 < proNode[j].rightch.Length)//判断要求follow集的非终结符的在右边字符串中出现且不是在最后一个字符{char ch = proNode[j].rightch[k + 1];if (isvt(ch))//判断是终结符{int lenth1 = firstfollow[i].follow.Length;if (lenth1 == 0){firstfollow[i].follow = firstfollow[i].follow + ch;}else{firstfollow[i].follow = addchar(firstfollow[i].follow, ch);}}if (isvn(ch))//判断为非终结符{if (!iskongch(ch))//该非终结不能推出空集;{for (int n = 0; n < lenvn; n++){if (firstfollow[n].ch == ch){addchtoch(firstfollow[i].follow, firstfollow[n].first);}}}else{for (int w = 0; w < lenvn; w++){if (firstfollow[w].ch == ch){addchtoch(firstfollow[i].follow, firstfollow[w].first);}int lenth3 = firstfollow[i].follow.Length;for (int l = 0; l < lenth3; l++){if (firstfollow[i].follow[l] != proNode[j].leftch){firstfollow[i].follow += proNode[j].leftch;}}}}}}}}}}}public void follow2()//求follow集的第二步{int i;for (i = 0; i < lenvn; i++){char ch;int lenth = firstfollow[i].follow.Length;int j;for (j = 0; j < lenth; j++){if (isvn(firstfollow[i].follow[j]))//判断follow集中是否有非终结符;{ch = firstfollow[i].follow[j];for (int k = 0; k < lenvn; k++){if (firstfollow[k].ch == ch){firstfollow[i].follow = firstfollow[i].follow.Remove(j, 1);firstfollow[i].follow = addchtoch(firstfollow[i].follow, firstfollow[k].follow);}}lenth = firstfollow[i].follow.Length;j = 0;}}}}public void select()//求select集{int i;for (i = 0; i < lenwenfa; i++){if (isvt(proNode[i].rightch[0])){int lenth = proNode[i].select.Length;int j;for (j = 0; j < lenth; j++){if (proNode[i].select[j] == proNode[i].rightch[0]){break;}}if (j == lenth){proNode[i].select += proNode[i].rightch[0];}}if (proNode[i].rightch[0] == '?')//集中'?'来表示空集;{int k;for (k = 0; k < lenvn; k++){if (firstfollow[k].ch == proNode[i].leftch){proNode[i].select = addchtoch(proNode[i].select, firstfollow[k].follow);}}}if (isvn(proNode[i].rightch[0])){int h;for (h = 0; h < lenvn; h++){if (firstfollow[h].ch == proNode[i].rightch[0]){int len = firstfollow[h].first.Length;int m;proNode[i].select = addchtoch(proNode[i].select, firstfollow[h].first);for (m = 0; m < len; m++){if (firstfollow[h].first[m] == '?')//集中'?'来表示空集;{int n;for (n = 0; n < lenvn; n++){if (firstfollow[n].ch == proNode[i].leftch){proNode[i].select = addchtoch(proNode[i].select, firstfollow[n].follow);}}}}}}}}}public int getvn(char ch)//求字符在非终结中的位置{int i;string vn;vn = textBox1.Text;for (i = 0; i < vn.Length; i++){if (vn[i] == ch){return i;}}return -1;}public int getvt(char ch)//求字符在终结符中的位置{int j;string vt;vt = textBox2.Text;for (j = 0; j < vt.Length; j++){if (vt[j] == ch){return j;}}return -1;}public void create_table()//建立分析表{int row;int col;int k;for (k = 0; k < lenwenfa; k++){int m;int lensel = proNode[k].select.Length;for (m = 0; m < lensel; m++){row = getvn(proNode[k].leftch);col = getvt(proNode[k].select[m]);table1[row, col] = proNode[k];}}}public void prtable(int m, int n)//输出表中每个元素{if (m != -1 && n != -1){richTextBox1.AppendText(table1[m, n].leftch + table1[m, n].midch + table1[m, n].rightch);}}public void shtabel()//显示表的内容{richTextBox1.AppendText("\t");int i;string vt;vt = textBox2.Text;for (i = 0; i < vt.Length; i++){richTextBox1.AppendText(vt[i] + "\t");}int k;for (k = 0; k < vt.Length; k++){if (vt[k] == '#'){richTextBox1.AppendText("\n");break;}}if (k == vt.Length)richTextBox1.AppendText("#" + "\n");}int j;string vn;vn = textBox1.Text;for (j = 0; j < vn.Length; j++){richTextBox1.AppendText(vn[j] + "\t");for (int n = 0; n < lenvn; n++){prtable(j, n);richTextBox1.AppendText("\t");}richTextBox1.AppendText("\n");}}public char getfirst(string str)//取第一个字符{char ch;int len;len = str.Length;if (len == 0){return (' ');}else{ch = str[0];return ch;}}public string remfirst(string str1)//删除第一个字符{int len = str1.Length;if (len == 0){return ("");}else{str1 = str1.Remove(0, 1);return str1;}public char getlast(string str)//取最后一个字符{char ch;int len;len = str.Length;if (len == 0){return (' ');}else{ch = str[len - 1];return ch;}}public string remlast(string str1)//删除最后一个字符{int len = str1.Length;if (len == 0){return ("");}else{str1 = str1.Remove(len - 1, 1);return str1;}}public void error(){richTextBox1.AppendText("分析错误!" + "\n"); }public void success(){richTextBox1.AppendText("Successful!" + "\n"); }public void scan()//分析过程{string prstr;int step = 1;int left;int right;char ch;char ch1;bool flag = true;string temstr = "#S";prstr = textBoxch.Text;richTextBox1.AppendText("步骤" + "\t" + "符号栈" + "\t" + "读入符号" + "\t" + "剩余符号串" + "\t" + "使用产生式" + "\n");richTextBox1.AppendText(step + "\t" + temstr + "\t");step++;ch = getfirst(prstr);prstr = remfirst(prstr);richTextBox1.AppendText(ch + "\t" + "\t");while (flag){richTextBox1.AppendText(prstr + "\t" + "\t");ch1 = getlast(temstr);temstr = remlast(temstr);left = getvn(ch1);right = getvt(ch);prtable(left, right);if (isvt(ch1)){if (ch1 == ch){richTextBox1.AppendText(ch1 + "匹配" + "\n");ch = getfirst(prstr);prstr = remfirst(prstr);richTextBox1.AppendText(step + "\t" + temstr + "\t" + ch + "\t" + "\t");step++;}else{flag = false;error();}}else{if (ch1 == '#'){if (ch == ch1){richTextBox1.AppendText("分析成功!" + "\n");success();flag = false;}else{flag = false;error();}}else{left = getvn(ch1);right = getvt(ch);if (right != -1){if (table1[left, right].leftch != '\0'){if (table1[left, right].rightch[0] != '?')//集中'?'来表示空集;{richTextBox1.AppendText("\n");int lenrigth = table1[left, right].rightch.Length;int len1;for (len1 = lenrigth - 1; len1 >= 0; len1--){temstr += table1[left, right].rightch[len1];}richTextBox1.AppendText(step + "\t" + temstr + "\t" + ch + "\t" + "\t");step++;}else{richTextBox1.AppendText("\n");richTextBox1.AppendText(step + "\t" + temstr + "\t" + ch + "\t" + "\t");step++;}}else{flag = false;error();}}else{flag = false;error();}}}}}public void getwenfa()//初始化文法数组{string[] s = richTextBox2.Text.Split('\n');int i;lenwenfa = s.Length - 1;for (i = 0; i < lenwenfa; i++){int j;proNode[i].leftch = s[i][0];proNode[i].midch += s[i][1];proNode[i].midch += s[i][2];for (j = 3; j < s[i].Length; j++){proNode[i].rightch += s[i][j];}proNode[i].select = "";}}private void Form1_Load(object sender, EventArgs e){for (int i = 0; i < lenwenfa; i++){richTextBox2.AppendText(proNode[i].leftch + proNode[i].midch + proNode[i].rightch + "\n");}}private void button2_Click(object sender, EventArgs e)//求字符按钮{getwenfa();getvnstr();textBox1.Text = vnstr;getvtstr();textBox2.Text = vtstr;textBox3.Text = kong;createfirf();getlenvn();}private void butn_Click_1(object sender, EventArgs e)//分析按钮{string temstr;first1();first2();follow1();follow2();richTextBox1.AppendText("非终结符" + "\t" + "FIRST集" + "\t" + "\t" + "FOLLOW 集" + "\n");for (int i = 0; i < lenvn; i++){richTextBox1.AppendText(firstfollow[i].ch + "\t" + "\t" + firstfollow[i].first + "\t" + "\t" + firstfollow[i].follow + "\n");}richTextBox1.AppendText("\n");select();richTextBox1.AppendText("文法产生式" + "\t" + "SELECT集" + "\n");for (int j = 0; j < lenwenfa; j++){richTextBox1.AppendText(proNode[j].leftch + proNode[j].midch + proNode[j].rightch + "\t" + "\t" + proNode[j].select + "\n");}richTextBox1.AppendText("\n");create_table();richTextBox1.AppendText("**************欢迎你使用该语法分析器**************" + "\n");richTextBox1.AppendText("\n");richTextBox1.AppendText("预测分析表:" + "\n");shtabel();richTextBox1.AppendText("\n");temstr = textBoxch.Text;if (temstr != "")//要求输入一个句子{int lenth = temstr.Length;if (temstr[lenth - 1] == '#')//要求输入的句子以‘#’结束;{scan();}else{MessageBox.Show("请以“#“结尾!");richTextBox1.Text = "";}}else{MessageBox.Show("请输入句子!");textBoxch.Text = "";richTextBox1.Text = "";}}private void button1_Click(object sender, EventArgs e)//清除按钮{textBoxch.Text = "";richTextBox1.Text = "";}private void 清除ToolStripMenuItem_Click_1(object sender, EventArgs e) {textBoxch.Text = "";richTextBox1.Text = "";}private void 说明ToolStripMenuItem_Click_1(object sender, EventArgs e) {MessageBox.Show("本程序所有权属于本程序的开发者!");}private void button3_Click(object sender, EventArgs e)//打开文件按钮{if (openFileDialog1.ShowDialog() == DialogResult.OK){FileStream fs = new FileStream(openFileDialog1.FileName, FileMode.Open);StreamReader sw = new StreamReader(fs);while (!sw.EndOfStream){richTextBox2.AppendText(sw.ReadLine() + "\n");}sw.Close();}}}}。

北方工业大学计算机专业编译原理实验报告——语法分析器详细代码报告

北方工业大学计算机专业编译原理实验报告——语法分析器详细代码报告
cout<<" i > > > > e2 > e2 >"<<endl;
else if(m==0)
cout<<"="<<setw(8);
else
cout<<"<"<<setw(8);
cout<<a<<setw(10);
cout<<&strings[k]<<setw(10);
if(t)
{
cout<<"归约"<<setw(8);
No[n++]=step-1;
}
else
cout<<"移进"<<setw(8);
{
push(a);
print(0,0);
if(stack[top]!='#')
goto u;
}
else
{
error(j);
a='#';
}
}
}while(a!='#');
}
void main()
{
cout<<"*********算符优先语法分析程序*********"<<endl;
cout<<" E->E+T|E-T|T"<<endl;
}
else
printf("\n错误e3:非法右括号!");
}
void prior_analysis()
相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

语法分析程序的源代码
#include<stdio.h>
#include<string.h>
char prog[80],token[6];
char ch;
int syn,p,m,n,sum,kk=0;
char * rwtab[6]={"begin","if","then","while","do","end"};
main()
{
p=0;
printf("\nplease intput string:");
do
{
ch=getchar();
prog[p++]=ch;
}while(ch!='#');
p=0;
scaner();
lrparser();
getch();
}
/*词法扫描程序:*/
scaner()
{
for(n=0;n<8;n++)
token[n]=NULL;
m=0;
ch=prog[p++];
while(ch==' ')ch=prog[p++];
if((ch<='z'&&ch>='a')||(ch<='Z'&&ch>='A'))
{
while((ch<='z'&&ch>='a')||(ch<='Z'&&ch>='A')||(ch<='9'&&ch>='0')) {
token[m++]=ch;
ch=prog[p++];
}
token[m++]='\0';
ch=prog[--p];
syn=10;
for(n=0;n<6;n++)
if(strcmp(token,rwtab[n])==0)
{
syn=n+1;
break;
}
}
else
if((ch<='9'&&ch>='0'))
{
sum=0;
while((ch<='9'&&ch>='0'))
{
sum=sum*10+ch-'0';
ch=prog[p++];
}
ch=prog[--p];
syn=11;
}
else
switch(ch)
{
case '<':m=0;token[m++]=ch;
ch=prog[p++];
if(ch=='>')
{
syn=21;
token[m++]=ch;
}
else
if(ch=='=')
{
syn=22;
token[m++]=ch;
}
else
{
syn=20;
ch=prog[--p];
}
break;
case '>':token[m++]=ch;
ch=prog[p++];
if(ch=='=')
{
syn=24;
token[m++]=ch;
}
else
{
syn=23;
ch=prog[--p];
}
break;
case ':':token[m++]=ch;
ch=prog[p++];
if(ch=='=')
{
syn=18;
token[m++]=ch;
}
else
{
syn=17;
ch=prog[--p];
}
break;
case '+':syn=13;token[0]=ch;break;
case '-':syn=14;token[0]=ch;break;
case '*':syn=15;token[0]=ch;break;
case '/':syn=16;token[0]=ch;break;
case ':=':syn=18;token[0]=ch;break;
case '<>':syn=21;token[0]=ch;break;
case '<=':syn=22;token[0]=ch;break;
case '>=':syn=24;token[0]=ch;break;
case '=':syn=25;token[0]=ch;break;
case ';':syn=26;token[0]=ch;break;
case '(':syn=27;token[0]=ch;break;
case ')':syn=28;token[0]=ch;break;
case '#':syn=0;token[0]=ch;break;
default:syn=-1;
}
}
lrparser()
{
if(syn==1)
{
scaner();
if(syn==6)
{
scaner();
if((syn==0)&&(kk==0))
printf("sucess");
}
else
{
if(kk!=1) printf("lost end error!");
kk=1;
}
}
else
{
printf("output of begin is error!");
kk=1;
}
return;
}
yucu()
{
statement();
while(syn==26)
{
scaner();
statement();
}
return;
}
statement()
{
if(syn==10)
{
scaner();
if(syn==18)
{
scaner();
expression();
}
{
printf("output of equal is error!");
kk=1;
}
}
else
{
printf("input of sentence is error!");
kk=1;
}
return;
}
expression()
{
term();
while(syn==13||syn==14)
{
scaner();
term();
}
return;
}
term()
{
factor();
while(syn==15||syn==16)
{
scaner();
factor();
}
return;
}
factor()
{
if(syn==10||syn==11)scaner();
else
if(syn==27)
{
scaner();
expression();
if(syn==28)scaner();
else
{
printf("output ')' is error!");
kk=1;
}
}
else
{
printf("output expression is error!");
kk=1;
}
return;
}。

相关文档
最新文档