编译原理 语法分析实验二

合集下载

编译原理实验报告5-语法分析程序的设计(2)

编译原理实验报告5-语法分析程序的设计(2)

实验5 语法分析程序的设计(2)一、实验目的通过设计、编制、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析中算法优先分析方法。

二、实验内容设计一个文法的算法优先分析程序,判断特定表达式的正确性。

三、实验要求1、给出文法如下:G[E]E->T|E+T;T->F|T*F;F->i|(E);可以构造算符优先表如下:+ * ( ) i+*()i2、计算机中表示上述优先关系,优先关系的机内存放方式有两种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]:=a ENDELSE ERROR UNTIL a=‘#’1、 根据给出算法,利用适当的数据结构实现算符优先分析程序;2、 利用算符优先分析程序完成下列功能:1) 手工将测试的表达式写入文本文件,每个表达式写一行,用“;”表示结束; 2) 读入文本文件中的表达式;3) 调用实验2中的词法分析程序搜索单词;4) 把单词送入算法优先分析程序,判断表达式是否正确(是否是给出文法的语言),若错误,应给出错误信息;5) 完成上述功能,有余力的同学可以对正确的表达式计算出结果。

四、实验环境PC 微机DOS 操作系统或 Windows 操作系统Turbo C 程序集成环境或 Visual C++ 程序集成环境五、实验步骤1、 分析文法中终结符号的优先关系;2、 存放优先关系或构造优先函数;3、利用算符优先分析的算法编写分析程序;4、写测试程序,包括表达式的读入和结果的输出;5、程序运行效果,测试数据可以参考下列给出的数据。

编译原理_实验二_语法分析_递归下降分析器设计_实验报告

编译原理_实验二_语法分析_递归下降分析器设计_实验报告

递归下降分析器设计一、实验/实习过程内容:利用JavaCC生成一个MiniC的语法分析器;要求:1. 用流的形式读入要分析的C语言程序,或者通过命令行输入源程序。

2. 具有错误检查的能力,如果有能力可以输出错误所在的行号,并简单提示3. 如果输入的源程序符合MiniC的语法规范,输出该程序的层次结构的语法树具体实施步骤如下:1.把MiniC转换为文法如下<程序〉→ main()〈语句块〉〈语句块〉→{〈语句串〉}〈语句串〉→〈语句〉〈语句串〉|〈语句〉〈语句〉→〈赋值语句〉|〈条件语句〉|〈循环语句〉〈赋值语句〉→ ID =〈表达式〉;〈条件语句〉→ if〈条件〉〈语句块〉〈循环语句〉→ while〈条件〉〈语句块〉〈条件〉→(〈表达式〉〈关系符〉〈表达式〉)〈表达式〉→〈表达式〉〈运算符〉〈表达式〉|(〈表达式〉)|ID|NUM〈运算符〉→+|-|*|/〈关系符〉→<|<=|>|>=|==|!=2.消除语句中的回溯与左递归3.在eclipse环境下完成JavaCC的插件安装后,写一个JavaCC文法规范文件(扩展名为jj)4.完成的功能包括词法分析,语法分析二、代码:options {JDK_VERSION = "1.5";}PARSER_BEGIN(eg1)public class eg1 {public static void main(String args[]) throws ParseException { eg1 parser = new eg1(System.in);parser.start();}}PARSER_END(eg1)SKIP :{" "| "\r"| "\t"| "\n"}TOKEN : /* OPERATORS */{< PLUS: "+" >| < MINUS: "-" >| < MULTIPLY: "*" >| < DIVIDE: "/" >}TOKEN :{<BIGGER:">"> |<SMALLER:"<"> |<NOTVOLUTION:"!="> |<SMALLEREQDD:"<="> |<BIGGEREE:">=" > |<DOUBLE:"==">TOKEN: //关键字{<MAIN:"main"> |<VOID:"void"> |<IF:"if"> |<INT:"int"> | <WHILE:"while"> |<CHAR:"char"> | <VOLUTION:"="> }TOKEN : //定义整型数{< INTEGER: ["0" - "9"]( <DIGIT> )+ >| < #DIGIT: ["0" - "9"] >}TOKEN : //数字{<NUMBER:(<DIGIT>)+ | (<DIGIT>)+"."| (<DIGIT>)+"."(<DIGIT>)+| "."(<DIGIT>)+>}TOKEN : //标记{<COMMA:","> | <SEMICOLON:";"> | <COLON:":"> | <LEFTPARENTHESES:"("> |<RIGHTPARENTHESES:")"> | <LEFTBRACE:"{"> | <RIGHTBRACE:"}"> }TOKEN : //标识符{<IDENTIFIER:<LETTER> |<LETTER>(<LETTER> | <DIGIT> )* >|<#LETTER:["a"-"z", "A"-"Z"]>}void start():{}{<MAIN> <LEFTPARENTHESES> <RIGHTPARENTHESES> block() }void block():{}{<LEFTBRACE> string() <RIGHTBRACE>}void string():{}{yuju() (string())?}void yuju():{}{fuzhiyuju() | tiaojianyuju() | xunhuanyuju()}void fuzhiyuju():{}{<IDENTIFIER> <VOLUTION> biaodashi() <SEMICOLON>}void tiaojianyuju():{}{<IF> tiaojian() block()}void xunhuanyuju():{}<WHILE> tiaojian() block()}void tiaojian():{}{<LEFTPARENTHESES> biaodashi() guanxifu() biaodashi()<RIGHTPARENTHESES>}void biaodashi():{}{( <LEFTPARENTHESES> biaodashi() <RIGHTPARENTHESES> biaodashi2()) |(<IDENTIFIER> biaodashi2() ) | ( <NUMBER> biaodashi2() )}void biaodashi2():{}{(yunsuanfu() biaodashi() biaodashi2() )?}void yunsuanfu():{}{< PLUS > | < MINUS > |< MULTIPLY> | < DIVIDE >}void guanxifu() :{}{<BIGGER> | <SMALLER> | <NOTVOLUTION><SMALLEREQDD> | <BIGGEREE> | <DOUBLE>}三、实验/实习总结本次实习,我使用javacc完成了包括词法分析,语法分析(输出语法树),能够读文件的功能,总的来说比较满意,通过本次实习掌握了javacc基本的使用。

天津理工大学编译原理实验2语法分析

天津理工大学编译原理实验2语法分析

天津理工大学编译原理实验2语法分析实验报告学院(系)名称:计算机与通信工程学院姓名学号专业班级实验项目实验二:语法分析课程名称编译原理课程代码2016年4月21日第1、2节实验时间 2016年4月26日第3、4节实验地点计算机软件实验室7-220 2016年4月28日第1、2节批改意见成绩教师签字: 实验内容:可选择LL1分析法、算符优先分析法、LR分析法之一,实现如下表达式文法的语法分析器:(1)E?E+T | E-T | T(2)T?T*F | T/F | F(3)F?P^F | P(4)P?(E) | i实验目的:1(掌握语法分析的基本概念和基本方法;2(正确理解LL1分析法、算符优先分析法、LR分析法的设计与使用方法。

实验要求:1(按要求设计实现能识别上述文法所表示语言的语法分析器,并要求输出全部分析过程;2(要求详细描述所选分析方法针对上述文法的分析表构造过程;3(完成对所设计语法分析器的功能测试,并给出测试数据和实验结果;4(为增加程序可读性,请在程序中进行适当注释说明;5(整理上机步骤,总结经验和体会;6(认真完成并按时提交实验报告。

第1页共13页【实验过程记录(源程序、测试用例、测试结果及心得体会等)】使用的是LL(1)分析法,其分析表的构造方法和构造过程如下: 实验源代码: #include<iostream>#include<cstring>#define size 1024using namespace std;int getLength(char str[size]) {int i=0;while(str[i]!='\0')i++;return i;}int getstringLength(string str) {int i=0;while(str[i]!='\0')i++;return i;}char gettop(char stack[size],int top) {if(stack[top]!='\0')return stack[top];elsereturn '#';}void popstack(char *stack,int *pointer){int p=*pointer;cout<<"\tPopup "<<stack[p]<<" out!";stack[p]='\0';(*pointer)--;}void pushstack(char *stack,int *pointer,string str) {int i=0;int length=getstringLength(str);cout<<" push "<<str<<" in stack reversed order."; for(i=length-1;i>=0;i--){(*pointer)++;第2页共13页stack[(*pointer)]=str[i];}}int getcol(char top) {switch(top){case '+':return 0;case '-':return 1;case '*':return 2;case '/':return 3;case '^':return 4;case ')':return 5;case '#':return 6;case '(':return 7;case 'i':return 8;default:cout<<"Error! This character string is not this grammer`s sentence."<<endl;return -1;}}void show(char str[size],int index){int length=getLength(str);if(index!=-1)cout<<"\t";for(int i=index+1;i<length;i++)cout<<str[i]; }int main(){char str[size];//接受字符串的数组char stack[size];//进行比对的栈int pointer=-1;//指向栈顶的指针int length=0;//记录字符串长度int index=0;//记录输入字符串第3页共13页char top;int i,j;//i表示行,j表示列string production;bool match=false;string table[7][9]={ // + - * / ^ ) # ( i/* E */ "error", "error", "error", "error", "error", "error", "error", "TX", "TX",/* X */ "+TX", "-TX", "error", "error", "error", "empty", "empty", "error", "error",/* T */ "error","error","error","error","error","error","error","FY","FY", /* Y */"empty","empty","*FY","/FY","error","empty","empty","error","error", /* F */ "error","error","error","error","error","error","error","PZ","PZ", /* Z */"empty","empty","empty","empty","^F","empty","empty","error","error", /* P */ "error","error","error","error","error","error","error","(E)","i"};cout<<"Please input character string: ";cin>>str;length=getLength(str);str[length]='#';str[length+1]='\0';// cout<<length<<endl;// cout<<table[0][0]; //已验证可以实现cout<<"符号栈\t当前符号\t输入串\t\t\t\t说明"<<endl;pointer++;stack[pointer]='#';pointer++;stack[pointer]='E';//初始化栈,使栈底是 #Ewhile(str[index]!='\0'){top=gettop(stack,pointer);switch(top){case 'E':i=0;//第1行j=getcol(str[index]);production=table[i][j];if(production=="error"){cout<<"Error! This character string is not this grammer`s sentence."<<endl;return 0;}else if(production=="empty"){cout<<"\n";show(stack,-1);cout<<"\t"<<str[index]<<"\t";show(str,index);popstack(stack,&pointer);第4页共13页}else //说明可以进行分解非终结符{cout<<"\n";show(stack,-1);cout<<"\t"<<str[index]<<"\t";show(str,index);popstack(stack,&pointer);pushstack(stack,&pointer,production);}break;case 'X':i=1;//第2行j=getcol(str[index]);production=table[i][j];if(production=="error"){cout<<"Error! This character string is not this grammer`s sentence."<<endl;return 0;}else if(production=="empty"){cout<<"\n";show(stack,-1);cout<<"\t"<<str[index]<<"\t";show(str,index);popstack(stack,&pointer);}else //说明可以进行分解非终结符{cout<<"\n";show(stack,-1);cout<<"\t"<<str[index]<<"\t";show(str,index);popstack(stack,&pointer);pushstack(stack,&pointer,production); }break;case 'T':i=2;//第3行j=getcol(str[index]);production=table[i][j];if(production=="error"){cout<<"Error! This character string is not this grammer`s sentence."<<endl;第5页共13页return 0;}else if(production=="empty"){cout<<"\n";show(stack,-1);cout<<"\t"<<str[index]<<"\t";show(str,index);popstack(stack,&pointer);}else //说明可以进行分解非终结符{cout<<"\n";show(stack,-1);cout<<"\t"<<str[index]<<"\t";show(str,index);popstack(stack,&pointer);pushstack(stack,&pointer,production);}break;case 'Y':i=3;//第4行j=getcol(str[index]);production=table[i][j];if(production=="error"){cout<<"Error! This character string is not this grammer`s sentence."<<endl;return 0;}else if(production=="empty"){cout<<"\n";show(stack,-1);cout<<"\t"<<str[index]<<"\t";show(str,index);popstack(stack,&pointer);}else //说明可以进行分解非终结符{cout<<"\n";show(stack,-1);cout<<"\t"<<str[index]<<"\t";show(str,index);popstack(stack,&pointer);pushstack(stack,&pointer,production);第6页共13页}break;case 'F':i=4;//第5行j=getcol(str[index]);production=table[i][j];if(production=="error"){cout<<"Error! This character string is not this grammer`s sentence."<<endl;return 0;}else if(production=="empty"){cout<<"\n";show(stack,-1);cout<<"\t"<<str[index]<<"\t";show(str,index);popstack(stack,&pointer);}else //说明可以进行分解非终结符{cout<<"\n";show(stack,-1);cout<<"\t"<<str[index]<<"\t";show(str,index);popstack(stack,&pointer);pushstack(stack,&pointer,production);}break;case 'Z':i=5;//第6行j=getcol(str[index]);production=table[i][j];if(production=="error"){cout<<"Error! This character string is not this grammer`s sentence."<<endl;return 0;}else if(production=="empty"){cout<<"\n";show(stack,-1);cout<<"\t"<<str[index]<<"\t";show(str,index);popstack(stack,&pointer);第7页共13页}else //说明可以进行分解非终结符{cout<<"\n";show(stack,-1);cout<<"\t"<<str[index]<<"\t";show(str,index);popstack(stack,&pointer);pushstack(stack,&pointer,production);}break;case 'P':i=6;//第7行j=getcol(str[index]);production=table[i][j];if(production=="error"){cout<<"Error! This character string is not this grammer`s sentence."<<endl;return 0;}else if(production=="empty"){cout<<"\n";show(stack,-1);cout<<"\t"<<str[index]<<"\t";show(str,index);popstack(stack,&pointer);}else //说明可以进行分解非终结符{cout<<"\n";show(stack,-1);cout<<"\t"<<str[index]<<"\t";show(str,index);popstack(stack,&pointer);pushstack(stack,&pointer,production); }break;case '+':switch(str[index]){case '+':cout<<"\n";show(stack,-1);cout<<"\t"<<str[index]<<"\t";第8页共13页show(str,index);cout<<"\tMatch + ! ";//" Popup + and next char in."<<endl;popstack(stack,&pointer);match=true;break;default:cout<<"Error! This character string is not this grammer`s sentence."<<endl;return 0;}break;case '-':switch(str[index]){case '-':cout<<"\n";show(stack,-1);cout<<"\t"<<str[index]<<"\t";show(str,index);cout<<"\tMatch - ! ";//Popup - and next char in."<<endl;popstack(stack,&pointer);match=true;break;default:cout<<"Error! This character string is not this grammer`s sentence."<<endl;return 0;}break;case '*':switch(str[index]){case '*':cout<<"\n";show(stack,-1);cout<<"\t"<<str[index]<<"\t";show(str,index);cout<<"\tMatch * ! ";//Popup * and next char in."<<endl;popstack(stack,&pointer);match=true;break;default:cout<<"Error! This character string is not this grammer`s sentence."<<endl;return 0;}break;case '/':第9页共13页switch(str[index]){case '/':cout<<"\n";show(stack,-1);cout<<"\t"<<str[index]<<"\t";show(str,index);cout<<"\tMatch / ! ";//Popup / and next char in."<<endl;popstack(stack,&pointer);match=true;break;default:cout<<"Error! This character string is not this grammer`s sentence."<<endl;return 0;}break;case '(':switch(str[index]){case '(':cout<<"\n";show(stack,-1);cout<<"\t"<<str[index]<<"\t";show(str,index);cout<<"\tMatch ( ! ";//Popup ( and next char in."<<endl;popstack(stack,&pointer);match=true;break;default:cout<<"Error! This character string is not this grammer`s sentence."<<endl;return 0;}break;case ')':switch(str[index]){case ')':cout<<"\n";show(stack,-1);cout<<"\t"<<str[index]<<"\t";show(str,index);cout<<"\tMatch ) ! ";//Popup ) and next char in."<<endl;popstack(stack,&pointer);match=true;break;第10页共13页default:cout<<"Error! This character string is not this grammer`s sentence."<<endl;return 0;}break;case '^':switch(str[index]){case '^':cout<<"\n";show(stack,-1);cout<<"\t"<<str[index]<<"\t";show(str,index);cout<<"\tMatch ^ ! ";//Popup ^ and next char in."<<endl;popstack(stack,&pointer);match=true;break;default:cout<<"Error! This character string is not this grammer`s sentence."<<endl;return 0;}break;case 'i':switch(str[index]){case 'i':cout<<"\n";show(stack,-1);cout<<"\t"<<str[index]<<"\t";show(str,index);cout<<"\tMatch i ! ";//Popup i and next char in."<<endl;popstack(stack,&pointer);match=true;break;default:cout<<"Error! This character string is not this grammer`s sentence."<<endl;return 0;}break;case '#':switch(str[index]){case '#':cout<<"\n";show(stack,-1);第11页共13页cout<<"\t"<<str[index]<<"\t";show(str,index);cout<<"\tMatch # ! 分析成功~";//Popup # and next char in."<<endl;return 0;default:cout<<"Error! This character string is not this grammer`s sentence."<<endl;return 0;}break;}if(match){index++;match=false;}}return 0;}实验代码测试结果:下面图片是以给定文法画出的一个语法树。

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

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

实验 2:语法分析
1.实验题目和要求
题目:语法分析程序的设计与实现。

实验内容:编写语法分析程序,实现对算术表达式的语法分析。

要求所分析算术表达式由如下的文法产生。

E E T|E T|T
T T*F|T/F|F F id
| (E) | num
实验要求:在对输入表达式进行分析的过程中,输出所采用的产生式。

方法 1 :编写递归调用程序实现自顶向下的分析。

方法 2 :编写 LL(1) 语法分析程序,要求如下。

(1)编程实现算法 4.2 ,为给定文法自动构造预测分析表。

(2)编程实现算法 4.1 ,构造 LL(1) 预测分析程序。

方法 3 :编写语法分析程序实现自底向上的分析,要求如下。

(1)构造识别所有活前缀的 DFA 。

(2)构造 LR 分析表。

(3)编程实现算法 4.3 ,构造 LR 分析程序。

方法 4 :利用 YACC 自动生成语法分析程序,调用LEX 自动生成的词法分析程序。

实现(采用方法1)1.1. 步骤:
1)对文法消除左递归
E TE '
E 'TE' | TE' |
T FT '
T '*FT'|/FT' |
F id | (E) | num
2)画出状态转换图
化简得:
3)源程序
在程序中I 表示 id
N 表示 num
1.2. 例子:
a)例子 1
输入 :I+(N*N)
输出:
b)例子 2
输入: I-NN
输出:。

编译原理实验二LL文法分析

编译原理实验二LL文法分析

实验2 LL(1)分析法一、实验目的通过完成预测分析法的语法分析程序,了解预测分析法和递归子程序法的区别和联系。

使学生了解语法分析的功能,掌握语法分析程序设计的原理和构造方法,训练学生掌握开发应用程序的基本方法。

有利于提高学生的专业素质,为培养适应社会多方面需要的能力。

二、实验要求1、编程时注意编程风格:空行的使用、注释的使用、缩进的使用等。

2、如果遇到错误的表达式,应输出错误提示信息。

3、对下列文法,用LL(1)分析法对任意输入的符号串进行分析:(1)E->TG(2)G->+TG|—TG(3)G->ε(4)T->FS(5)S->*FS|/FS(6)S->ε(7)F->(E)(8)F->i三、实验内容根据某一文法编制调试LL ( 1 )分析程序,以便对任意输入的符号串进行分析。

构造预测分析表,并利用分析表和一个栈来实现对上述程序设计语言的分析程序。

分析法的功能是利用LL(1)控制程序根据显示栈栈顶内容、向前看符号以及LL(1)分析表,对输入符号串自上而下的分析过程。

四、实验步骤1、根据流程图编写出各个模块的源程序代码上机调试。

2、编制好源程序后,设计若干用例对系统进行全面的上机测试,并通过所设计的LL(1)分析程序;直至能够得到完全满意的结果。

3、书写实验报告;实验报告正文的内容:写出LL(1)分析法的思想及写出符合LL(1)分析法的文法。

程序结构描述:函数调用格式、参数含义、返回值描述、函数功能;函数之间的调用关系图。

详细的算法描述(程序执行流程图)。

给出软件的测试方法和测试结果。

实验总结(设计的特点、不足、收获与体会)。

五、实验截图六、核心代码#include<iostream>#include<stdio.h>#include<stdlib.h>#include<string.h>#define MAX 20using namespace std;char A[MAX];char B[MAX];char v1[MAX] = { 'i','+','-','*','/','(',')','#'}; char v2[MAX] = {'E','G','T','S','F'};int j = 0, b = 0, top = 0;int l; //l是字符串长度class type{public:char origin;char array[7];int length;};type e, t, g,g0, g1, s, s0,s1, f, f1;type C[10][10];void print(){int a;for ( a = 0; a <= top + 1; a++)cout<<A[a];cout << "\t\t";}void print1(){int j;for (j = 0; j<b; j++)cout << " ";for (j = b; j <= l; j++)cout << B[j];cout << "\t\t\t";}int main(){int m, n, k = 0;int flag = 0,finish = 0;char ch, x;type cha;e.origin = 'E';strcpy(e.array, "TG");e.length = 2;t.origin = 'T';strcpy(t.array, "FS");t.length = 2;g.origin = 'G';strcpy(g.array, "+TG");g.length = 3;g0.origin = 'G';strcpy(g0.array, "-TG");g0.length = 3;g1.origin = 'G';g1.array[0] = '^';g1.length = 1;s.origin = 'S';strcpy(s.array, "*FS");s.length = 3;s0.origin = 'S';strcpy(s0.array, "/FS");s0.length = 3;s1.origin = 'S';s1.array[0] = '^';s1.length = 1;f.origin = 'F';strcpy(f.array, "(E)");f.length = 3;f1.origin = 'F';f1.array[0] = 'i';f1.length = 1;for (m = 0; m <= 4;m++)for (n = 0; n <= 7; n++)C[m][n].origin = 'N';/*C[0][0] = e; C[0][3] = e; C[1][2] = g0;C[1][1] = g; C[1][4] = g1; C[1][5] = g1;C[2][0] = t; C[2][3] = t;C[3][1] = s1; C[3][2] = s;C[3][4] = C[3][5] = s1;C[4][0] = f1; C[4][3] = f;*/C[0][0] = e; C[0][5] = e;C[1][1] = g; C[1][2] = g0;C[1][6] = g1; C[1][7] = g1;C[2][0] = t; C[2][5] = t;C[3][1] = s1; C[3][2] = s1;C[3][3] = s;C[3][4] = s0; C[3][6] = s1; C[3][7] = s1;C[4][0] = f1; C[4][5] = f;cout << "input,please~:";do{cin >> ch;if ((ch!='i') &&(ch!='+') &&(ch!='-') &&(ch!='*') &&(ch!='/') &&(ch!='(') &&(ch!=')') &&(ch!='#')){cout << "Error!\n";exit(1);}B[j] = ch;j++;} while (ch != '#');l = j; //l是字符串长度/* for(j=0;j<l;j++)cout<<B[j]<<endl;*/ch = B[0]; //当前分析字符A[top] = '#';A[++top] = 'E';/*'#','E'进栈*/cout << "步骤\t\t分析栈\t\t剩余字符\t\t所用字符\n"; do{x = A[top--];cout << k++;cout << "\t\t";for (j = 0; j<=7 ; j++)if (x == v1[j]){flag = 1;break;}if (flag==1){if (x == '#'){finish = 1;cout << "acc!\n";getchar();getchar();exit(1);}if (x == ch){print();print1();cout <<ch << "匹配\n";ch = B[++b];flag = 0;}else{cout<<"x:"<<x<<endl;cout<<"ch:"<<ch<<endl;print();print1();cout <<ch<< "出错\n" ;exit(1);}}else //非终结符{for (j = 0; j <= 4; j++)if (x == v2[j]){m = j;//行号break;}for (j = 0; j <= 7; j++)if (ch == v1[j]){n = j; //列号break;}cha = C[m][n];if (cha.origin != 'N'){print();print1();cout << cha.origin << "->";for (j = 0; j<cha.length; j++)cout << cha.array[j];cout << "\n";for (j = (cha.length - 1); j >= 0; j--)A[++top] = cha.array[j];if (A[top] == '^')/*为空则不进栈*/top--;}else{print();print1();cout<<"x:"<<x<<endl;cout<<"ch:"<<ch<<endl;cout<<"sign1"<<endl;cout << "Error!" << x;exit(1);}}} while (finish == 0);}。

编译原理_实验报告实验二__语法分析(算符优先) 2

编译原理_实验报告实验二__语法分析(算符优先) 2

华北水利水电学院编译原理实验报告一、实验题目:语法分析(算符优先分析程序)(1)选择最有代表性的语法分析方法算符优先法;(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<stdlib.h>#include<stdio.h>#include<string.h>#include<iostream.h>#define SIZE 128char priority[6][6]; //算符优先关系表数组char input[SIZE]; //存放输入的要进行分析的句子char remain[SIZE]; //存放剩余串char AnalyseStack[SIZE]; //分析栈void analyse();int testchar(char x); //判断字符X在算符优先关系表中的位置void remainString(); //移进时处理剩余字符串,即去掉剩余字符串第一个字符int k;void init()//构造算符优先关系表,并将其存入数组中{priority[0][2]='<';priority[0][3]='<';priority[0][4]='>';priority[0][5]='>';priority[1][0]='>';priority[1][1]='>';priority[1][2]='<';priority[1][3]='<';priority[1][4]='>';priority[1][5]='>';priority[2][0]='>';priority[2][1]='>';priority[2][2]='$';//无优先关系的用$表示priority[2][3]='$';priority[2][4]='>';priority[2][5]='>';priority[3][0]='<';priority[3][1]='<';priority[3][2]='<';priority[3][3]='<';priority[3][4]='=';priority[3][5]='$';priority[4][0]='>';priority[4][1]='>';priority[4][2]='$';priority[4][3]='$';priority[4][4]='>';priority[4][5]='>';priority[5][0]='<';priority[5][3]='<';priority[5][4]='$';priority[5][5]='=';}void analyse()//对所输入的句子进行算符优先分析过程的函数{FILE *fp;fp=fopen("li","a");int i,j,f,z,z1,n,n1,z2,n2;int count=0;//操作的步骤数char a; //用于存放正在分析的字符char p,Q,p1,p2;f=strlen(input); //测出数组的长度for(i=0;i<=f;i++){a=input[i];if(i==0)remainString();if(AnalyseStack[k]=='+'||AnalyseStack[k]=='*'||AnalyseStack[k]=='i'||Analy seStack[k]=='('||AnalyseStack[k]==')'||AnalyseStack[k]=='#')j=k;elsej=k-1;z=testchar(AnalyseStack[j]);//从优先关系表中查出s[j]和a的优先关系if(a=='+'||a=='*'||a=='i'||a=='('||a==')'||a=='#')n=testchar(a);else //如果句子含有不是终结符集合里的其它字符,不合法{printf("错误!该句子不是该文法的合法句子!\n");break;}if(p=='$'){printf("错误!该句子不是该文法的合法句子!\n");return;}if(p=='>'){ for( ; ; ){Q=AnalyseStack[j];if(AnalyseStack[j-1]=='+'||AnalyseStack[j-1]=='*'||AnalyseStack[j-1]=='i'||AnalyseStack[j-1]=='('||AnalyseStack[j-1]==')'||AnalyseStack[j-1]=='#')j=j-1;elsej=j-2;z1=testchar(AnalyseStack[j]);n1=testchar(Q);p1=priority[z1][n1];if(p1=='<') //把AnalyseStack[j+1]~AnalyseStack[k]归约为N{count++;printf("(%d) %s\t%10c\t%5c%17s\t 归约\n",count,AnalyseStack,p,a,remain);fprintf(fp,"(%d) %s\t%17s\t %s\n",count,AnalyseStack,remain,"归约");k=j+1;i--;AnalyseStack[k]='N';int r,r1;r=strlen(AnalyseStack);for(r1=k+1;r1<r;r1++)AnalyseStack[r1]='\0';break;}else}}else{if(p=='<') //表示移进{count++;printf("(%d) %s\t%10c\t%5c%17s\t 移进\n",count,AnalyseStack,p,a,remain);fprintf(fp,"(%d) %s\t%17s\t %s\n",count,AnalyseStack,remain,"移进");k=k+1;AnalyseStack[k]=a;remainString();}else{if(p=='='){z2=testchar(AnalyseStack[j]);n2=testchar('#');p2=priority[z2][n2];if(p2=='='){count++;printf("(%d) %s\t%10c\t%5c%17s\t 接受\n",count,AnalyseStack,p,a,remain);fprintf(fp,"(%d) %s\t%17s\t %s\n",count,AnalyseStack,remain,"接受");printf("该句子是该文法的合法句子。

编译原理实验 词法分析&语法分析程序

编译原理实验 词法分析&语法分析程序

编译原理实验词法分析程序实验一:词法分析程序1、实验目的从左至右逐个字符的对源程序进行扫描,产生一个个单词符号,把字符串形式的源程序改造成单词符号形式的中间程序。

2、实验内容表C语言子集的单词符号及内码值单词符号种别编码助记符内码值while 1 while --if 2 if --else 3 else --switch 4 switch --case 5 case --标识符 6 id id在符号表中的位置常数7 num num在常数表中的位置+ 8 + --- 9 - --* 10 * --<= 11 relop LE< 11 relop LT== 11 relop LQ= 12 = --; 13 ; --输入源程序如下if a==1 a=a+1;else a=a+2;输出对应的单词符号形式的中间程序3、实验过程实验上机程序如下:#include "stdio.h"#include "string.h"int i,j,k;char s ,a[20],token[20];int letter(){if((s>=97)&&(s<=122))return 1;else return 0;}int Digit(){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(){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 you source program,end('#'):\n");i=0;do{i=i+1;scanf("%c",&a[i]);}while(a[i]!='#');i=1;memset(token,0,sizeof(char)*10);j=0;get();while(s!='#'){if(s==' '||s==10||s==13)get();else{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'p':case'q':case'r':case's':case't':case'u':case'v':case'w':case'x':case'y':case'z':while(Digit()||letter()){token[j]=s;j=j+1;get();}retract();k=lookup();if(k==0)printf("(6,%s)\n",token); elseprintf("(%d,null)\n",k); break;case'0':case'1':case'2':case'3':case'4':case'5':case'6':case'7':case'8':case'9':while(Digit()){token[j]=s;j=j+1;get();}retract();printf("(%d,%s)\n",7,token); break;case'+':printf("(+,null)\n"); break;case'-':printf("(-,null)\n"); break;case'*':printf("(*,null)\n"); break;case'<':get();if(s=='=')printf("(relop,LE)\n"); else{retract();printf("(relop,LT)\n");}break;case'=':get();if(s=='=')printf("(relop,EQ)\n"); else{retract();printf("(=,null)\n");}break;case';':printf("(;,null)\n"); break;default:printf("(%c,error)\n",s);break;}memset(token,0,sizeof(char)*10);j=0;get();}}}4、实验结果实验结果分析:if是关键字,对应种别编码为2,输出(2,null)a是标识符,对应种别编码为6,值为a,输出(6,a)==的助记符是relop,内码值为LE,输出(relop,LE)1是常数,对应种别编码为7,值为1,输出(7,1)a是标识符,对应种别编码为6,值为a,输出(6,a)=是赋值符号,直接输出,(=,null)a是标识符,对应种别编码为6,值为a,输出(6,a)+是运算符,直接输出(=,null)1是常数,对应种别编码为7,值为1,输出(7,1);是语句结束符号,直接输出(;,null)else是关键字,对应种别编码为3,输出(3,null)a是标识符,对应种别编码为6,值为a,输出(6,a)=是赋值符号,直接输出,(=,null)a是标识符,对应种别编码为6,值为a,输出(6,a)+是运算符,直接输出(=,null)2是常数,对应种别编码为7,值为2,输出(7,2);是语句结束符号,直接输出(;,null)#是输入结束标志编译原理实验语法分析程序实验二:语法分析程序1、实验目的:将单词组成各类语法单位,讨论给类语法的形成规则,判断源程序是否符合语法规则3、实验内容:给定文法:G[E]:E→E+E|E-E|E*E|E/E|(E)E→0|1|2|3|4|5|6|7|8|9首先把G[E]构造为算符优先文法,即:G’[E]:E→E+T|TT→T-F|FF→F*G|GG→G/H|HH→(E)|i得到优先关系表如下:+ - * / i ( ) # + ·><·<·<·<·<··>·> - ·>·><·<·<·<··>·> * ·>·>·><·<·<··>·> / ·>·>·>·><·<··>·>i ·>·>·>·>·>·>( <·<·<·<·<·<·=) ·>·>·>·>·>·> # <·<·<·<·<·<·=构造出优先函数+ - * / i ( ) #f 6 8 10 12 12 2 12 2g 5 7 9 11 13 13 2 2要求输入算术表达式:(1+2)*3+2*(1+2)-4/2输出其对应的语法分析结果4、实验过程:上机程序如下:#include "stdio.h"#include "string.h"char a[20],optr[10],s,op;int i,j,k,opnd[10],x1,x2,x3;int operand(char s){if((s>=48)&&(s<=57))return 1;else return 0;}int f(char s){switch(s){case'+':return 6;case'-':return 8;case'*':return 10;case'/':return 12;case'(':return 2;case')':return 12;case'#':return 2;default:printf("error");}}int g(char s){switch(s){case'+':return 5;case'-':return 7;case'*':return 9;case'/':return 11;case'(':return 13;case')':return 2;case'#':return 2;default:printf("error");}}void get(){s=a[i];i=i+1;}void main(){printf("请输入算数表达式,并以‘#’结束:\n");i=0;do{scanf("%c",&a[i]);i++;}while(a[i-1]!='#');i=0;j=0;k=0;optr[j]='#';get();while((optr[j]!='#')||(s!='#')){if(operand(s)){opnd[k]=s-48;k=k+1;get();}else if(f(optr[j])<g(s)){j=j+1;optr[j]=s;get();}else if(f(optr[j])==g(s)){if(optr[j]=='('&&s==')'){j=j-1;get();}else if(optr[j]=='('&&s=='#'){printf("error\n");break;}else if(optr[j]=='#'&&s==')'){printf("error\n");break;}}else if(f(optr[j])>g(s)){op=optr[j];j=j-1;x2=opnd[k-1];x1=opnd[k-2];k=k-2;switch(op){case'+':x3=x1+x2;break;case'-':x3=x1-x2;break;case'*':x3=x1*x2;break;case'/':x3=x1/x2;break;}opnd[k]=x3;k=k+1;printf("(%c,%d,%d,%d)\n",op,x1,x2,x3);}else{printf("error\n");break;}}if(j!=0||k!=1)printf("error\n");}5、实验结果:实验结果分析:(1+2)*3+2*(1+2)-4/2#因为‘)’优先级大于‘*’,先计算1+2=3,并输出(+,1,2,3)原式变为:3*3+2*(1+2)-4/2#因为‘*’优先级大于‘+’,先计算3*3=9,并输出(*,3,3,9)原式变为:9+2*(1+2)-4/2#因为‘)’优先级大于‘-’,先计算1+2=3,并输出(+,1,2,3)原式变为:9+2*3-4/2#因为‘*’优先级大于‘-’,先计算2*3=6,并输出(*,2,3,6)原式变为:9+6-4/2#因为‘/’优先级大于‘#’,先计算4/2=2,并输出(/,4,2,2)原式变为:9+6-2#因为‘-’优先级大于‘#’,先计算6-2=4,并输出(-,6,2,4)原式变为:9+4#因为‘+’优先级大于‘#’,计算9+4=13,并输出(+,9,4,13)原式变为13#优先级等于#,跳出while循环,运算结束!。

编译原理实验二 语法分析

编译原理实验二   语法分析
{wordindex++;
factor();}
}
factor()
{switch(token[wordindex]){
case LPAREN :
wordindex++;
exp();
if(token[wordindex]==RPAREN)
wordindex++;
else {printf("error");
{if(token[wordindex]==ID)
wordindex++;
else {printf("error");
exit(1);}
if(token[wordindex]==ASSIGN)
wordindex++;
else {printf("error");
exit(1);}
exp();
}
exp()
typedef enum {ifk,assignk,declk} stmtkind;
typedef enum {opk,constk,idk} expkind;
typedef struct treenode
{ struct treenode * child[3];
struct treenode * sibling;
stmt_seqid := exp
expexp + term | exp–term | term
termterm * factor | term / factor | factor
factor( exp ) | id | num
语法树的数据结构:
typedef enum {stmtk,expk} nodekind;

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

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

实验二语法分析实验报告一、实验内容1.1 实验目的编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析.1.2 实验要求利用C语言编制递归下降分析程序,并对简单语言进行语法分析1.2.1待分析的简单语言的词法用扩充的BNF表示如下:(1) <程序>::={<声明序列><语句序列>}(2)<语句串>::=<语句>{;<语句>}(3) <语句>::=<赋值语句>(4) <赋值语句>::=ID:= <表达式>(5) <表达式>::=<项>{(+<项>|-<项>}(6) <项>::=<因子>{*<因子>|/<因子>}(7) <因子>::=ID|NUM|(<算术表达式>)1.2.2实验要求说明输入单词串,以“#”结束,如果是文法正确的句子,则输出成功信息,打印“success”,否则输出“error”。

二、实验程序的总体结构框架图1. 语法分析主程序示意图图2.递归下降分析程序示意图图5. expression表达式分析函数示意图图6.term分析函数示意图三、关键技术的实现方法Scanner函数定义已在实验一给出,本实验不再重复给出void Irparser(){kk=0;if(syn==1){scaner();yucu();if(syn==6){scaner();if(syn==0 && (kk==0)) cout<<"success!"<<endl;}else{if(kk!=1)cout<<"缺end!"<<endl;kk=1;}}else {cout<<"缺begin!"<<endl;kk=1;}return;}void yucu(){statement();while(syn==26){scaner();statement();}return;}void statement() {if(syn==10){scaner();if(syn==18){scaner();expression();}else{cout<<"赋值号错误"<<endl;kk=1;}}else{cout<<"语句错误"<<endl;kk=1;}return;}void expression(){term();while((syn==13)||(syn==14)){scaner();term();}return;}void term(){factor();while((syn==15)||(syn==16)){scaner();factor();}return;}void factor(){if((syn==10)||(syn==11))scaner();else if(syn==27){scaner();expression();if(syn==28)scaner();else{cout<<")错误"<<endl;kk=1;}}else{cout<<"表达式错误"<<endl;kk=1;}return;}void main(){p=0;cout<<"Please input string"<<endl;do{cin.get(ch);if(ch!=”\n”)prog[p++]=ch;}while(ch!='#');p=0;scaner();Irparser();}四、实验心得语法分析是编译过程的核心部分,它的主要功能是按照程序语言的语法规则,从由词法分析输出的源程序符号串中识别出各类语法成分,同时进行语法检查,为语义分析和代码生成做准备。

编译原理实验报告二

编译原理实验报告二

深圳大学实验报告课程名称:编译原理实验项目名称:语法分析--递归下降法学院:计算机与软件专业:软件工程指导教师:张小建报告人:文成学号:2011150259 班级: 2 实验时间:2013-12-25实验报告提交时间:2013-12-26教务部制一、实验目的:掌握自顶向下的语法分析法——递归下降法。

二、实验内容:用递归下降法对如下所定义的逻辑表达式进行语法分析。

1 L→ L || A2 L→ A3 A→ A && R4 A→ R5 R→ [ L ]6 R→ ! L7 R→ E >= E8 R→ E > E9 R→ E <= E10 R→ E < E11 R→ E == E12 R→ E != E13 R→ E14 E→ E + T15 E→ T16 T→ T * F17 T→ F18 F→ ( E )19 F→ n // 数20 F→ i // 标识符三、实验设计:1、消除该文法的左递归(产生式1、3、14、16);产生式(1)L→ L || A (2)L→ A消除左递归得到:L→ A L' L'→ || A L' | з产生式(3)A→ A && R (4)A→ R消除左递归得到:A→ RA' A'→ && RA' | з产生式(14)E→ E + T (15)E→ T消除左递归得到:E→ TE' E'→ + TE' | з产生式(16)T→ T * F (17)T→ F消除左递归得到:T→ FT' T'→ *FT' | з2、通过抽取公共左因子(产生式7 ~ 12),对该文法进行LL(1)改造;产生式7~127 R→ E >= E8 R→ E > E9 R→ E <= E10 R→ E < E11 R→ E == E12 R→ E != E抽取公共左因子:R→ ER'R'→ >=E | >E | <=E | <E | ==E | !=E3、证明最终得到的文法为LL(1)文法。

编译原理Lab2

编译原理Lab2

编译原理实验报告实验名称:语法分析器设计与实现实验日期: 2016.1.13学生姓名:学生学号:一、实验目的加深对语法分析器的工作过程的理解;加强对语法分析方法的掌握;能够采用一种编程语言实现简单的语法分析程序;能够使用自己编写的分析程序对简单的程序段进行语法分析。

通过本实验,应达到以下目标:1.掌握从源程序文件中读取有效字符的方法和产生源程序的内部表示文件的方法。

2.掌握语法分析的实现方法。

3.上机调试编出的语法分析程序。

二、实验内容编写语法分析程序,利用实验一词法分析的结果,逐个读入经过词法分析生成的Token 序列。

根据定义好的句型,构造LR(1)分析表,根据该表对输入串进行规约,并输出规约序列。

语法分析是编译过程中的一个阶段,在词法分析后进行。

也可以和词法分析结合在一起进行,由语法分析程序调用词法分析程序来获得当前单词供语法分析使用。

输入:Token序列输出:规约序列三、实验方案1.程序的功能:从destination.txt文件读入Token序列,在syntax.txt文件中写入规约序列,格式为X->Y。

2.实现方案:采用LR(1)文法实现:a)定义上下文无关文法(CFG)b)根据CFG构造分层有限自动机c) 根据分层有限自动机构造LR(1)分析表c) 使用LR(1)分析表设计程序四、实验假设定义上下文无关文法如下:S’->SS->if S else SS->if SS->S;SS->EE->(E)E->E+TE->E-TE->TT->T*FT->T/FT->FF->idF->num五、相关的有限自动机根据上下文无关文法构造分层有限自动机(略)六、构造LR(1)分析表根据有限自动机构造LR(1)分析表如下:对于表中的冲突项:r2/S30冲突: 因为if的优先级高于;,所以应该将if S.;S左边的if S归约为S,故应保留r2。

编译原理-语法分析实验二

编译原理-语法分析实验二

华北水利水电学院编译原理实验报告2010~2011学年第二学期 xxxx 级计算机专业班级: xxxxx 学号: xxxxx 姓名: xxx一、实验目的通过设计、编制、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析方法。

二、实验要求⑴选择最有代表性的语法分析方法,如LL(1)分析法、算符优先法或LR分析法⑵选择对各种常见程序语言都用的语法结构,如赋值语句(尤指表达式)作为分析对象,并且与所选语法分析方法要比较贴切。

⑶实习时间为6小时。

三、实验内容选题1:使用预测分析法(LL(1)分析法)实现语法分析:(1)根据给定文法,先求出first集合、follow集合和select集合,构造预测分析表(要求预测分析表输出到屏幕或者输出到文件);(2)根据算法和预测分析表分析给定表达式是否是该文法识别的正确的算术表达式(要求输出归约过程)(3)给定表达式文法为:G(E): S→TEE→+TE | εT→FKK→*FK |εF→(S)|i(4)分析的句子为:(i+i)*i和i+i)*i四、程序源代码#include "stdafx.h"#include "SyntaxAnalysis.h"#include "SyntaxAnalysisDlg.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_ char THIS_FILE[] = __FILE__; #endif/////////////////////////////////////////// // CAboutDlg dialog used for App Aboutclass CAboutDlg : public CDialog{public:CAboutDlg();// Dialog Data//{{AFX_DATA(CAboutDlg)enum { IDD = IDD_ABOUTBOX };//}}AFX_DATA// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CAboutDlg)protected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support//}}AFX_VIRTUAL// Implementationprotected://{{AFX_MSG(CAboutDlg)//}}AFX_MSGDECLARE_MESSAGE_MAP()};CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD){//{{AFX_DATA_INIT(CAboutDlg)//}}AFX_DATA_INIT}voidCAboutDlg::DoDataExchange(CDataExchange* pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CAboutDlg)//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)//{{AFX_MSG_MAP(CAboutDlg)// No message handlers//}}AFX_MSG_MAPEND_MESSAGE_MAP()// CSyntaxAnalysisDlg dialogCSyntaxAnalysisDlg::CSyntaxAnalysisDlg(CWnd * pParent /*=NULL*/): CDialog(CSyntaxAnalysisDlg::IDD, pParent){//{{AFX_DATA_INIT(CSyntaxAnalysisDl g)m_strCode = _T("");m_strResult = _T("");//}}AFX_DATA_INIT// Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);}voidCSyntaxAnalysisDlg::DoDataExchange(CDataExc hange* pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CSyntaxAnalysisDlg)DDX_Control(pDX, IDC_LIST1, m_ListCtrl);DDX_Text(pDX, IDC_EDIT_Code, m_strCode);DDX_Text(pDX, IDC_EDIT_Result, m_strResult);//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CSyntaxAnalysisDlg, CDialog)//{{AFX_MSG_MAP(CSyntaxAnalysisDlg)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDC_BTN_Analysis, OnBTNAnalysis)//}}AFX_MSG_MAPEND_MESSAGE_MAP()// CSyntaxAnalysisDlg message handlersBOOL CSyntaxAnalysisDlg::OnInitDialog(){CDialog::OnInitDialog();ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX < 0xF000);CMenu* pSysMenu = GetSystemMenu(FALSE);if (pSysMenu != NULL){CString strAboutMenu;strAboutMenu.LoadString(IDS_ABOUTBO X);if (!strAboutMenu.IsEmpty()){pSysMenu->AppendMenu(MF_SEPARATOR);pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);}}SetIcon(m_hIcon, TRUE);// Set big iconSetIcon(m_hIcon, FALSE);// Set small icon// TODO: Add extra initialization here//初始化给定文法m_VN[0]="S";m_VN[1]="E";m_VN[2]="T";m_VN[3]="K";m_VN[4]="F";m_VT[0]="i";m_VT[1]="+";m_VT[2]="*";m_VT[3]="(";m_VT[4]=")";m_Gl[0]=0;m_Gr[0]="TE";m_Gl[1]=1;m_Gr[1]="+TE";m_Gl[2]=1;m_Gr[2]="ε";m_Gl[3]=2;m_Gr[3]="FK";m_Gl[4]=3;m_Gr[4]="*FK";m_Gl[5]=3;m_Gr[5]="ε";m_Gl[6]=4;m_Gr[6]="(S)";m_Gl[7]=4;m_Gr[7]="i";Cal_Symbol();Cal_First();Cal_Follow();DrawMList();return TRUE; // return TRUE unless you set the focus to a control}void CSyntaxAnalysisDlg::OnSysCommand(UINT nID, LPARAM lParam){if ((nID & 0xFFF0) == IDM_ABOUTBOX){CAboutDlg dlgAbout;dlgAbout.DoModal();}else{CDialog::OnSysCommand(nID, lParam);}} void CSyntaxAnalysisDlg::OnPaint(){if (IsIconic()){CPaintDC dc(this);SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);// Center icon in client rectangleint cxIcon = GetSystemMetrics(SM_CXICON);int cyIcon = GetSystemMetrics(SM_CYICON);CRect rect;GetClientRect(&rect);int x = (rect.Width() - cxIcon + 1) / 2;int y = (rect.Height() - cyIcon + 1) / 2;// Draw the icondc.DrawIcon(x, y, m_hIcon);}else{CDialog::OnPaint();}}CSyntaxAnalysisDlg::OnQueryDragIcon(){return (HCURSOR) m_hIcon;}void CSyntaxAnalysisDlg::Cal_Symbol() //求出能推出ε的非终结符{int i,j,k,nEnd;CString Gr[8];for (i=0;i<5;i++)m_nFlags[i]=0; //置初值,0表示否for (i=0;i<8;i++){Gr[i]=m_Gr[i];if (Gr[i]=="ε"){m_nFlags[m_Gl[i]]=1;//1表示是,即能推出ε}}do{nEnd=0;for (i=0;i<5;i++) //检查每一个非终结符{if (m_nFlags[i]==1) //如果该非终结符能推出ε,就将所有表达式右部删去该终结符{for(j=0;j<8;j++) //查找每一个表达式{if (Gr[j].IsEmpty()||Gr[j]=="ε") continue;for (k=0;k<Gr[j].GetLength();k++) //查找表达式右部的每一个字符{if (Gr[j].GetAt(k)==m_VN[i]) //找到该终结符{Gr[j]=Gr[j].Left(k)+Gr[j].Right(Gr[ j].GetLength()-k-1); //删去该终结符nEnd=1;break;}}if (Gr[j].IsEmpty()) m_nFlags[m_Gl[j]]=1; //如果右部为空,就在表中填是}}}} while(nEnd);}void CSyntaxAnalysisDlg::Cal_First() //求各非终结符的First集合{int i,j,k,nEnd,n;CString strFirst;for (i=0;i<5;i++){for (j=0;j<6;j++)m_First[i][j]=0;}for (i=0;i<8;i++){if (m_Gr[i].Left(2)=="ε"){m_First[m_Gl[i]][5]=1;continue;}strFirst=m_Gr[i].GetAt(0);for (j=0;j<5;j++){if(strFirst==m_VT[j]) //如果右部第一个字符是终结符{m_First[m_Gl[i]][j]=1;break;}}}do{nEnd=0;for (i=0;i<8;i++){n=0;strFirst=m_Gr[i].GetAt(0);do{for(j=0;j<5;j++){if (strFirst==m_VN[j]) //如果右部第一个字符是非终结符{for (k=0;k<6;k++){if(m_First[m_Gl[i]][k]!=m_First[j][k]){m_First[m_Gl[i]][k]=m_First[j][k];nEnd=1;}}if(m_First[j][5]==1&&n<m_Gr[i].GetLength()-1) //前一字符能推出ε,则下一字符的first集也包含于first(x)strFirst=m_Gr[i].GetAt(++n);elsestrFirst="";break;}}if (j==5) break;}while(!strFirst.IsEmpty());}} while(nEnd);}void CSyntaxAnalysisDlg::Cal_Follow() //求各非终结符的Follow集合{}void CSyntaxAnalysisDlg::DrawMList() //构造预测分析表{int i,j;for (i=0;i<5;i++){for (j=0;j<6;j++){m_M[i][j]="";}}m_M[0][0]="TE";m_M[0][3]="TE";m_M[1][1]="+TE";m_M[1][4]="ε";m_M[1][5]="ε";m_M[2][0]="FK";m_M[2][3]="FK";m_M[3][1]="ε";m_M[3][2]="*FK";m_M[3][4]="ε";m_M[3][5]="ε";m_M[4][0]="i";m_M[4][3]="(S)";m_ListCtrl.SetExtendedStyle(LVS_EX_ GRIDLINES);m_ListCtrl.InsertColumn(0,"",LVCFMT _CENTER,50);m_ListCtrl.InsertColumn(1,"i",LVCFM T_CENTER,50);m_ListCtrl.InsertColumn(2,"+",LVCFM T_CENTER,50);m_ListCtrl.InsertColumn(3,"*",LVCFM T_CENTER,50);m_ListCtrl.InsertColumn(4,"(",LVCFM T_CENTER,50);m_ListCtrl.InsertColumn(5,")",LVCFM T_CENTER,50);m_ListCtrl.InsertColumn(6,"#",LVCFM T_CENTER,50);for (i=0;i<5;i++){m_ListCtrl.InsertItem(i,m_VN[i]);for (j=0;j<6;j++){if(!m_M[i][j].IsEmpty())m_ListCtrl.SetItemText(i,j+1,"→"+m_M[i][j]);}}}void CSyntaxAnalysisDlg::OnBTNAnalysis() {UpdateData(true);if (m_strCode.IsEmpty()){MessageBox("请输入要分析的句子!","提醒");return;}if (Analysis())m_strResult+="归约过程如下:\r\n\r\n"+m_sPro.Right(m_sPro.GetLength( )-3);UpdateData(false);}//主要的程序算法BOOL CSyntaxAnalysisDlg::Analysis(){CString stack[100];int pStack;//定义一个顺序栈stack[0]="#";stack[1]="S";pStack=1;//初始化栈int n=0;CString sStack,sCode,str,strCode,strPro;int i,j;strCode=m_strCode+"#"; //输入串m_sPro="<= S";strPro="S";while (1){if (n==m_strCode.GetLength()&&pStack==0) //分析成功{m_strResult="符合给定文法.";return true;}sStack=stack[pStack];//栈顶字符sCode=strCode.GetAt(n);//剩余输入串的首字符if (sStack==sCode) //匹配{pStack--;n++;continue;}for (i=0;i<5;i++){if (sStack==m_VN[i])break;}if (i==5){m_strResult="不符合给定文法!";return false;}for (j=0;j<5;j++){if (sCode==m_VT[j])break;}if (j==5&&sCode!="#") {m_strResult="不可识别的字符: "+sCode; return false;}str=m_M[i][j]; if (str.IsEmpty()) {m_strResult="不符合给定文法!"; return false;}if (str=="ε") { strPro=strPro.Left(n)+strPro.Right(strPro.GetLength()-n-1);m_sPro="<="+strPro+"\r\n"+m_sPro;pStack--; continue;}strPro=strPro.Left(n)+str+strPro.Right(strPro.GetLength()-n-1);m_sPro="<="+strPro+"\r\n"+m_sPro; pStack--;for(j=0;j<str.GetLength();j++) {pStack++;stack[pStack]=str.GetAt(str.GetLength()-j-1); }}五、运行结果分析句子(i+i)*i正确并写出归约此次实验我继续使用VC++6.0平台编译程序,见面力求简洁,以满足实验功能为主。

编译原理实验二:LL(1)语法分析器

编译原理实验二:LL(1)语法分析器

编译原理实验⼆:LL(1)语法分析器⼀、实验要求 1. 提取左公因⼦或消除左递归(实现了消除左递归) 2. 递归求First集和Follow集 其它的只要按照课本上的步骤顺序写下来就好(但是代码量超多...),下⾯我贴出实验的⼀些关键代码和算法思想。

⼆、基于预测分析表法的语法分析 2.1 代码结构 2.1.1 Grammar类 功能:主要⽤来处理输⼊的⽂法,包括将⽂法中的终结符和⾮终结符分别存储,检测直接左递归和左公因⼦,消除直接左递归,获得所有⾮终结符的First集,Follow集以及产⽣式的Select集。

#ifndef GRAMMAR_H#define GRAMMAR_H#include <string>#include <cstring>#include <iostream>#include <vector>#include <set>#include <iomanip>#include <algorithm>using namespace std;const int maxn = 110;//产⽣式结构体struct EXP{char left; //左部string right; //右部};class Grammar{public:Grammar(); //构造函数bool isNotTer(char x); //判断是否是终结符int getTer(char x); //获取终结符下标int getNonTer(char x); //获取⾮终结符下标void getFirst(char x); //获取某个⾮终结符的First集void getFollow(char x); //获取某个⾮终结符的Follow集void getSelect(char x); //获取产⽣式的Select集void input(); //输⼊⽂法void scanExp(); //扫描输⼊的产⽣式,检测是否有左递归和左公因⼦void remove(); //消除左递归void solve(); //处理⽂法,获得所有First集,Follow集以及Select集void display(); //打印First集,Follow集,Select集void debug(); //⽤于debug的函数~Grammar(); //析构函数protected:int cnt; //产⽣式数⽬EXP exp[maxn]; //产⽣式集合set<char> First[maxn]; //First集set<char> Follow[maxn]; //Follow集set<char> Select[maxn]; //select集vector<char> ter_copy; //去掉$的终结符vector<char> ter; //终结符vector<char> not_ter; //⾮终结符};#endif 2.1.2 AnalyzTable类 功能:得到预测分析表,判断输⼊的⽂法是否是LL(1)⽂法,⽤预测分析表法判断输⼊的符号串是否符合刚才输⼊的⽂法,并打印出分析过程。

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

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

编译原理课程实验报告实验2:语法分析
三、系统设计得分
要求:分为系统概要设计和系统详细设计。

(1)系统概要设计:给出必要的系统宏观层面设计图,如系统框架图、数据流图、功能模块结构图等以及相应的文字说明。

1)系统的数据流图:
说明
说明:本语法分析器是基于上一个实验词法分析器的基础上,通过在界面写或者是导入源程序,词法分析器将源程序识别的词法单元传递给语法分析器,语法分析器验证这个词法单元组成的串是否可以由源语言的文法生成,能够输出语法分析的结果,文法的first集、follow 集和预测分析表,当然也可以以易于理解的方式报告语法错误。

2)系统框架图
本系统框架主要是三部分,一部分是词法分析,负责识别源程序的词法单元识别,并将其存
因为预测分析表实在是过于庞大,因此本处分段截取预测分析表,下面的表是接在上面表的右侧。

(3)针对一测试程序输出其句法分析结果;
测试程序:
语法分析结果:
语法分析树:
(4)输出针对此测试程序对应的语法错误报告;
带错误的测试程序:
语法错误报告:
(5)对实验结果进行分析。

总结:
本语法分析器具有强大的语法分析功能
●允许变量的连续声明,比如int a,b,c;
●允许声明的同时赋值,比如string c = “你好”;
●允许对数组的声明和引用,同时进行赋值,比如char[4] a = {‘a’,’b’,’c’,’d’};a[0] = ‘m’;
●支持多种类型的声明和赋值,比如int,short,long,flaot,double,char,string,boolean
的声明和赋值;
●允许声明和使用一个过程函数,比如:。

《编译原理》课程(语法分析)实验报告

《编译原理》课程(语法分析)实验报告

《编译原理》课程实验报告题目语法分析专业计算机科学与技术班级学号姓名指导教师签名华东理工大学信息学院计算机系2013年5月8日一. 实验序号:《编译原理》第二次实验二. 实验题目:语法分析三. 实验日期:2013.4-2013.5四. 实验环境(操作系统,开发语言)操作系统:Windows开发语言:C五. 实验内容(实验要求)a)将复合语句语法中的“begin”改为“{”,“end”改为“}”。

b)将赋值语句的语法改为“赋值语句必须以分号;结束”。

c)将条件语句语法中的“条件”前增加“(”,“条件”后增加“)”但删除“then”d)“语句”语法中增加if-else语句:if (<条件>) <语句> else <语句>六. 实验体会(请手写,不能打印)(包括收获、心得体会、存在的问题及解决问题的方法、建议等)七. 实验结果(运行结果截图,关键源程序)复合语句更改后的程序:int CompoundStatement(int i){ PrintParsing(ResultofWordTable[AWordIndex],i,"OB");AWordIndex++;StatementParsing(i+1);while (ResultofWordTable[AWordIndex].W_Type==SEMICOLON){ PrintParsing(ResultofWordTable[AWordIndex],i,"SEMICOLOM");AWordIndex++;StatementParsing(i+1);}if (ResultofWordTable[AWordIndex].W_Type==CB){ PrintParsing(ResultofWordTable[AWordIndex],i,"CB");AWordIndex++;return 1;}elsereturn 0;}赋值语句以分号结尾:int AssignmentStatement(int i){ PrintParsing(ResultofWordT able[AWordIndex],i,"IDENTIFIER");AWordIndex++;if (ResultofWordTable[AWordIndex].W_Type==BECOMES){ PrintParsing(ResultofWordTable[AWordIndex],i,"BECOMES");AWordIndex++;Expression(i+1);if (ResultofWordTable[AWordIndex].W_Type==SEMICOLON){ PrintParsing(ResultofWordTable[AWordIndex],i,"SEMICOLON");AWordIndex++;return 1;}elsereturn 0;}elsereturn 0;}条件语句修改后:int ConditionalStatement(int i){ PrintParsing(ResultofWordTable[AWordIndex],i,"IF");AWordIndex++;if (ResultofWordTable[AWordIndex].W_Type==LPAREN){ PrintParsing(ResultofWordTable[AWordIndex],i,"LPAREN");AWordIndex++;Conditional(i);if (ResultofWordTable[AWordIndex].W_Type==RPAREN){ PrintParsing(ResultofWordTable[AWordIndex],i,"RPAREN");AWordIndex++;StatementParsing(i+1);if (ResultofWordTable[AWordIndex].W_Type==ELSE){ PrintParsing(ResultofWordTable[AWordIndex],i,"ELSE");AWordIndex++;StatementParsing(i+1);return 1; }}elsereturn 0;}elsereturn 0;}其他一些程序代码:主函数:int main(int , char* ){ FILE *fp;if((fp=fopen(FILE_NAME,"r"))==NULL)printf( "Can’t open the file!\n" );if((fp=fopen(FILE_RESULT,"w+"))==NULL)printf( " Can’t open the file!\n" );char ch; //定义读到的每个字符ch = fgetc(fp); //从文件中读入一个字符while(ch != EOF) //按读入字符逐个输出在屏幕中{ putchar(ch);ch = fgetc(fp);}Initialize(); //初始化printf("----------- Parsing Analysis!------------\n");printf("Index Rows Word Analysis\n");ParsingAnalysisFunction(Index);printf("-------------------END------------------\n");getchar();return 0;}分程序分析:int BlockParsing(int i){ PrintParsing(ResultofWordTable[AWordIndex],i-1,"BlockParsing");if(ResultofWordTable[AWordIndex].W_Type==CONST){PrintParsing(ResultofWordTable[AWordIndex],i,"CONST");AWordIndex++;PrintParsing(ResultofWordTable[AWordIndex],i,"oneConstantParsing");oneConstantParsing(i+1); //常量声明分析}if(ResultofWordTable[AWordIndex].W_Type==VAR){PrintParsing(ResultofWordTable[AWordIndex],i,"VAR");AWordIndex++;PrintParsing(ResultofWordTable[AWordIndex],i,"oneVarParsing");oneVariableParsing(i+1); //变量声明分析}while(ResultofWordT able[AWordIndex].W_Type==PROCEDURE){ PrintParsing(ResultofWordTable[AWordIndex],i,"PROCEDURE");AWordIndex++;PrintParsing(ResultofWordTable[AWordIndex],i,"oneProcesureParsing");ProcedureParsing(i+1); //过程声明分析}StatementParsing(i);return 1;}过程调用语句:int ProcedureCall(int i){ PrintParsing(ResultofWordTable[AWordIndex],i,"CALL");AWordIndex++;if (ResultofWordTable[AWordIndex].W_Type==IDENTIFIER){ PrintParsing(ResultofWordTable[AWordIndex],i,"IDENTIFIER");AWordIndex++;return 1;}elsereturn 0;}循环语句分析:int LoopStatement(int i){ PrintParsing(ResultofWordTable[AWordIndex],i,"WHILE");AWordIndex++;Conditional(i);if (ResultofWordTable[AWordIndex].W_Type==DO){ PrintParsing(ResultofWordTable[AWordIndex],i,"DO");AWordIndex++;StatementParsing(i+1);return 1;}elsereturn 0;}实验结果截图:。

编译原理实验2语法分析器构造

编译原理实验2语法分析器构造
不为#N
将symbols中所有优先 级比当前字符低的弹 出栈存入ch直到有一
个不低于的
判断ch与word[i]是否相 等

规约为N,将N压入 symbols
从inputStr读入字符
判断当前字符优先级是

否不低于栈顶字符

将当前字符压入 symbols
当前字符是否为#

结束
报错
3. 主要技术问题的处理方法 (1) 判断优先级时,原本设置了三个函数,代码过于冗余,提取相同部分 后将他们整合为了一个函数,大大减少了代码量 (2) 最初基本功能全部写在了主函数内,虽然变量的传值十分简单,但是 逻辑也极其混乱,优化结构后将大部分功能封装在一个个的函数内部,结 构变得十分清晰,逻辑也更为优质。 (3) 在比较优先级的时候做的还不够完美,需要传入一个数组下标和一个 字符才可以比较,进一步的优化可以将其改为直接传入两个字符来进行优 先级的比较,代码也更加人性化。
default: return -1;
} } /* 判断终结符 */ int isVT(char ch) {
if(ch=='N') return 0;
return 1; }
/* 读入终结符 */ char readVT(int k) {
if(isVT(inputStr[k])) { return inputStr[k];
2018~2019 年春季学期
序号:
《编译原理》课程 实验报告
实验二 语法分析器构造
专业班级: 学生姓名: 学生学号:
一、目的和要求
借助于词法分析程序提供的分析结果,编写一个算符优先语法分析程序,程 序能进行语法结构分析和错误检查,并产生相应的归约信息。同时给出出错信息 和错误类型,从而加深对语法分析的理解。

语法分析实验报告(实验二)

语法分析实验报告(实验二)

编译原理语法分析实验报告软工082班兰洁200831104044一、实验内容二、实验目的三、实验要求四、程序流程图●主函数;●scanner();●irparser()函数●yucu() /*语句串分析*/●statement()/*语句分析函数*/●expression()/*表达式分析函数*/●term()/*项分析函数*/●factor()/*因子分析函数*/五、程序代码六、测试用例七、输出结果八、实验心得一、实验内容:编写为一上下文无关文法构造其递归下降语法分析程序,并对任给的一个输入串进行语法分析检查。

程序要求能对输入串进行递归下降语法分析,能判别程序是否符合已知的语法规则,如果不符合(编译出错),则输出错误信息。

二、实验目的:构造文法的语法分析程序,要求采用递归下降语法分析方法对输入的字符串进行语法分析,实现对词法分析程序所提供的单词序列的语法检查和结构分析,进一步掌握递归下降的语法分析方法。

三、实验要求:利用C语言编制递归下降分析程序,并对Training语言进行语法分析。

1.待分析的Training语言语法。

用扩充的表示如下:<程序>-->function<语句串>endfunc<语句串>--><语句>{;<语句>}<语句>→<赋值语句><赋值语句>→ID→<表达式><表达式>→<项>{+<项>|-<项>}<项>→<因子>{*<因子>|/<因子>}<因子>→ID|NUM|(<表达式>)备注:实验当中我对程序进行了扩展,增加了程序识别if条件判断语句,while循环语句的功能2.实验要求说明输入单词串以“#”结束,如果是文法正确的句子,则输出成功信息,打印“success”,否则输出“error”。

编译原理——语法分析程序设计实验报告

编译原理——语法分析程序设计实验报告

实验二语法分析程序设计[实验目的]:1.了解语法分析的主要任务。

2.熟悉编译程序的编制。

[实验内容]:根据某文法,构造一基本递归下降语法分析程序。

给出分析过程中所用的产生式序列。

[实验要求]:1.选择一个文法,进行实验,可选的文法包括以下三个:P190 4.8P190 4.9P190 4.102.设计语法分析程序的输出形式(输出应为语法树或推导),一个可以参考的例子,可见图1。

3.编写递归下降语法分析程序(参考P148-149 Topdown parsing byrecursive-descent),实现基本的递归下降分析器,能够分析任给的符号串是否为该文法所定义的合法句子。

实验报告中要说明分析使用的方法。

4.根据所作业题选项e所给出的input,生成并输出分析过程中所用的产生式序列(show the actions of parser):1 产生式12 产生式2……5.自已设计一个不合法的句子,作为输出进行分析,给出结果。

[实验过程]本次实验选择的文法为P190 4.8lexp->atom|listatom->number|identifierlist->(lexp-seq)lexp-seq->lexp lexp-seq1.写出实现的算法,并画流程图。

本次实验采用递归下降算法,算法流程图如下图1-1:图1-1 算法流程图2.根据你选择的文法,分析左递归或左因子是否会影响本算法的结果。

会影响本算法的结果。

递归下降分析法要求的文法是LL(1)文法,需要消除左递归和左因子的影响。

如果存在左因子,对相同的字符跳转到不同的函数,无法实现递归。

3.列举实验设计过程中出现的问题及解决的方法(至少3条,选择实验中最困扰的问题)。

1).会多次输出accept/error结果解决方案:所有的递归函数返回类型为int,若accept返回1,error返回0,在main主函数中统一判断输出语句。

编译原理实验二LL(1)语法分析实验报告

编译原理实验二LL(1)语法分析实验报告

专题3_LL(1)语法分析设计原理与实现李若森 13281132 计科1301一、理论传授语法分析的设计方法和实现原理;LL(1) 分析表的构造;LL(1)分析过程;LL(1)分析器的构造。

二、目标任务实验项目实现LL(1)分析中控制程序(表驱动程序);完成以下描述算术表达式的 LL(1)文法的LL(1)分析程序。

G[E]:E→TE’E’→ATE’|εT→FT’T’→MFT’|εF→(E)|iA→+|-M→*|/设计说明终结符号i为用户定义的简单变量,即标识符的定义。

加减乘除即运算符。

设计要求(1)输入串应是词法分析的输出二元式序列,即某算术表达式“专题 1”的输出结果,输出为输入串是否为该文法定义的算术表达式的判断结果;(2)LL(1)分析程序应能发现输入串出错;(3)设计两个测试用例(尽可能完备,正确和出错),并给出测试结果。

任务分析重点解决LL(1)表的构造和LL(1)分析器的实现。

三、实现过程实现LL(1)分析器a)将#号放在输入串S的尾部b)S中字符顺序入栈c)反复执行c),任何时候按栈顶Xm和输入ai依据分析表,执行下述三个动作之一。

构造LL(1)分析表构造LL(1)分析表需要得到文法G[E]的FIRST集和FOLLOW集。

构造FIRST(α)构造FOLLOW(A)构造LL(1)分析表算法根据上述算法可得G[E]的LL(1)分析表,如表3-1所示:表3-1 LL(1)分析表主要数据结构pair<int, string>:用pair<int, string>来存储单个二元组。

该对照表由专题1定义。

map<string, int>:存储离散化后的终结符和非终结符。

vector<string>[][]:存储LL(1)分析表函数定义init:void init();功能:初始化LL(1)分析表,关键字及识别码对照表,离散化(非)终结符传入参数:(无)传出参数:(无)返回值:(无)Parse:bool Parse( const vector<PIS> &vec, int &ncol );功能:进行该行的语法分析传入参数:vec:该行二元式序列传出参数:emsg:出错信息epos:出错标识符首字符所在位置返回值:是否成功解析。

编译原理语法分析实验二表达式语法分析器的设计实现

编译原理语法分析实验二表达式语法分析器的设计实现

编译原理程序设计实验报告——实验题目班级:计算机1306姓名:学号:实验目标:表达式语法分析器的设计实现1) 递归下降子程序 2) LL (1)分析法实验内容: 1. 概要设计1) 按照流程图,调用子程序实现;2) 通过ll (1)分析表和对应压栈、弹栈操作实现。

2. 流程图1) 递归: Z ’(main):N Err开始Read (w ) E #? 结束E: E1:Y NY NT: T1:YNYNF :N N err Y YY N err入口 TE1 入口+? -? 出口Read(w) T出口入口 FT1 出口入口*?/?出口Read (w )T入口I ? (? Read (w )E )? Read (w )出口2) LL (1):BeginPUSH(#),PUSH(E)POP(x)x ∈VTx ∈VNx=wendW=#nyNEXT(w)yn err查LL (1)分析表空?nPUSH (i )errny逆序压栈开始构建LL(1)分析表调用函数token ()切分单词 调用*Analyse(char *token)进行分析 结束3.关键函数1)递归下降子程序void E(); //E->TX;int E1(); //X->+TX | evoid T(); //T->FYint T1(); //Y->*FY | eint F(); //F->(E) | i2)LL(1)分析法char *Find(char vn,char vt)//是否查到表char *Analyse(char *token)//分析过程int Token()//将token中数字表示成i,标识符表示成n源程序代码:(加入注释)1)递归下降子程序:#include<stdio.h>#include<iostream>#include <string.h>#include <stdlib.h>using namespace std;/********全局变量**********/char str[30];int index=0;void E();//E->TX;int E1();//X->+TX | evoid T();//T->FYint T1();//Y->*FY | eint F();//F->(E) | iFILE *fp;char cur;/*************主函数************/int main(){int len;int m;if((fp=fopen("source.txt","r"))==NULL){cout<<"can not open the source file!"<<endl;exit(1);}cur=fgetc(fp);while(cur!='#'){E();}cout<<endl;cout<<"success"<<endl;return 0;}/*************************************/void E(){T();E1();}/*************************************/int E1(){if(cur=='+'){cur=fgetc(fp);T();cout<<'+'<<" ";E1();}else if(cur=='-'){cur=fgetc(fp);T();cout<<'-'<<" ";E1();}return 0;}/************************************/void T(){F();T1();}/***********************************/int T1(){if(cur=='*'){cur=fgetc(fp);F();cout<<'*'<<" ";T1();}else if(cur=='/'){cur=fgetc(fp);F();cout<<'/'<<" ";T1();}return 0;}int F(){if((cur<='z'&&cur>='a')||(cur<='Z'&&cur>='A')||cur=='_'){for(int i=0;i<20;i++){str[i]='\0';index=0;}str[index++]=cur;cur=fgetc(fp);while((cur<='z'&&cur>='a')||(cur<='Z'&&cur>='A')||cur=='_'||(cur<='9'&&cur>='0')){str[index++]=cur;cur=fgetc(fp);}cout<<str;cout<<" ";return NULL;}else if (cur<='9'&&cur>='0'){for(int i=0;i<20;i++){str[i]='\0';index=0;}while(cur<='9'&&cur>='0'){str[index++]=cur;cur=fgetc(fp);}if(cur=='.'){str[index++]=cur;cur=fgetc(fp);while(cur<='9'&&cur>='0'){str[index++]=cur;cur=fgetc(fp);}cout<<str;cout<<" ";return NULL;}else if((cur<='z'&&cur>='a')||(cur<='Z'&&cur>='A')||cur=='_'){printf("error6\n");exit(1);}else{cout<<str;cout<<" ";return NULL;}}else if (cur=='('){cur=fgetc(fp);E();if(cur==')'){cur=fgetc(fp);return 0;}else{printf("error3\n");exit (1);}}else{printf("error4\n");exit(1);}return 0;}程序运行结果:(截屏)输入:Source.txt文本((Aa+Bb)*(88.2/3))#输出:2)LL(1)#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <stack>using namespace std;struct Node1{char vn;char vt;char s[12];}MAP[22];//存储分析预测表每个位置对应的终结符,非终结符,产生式int k;char token[30];int token_index=0;charG[12][12]={"E->TR","R->+TR","R->-TR","R->e","T->FW","W->*FW","W->/FW", "W->e","F->(E)","F->i","F->n"};//存储文法中的产生式,用R代表E',W代表T',e代表空//char VN[6]={'E','R','T','W','F'};//存储非终结符//char VT[9]={'i','n','+','-','*','/','(',')','#'};//存储终结符char Select[12][12]={"(,i,n","+","-","),#","(,i,n","*","/","+,-,),#","(","i","n"};//存储文法中每个产生式对应的select集合charRight[12][8]={"->TR","->+TR","->-TR","->e","->FW","->*FW","->/FW","->e","->( E)","->i","->n"};stack<char> stak,stak1,stak2;char *Find(char vn,char vt){int i;for(i=0;i<k;i++){if(MAP[i].vn==vn&& MAP[i].vt==vt)return MAP[i].s;}return "error";}char *Analyse(char *token){char p,action[10],output[10];int i=1,j,k=0,l_act,m;while(!stak.empty())//判断栈中是否为空,若不空就将栈顶元素与分析表匹配进行相应操作stak.pop();stak.push('#');//栈底标志stak.push('E');//起始符号先入栈printf(" 步骤栈顶元素输入串推导所用产生式或匹配\n");p=stak.top();while(p!='#')//查预测分析表将栈顶元素进行匹配,若栈顶元素与输入串匹配成功则向前匹配,否则生成式反序入栈{printf("%7d ",i++);p=stak.top();//从栈中弹出一个栈顶符号,由p记录并输出stak.pop();printf("%6c ",p);for(j=0,m=0;j<token_index;j++)//将未被匹配的剩余输入串输出output[m++]=token[j];output[m]='\0';printf("%10s",output);if(p==token[k]){ if(p=='#')//若最后一个结束符号匹配说明输入表达式被接受,否则继续匹配{printf(" 接受\n");return "SUCCESS";}printf(" “%c”匹配\n",p);k++;}else{ //将未被匹配的第一个字符与find函数的结果进行比较,在预测分析表中查找相应生成式strcpy(action,Find(p,token[k]));if(strcmp(action,"error")==0){printf(" 没有可用的产生式\n");return "ERROR";}printf(" %c%s\n",p,action);int l_act=strlen(action);if(action[l_act-1]=='e')continue;for(j=l_act-1;j>1;j--)stak.push(action[j]);}}return "ERROR";}int Token(){FILE *fp;char cur;int i,j;fp=fopen("source.txt","r");cur=fgetc(fp);while(cur!=EOF)//把用字母数字表示的输入串转换为token序列的表示方法{if((cur<='z'&&cur>='a')||(cur<='Z'&&cur>='A')||cur=='_'){cur=fgetc(fp);while((cur<='z'&&cur>='a')||(cur<='Z'&&cur>='A')||cur=='_'||(cur<='9'&&cur>='0')){cur=fgetc(fp);} token[token_index++]='i';continue;}else if (cur<='9'&&cur>='0'){while(cur<='9'&&cur>='0')cur=fgetc(fp);if(cur=='.'){cur=fgetc(fp);while(cur<='9'&&cur>='0')cur=fgetc(fp);}token[token_index++]='n';continue;}else{token[token_index++]=cur;cur=fgetc(fp);continue;} }token[token_index]='#';cout<<"把文件中字符串用i表示,数字用n表示,转化后:";for(int index=0;index<=token_index;index++)cout<<token[index];cout<<endl<<endl;return 0;}int main (){int i,j,l,m;for(i=0,k=0;i<11;i++)//通过select集合生成预测分析表{l=strlen(Select[i]);for(j=0;j<l;j+=2){MAP[k].vn=G[i][0];MAP[k].vt=Select[i][j];strcpy(MAP[k].s,Right[i]);k++;}}Token();cout<<"分析过程如下:"<<endl;cout<<Analyse(token)<<endl;return 0;}程序运行结果:(截屏)输入:Source.txt文本((Aa+Bb)*(88.2/3))输出:目录第一章项目总论 ········································错误!未定义书签。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

华北水利水电学院编译原理实验报告2010~2011学年第二学期xxxx 级计算机专业班级:xxxxx 学号:xxxxx 姓名:xxx一、实验目的通过设计、编制、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析方法。

二、实验要求⑴选择最有代表性的语法分析方法,如LL(1)分析法、算符优先法或LR分析法⑵选择对各种常见程序语言都用的语法结构,如赋值语句(尤指表达式)作为分析对象,并且与所选语法分析方法要比较贴切。

⑶实习时间为6小时。

三、实验内容选题1:使用预测分析法(LL(1)分析法)实现语法分析:(1)根据给定文法,先求出first集合、follow集合和select集合,构造预测分析表(要求预测分析表输出到屏幕或者输出到文件);(2)根据算法和预测分析表分析给定表达式是否是该文法识别的正确的算术表达式(要求输出归约过程)(3)给定表达式文法为:G(E): S→TEE→+TE | εT→FKK→*FK |εF→(S)|i(4)分析的句子为:(i+i)*i和i+i)*i四、程序源代码#include "stdafx.h"#include "SyntaxAnalysis.h"#include "SyntaxAnalysisDlg.h" #ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILE static char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////// // CAboutDlg dialog used for App Aboutclass CAboutDlg : public CDialog{public:CAboutDlg();// Dialog Data//{{AFX_DATA(CAboutDlg)enum { IDD = IDD_ABOUTBOX };//}}AFX_DATA// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CAboutDlg)protected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support//}}AFX_VIRTUAL// Implementationprotected://{{AFX_MSG(CAboutDlg)//}}AFX_MSGDECLARE_MESSAGE_MAP()};CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD){//{{AFX_DATA_INIT(CAboutDlg)//}}AFX_DATA_INIT}void CAboutDlg::DoDataExchange(CDataExchange* pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CAboutDlg)//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)//{{AFX_MSG_MAP(CAboutDlg)// No message handlers//}}AFX_MSG_MAPEND_MESSAGE_MAP()// CSyntaxAnalysisDlg dialogCSyntaxAnalysisDlg::CSyntaxAnalysisDlg(CWnd * pParent /*=NULL*/): CDialog(CSyntaxAnalysisDlg::IDD, pParent){//{{AFX_DATA_INIT(CSyntaxAnalysisDlg)m_strCode = _T("");m_strResult = _T("");//}}AFX_DATA_INIT// Note that LoadIcon does not require a subsequent DestroyIcon in Win32m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);}voidCSyntaxAnalysisDlg::DoDataExchange(CDataExc hange* pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CSyntaxAnalysisDlg)DDX_Control(pDX, IDC_LIST1, m_ListCtrl);DDX_Text(pDX, IDC_EDIT_Code, m_strCode);DDX_Text(pDX, IDC_EDIT_Result, m_strResult);//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CSyntaxAnalysisDlg, CDialog)//{{AFX_MSG_MAP(CSyntaxAnalysisDlg)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDC_BTN_Analysis, OnBTNAnalysis)//}}AFX_MSG_MAPEND_MESSAGE_MAP()// CSyntaxAnalysisDlg message handlersBOOL CSyntaxAnalysisDlg::OnInitDialog(){CDialog::OnInitDialog();ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX < 0xF000);CMenu* pSysMenu = GetSystemMenu(FALSE);if (pSysMenu != NULL){CString strAboutMenu;strAboutMenu.LoadString(IDS_ABOUTBOX);if (!strAboutMenu.IsEmpty()){pSysMenu->AppendMenu(MF_SEPARATOR);pSysMenu->AppendMenu(MF_STRING,IDM_ABOUTBOX, strAboutMenu);}}SetIcon(m_hIcon, TRUE); // Set big iconSetIcon(m_hIcon, FALSE); // Set small icon// TODO: Add extra initialization here//初始化给定文法m_VN[0]="S";m_VN[1]="E";m_VN[2]="T";m_VN[3]="K";m_VN[4]="F";m_VT[0]="i";m_VT[1]="+";m_VT[2]="*";m_VT[3]="(";m_VT[4]=")";m_Gl[0]=0;m_Gr[0]="TE";m_Gl[1]=1;m_Gr[1]="+TE";m_Gl[2]=1;m_Gr[2]="ε";m_Gl[3]=2;m_Gr[3]="FK";m_Gl[4]=3;m_Gr[4]="*FK";m_Gl[5]=3;m_Gr[5]="ε";m_Gl[6]=4;m_Gr[6]="(S)";m_Gl[7]=4;m_Gr[7]="i";Cal_Symbol();Cal_First();Cal_Follow();DrawMList();return TRUE; // return TRUE unless you set the focus to a control}void CSyntaxAnalysisDlg::OnSysCommand(UINT nID, LPARAM lParam){if ((nID & 0xFFF0) == IDM_ABOUTBOX){CAboutDlg dlgAbout;dlgAbout.DoModal();}else{CDialog::OnSysCommand(nID, lParam);}}void CSyntaxAnalysisDlg::OnPaint(){if (IsIconic()){CPaintDC dc(this);SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);// Center icon in client rectangleint cxIcon = GetSystemMetrics(SM_CXICON);int cyIcon = GetSystemMetrics(SM_CYICON);CRect rect;GetClientRect(&rect);int x = (rect.Width() - cxIcon + 1) / 2;int y = (rect.Height() - cyIcon + 1) / 2;// Draw the icondc.DrawIcon(x, y, m_hIcon);}else{CDialog::OnPaint();}}CSyntaxAnalysisDlg::OnQueryDragIcon(){return (HCURSOR) m_hIcon;}void CSyntaxAnalysisDlg::Cal_Symbol() //求出能推出ε的非终结符{int i,j,k,nEnd;CString Gr[8];for (i=0;i<5;i++)m_nFlags[i]=0; //置初值,0表示否for (i=0;i<8;i++){Gr[i]=m_Gr[i];if (Gr[i]=="ε"){m_nFlags[m_Gl[i]]=1; //1表示是,即能推出ε}}do{nEnd=0;for (i=0;i<5;i++) //检查每一个非终结符{if (m_nFlags[i]==1) //如果该非终结符能推出ε,就将所有表达式右部删去该终结符{for (j=0;j<8;j++) //查找每一个表达式{if(Gr[j].IsEmpty()||Gr[j]=="ε") continue;for(k=0;k<Gr[j].GetLength();k++) //查找表达式右部的每一个字符{if(Gr[j].GetAt(k)==m_VN[i]) //找到该终结符{Gr[j]=Gr[j].Left(k)+Gr[j].Right(Gr[j].G etLength()-k-1); //删去该终结符nEnd=1;break;}}if (Gr[j].IsEmpty()) m_nFlags[m_Gl[j]]=1; //如果右部为空,就在表中填是}}}} while(nEnd);}void CSyntaxAnalysisDlg::Cal_First() //求各非终结符的First集合{int i,j,k,nEnd,n;CString strFirst;for (i=0;i<5;i++){for (j=0;j<6;j++)m_First[i][j]=0;}for (i=0;i<8;i++){if (m_Gr[i].Left(2)=="ε"){m_First[m_Gl[i]][5]=1;continue;}strFirst=m_Gr[i].GetAt(0);for (j=0;j<5;j++){if (strFirst==m_VT[j]) //如果右部第一个字符是终结符{m_First[m_Gl[i]][j]=1;break;}}}do{nEnd=0;for (i=0;i<8;i++){n=0;strFirst=m_Gr[i].GetAt(0);do{for (j=0;j<5;j++){if(strFirst==m_VN[j]) //如果右部第一个字符是非终结符{for(k=0;k<6;k++){if(m_First[m_Gl[i]][k]!=m_First[j][k]){m_First[m_Gl[i]][k]=m_First[j][k];nEnd=1;}}if(m_First[j][5]==1&&n<m_Gr[i].GetLength()-1) //前一字符能推出ε,则下一字符的first 集也包含于first(x)strFirst=m_Gr[i].GetAt(++n);elsestrFirst="";break;}}if (j==5) break;} while(!strFirst.IsEmpty());}} while(nEnd);}void CSyntaxAnalysisDlg::Cal_Follow() //求各非终结符的Follow集合{}void CSyntaxAnalysisDlg::DrawMList() //构造预测分析表{int i,j;for (i=0;i<5;i++){for (j=0;j<6;j++){m_M[i][j]="";}}m_M[0][0]="TE";m_M[0][3]="TE";m_M[1][1]="+TE";m_M[1][4]="ε";m_M[1][5]="ε";m_M[2][0]="FK";m_M[2][3]="FK";m_M[3][1]="ε";m_M[3][2]="*FK";m_M[3][4]="ε";m_M[3][5]="ε";m_M[4][0]="i";m_M[4][3]="(S)";m_ListCtrl.SetExtendedStyle(LVS_EX_GRID LINES);m_ListCtrl.InsertColumn(0,"",LVCFMT_CEN TER,50);m_ListCtrl.InsertColumn(1,"i",LVCFMT_CE NTER,50);m_ListCtrl.InsertColumn(2,"+",LVCFMT_CE NTER,50);m_ListCtrl.InsertColumn(3,"*",LVCFMT_CE NTER,50);m_ListCtrl.InsertColumn(4,"(",LVCFMT_CE NTER,50);m_ListCtrl.InsertColumn(5,")",LVCFMT_CE NTER,50);m_ListCtrl.InsertColumn(6,"#",LVCFMT_CE NTER,50);for (i=0;i<5;i++){m_ListCtrl.InsertItem(i,m_VN[i]);for (j=0;j<6;j++){if (!m_M[i][j].IsEmpty())m_ListCtrl.SetItemText(i,j+1,"→"+m_M[i][j]);}}}void CSyntaxAnalysisDlg::OnBTNAnalysis() {UpdateData(true);if (m_strCode.IsEmpty()){MessageBox("请输入要分析的句子!","提醒");return;}if (Analysis())m_strResult+="归约过程如下:\r\n\r\n"+m_sPro.Right(m_sPro.GetLength( )-3);UpdateData(false);}//主要的程序算法BOOL CSyntaxAnalysisDlg::Analysis(){CString stack[100];int pStack;//定义一个顺序栈stack[0]="#";stack[1]="S";pStack=1;//初始化栈int n=0;CString sStack,sCode,str,strCode,strPro;int i,j;strCode=m_strCode+"#"; //输入串m_sPro="<= S";strPro="S";while (1){if(n==m_strCode.GetLength()&&pStack==0) //分析成功{m_strResult="符合给定文法.";return true;}sStack=stack[pStack]; //栈顶字符sCode=strCode.GetAt(n); //剩余输入串的首字符if (sStack==sCode) //匹配{pStack--;n++;continue;}for (i=0;i<5;i++){if (sStack==m_VN[i])break;}if (i==5){m_strResult="不符合给定文法!";return false;}for (j=0;j<5;j++){if (sCode==m_VT[j])break;}if (j==5&&sCode!="#"){m_strResult="不可识别的字符:"+sCode;return false;}str=m_M[i][j];if (str.IsEmpty()){m_strResult="不符合给定文法!";return false;}if (str=="ε"){strPro=strPro.Left(n)+strPro.Right(strPro.GetLengtm_sPro="<="+strPro+"\r\n"+m_sPro;pStack--;continue;}strPro=strPro.Left(n)+str+strPro.Right(strPro.GetLength()-n-1);m_sPro="<= "+strPro+"\r\n"+m_sPro;pStack--;for (j=0;j<str.GetLength();j++){pStack++;stack[pStack]=str.GetAt(str.GetLength()-j-1);} }五、运行结果分析句子(i+i)*i正确并写出归约此次实验我继续使用VC++6.0平台编译程序,见面力求简洁,以满足实验功能为主。

相关文档
最新文档