编译原理-LR语法分析器的控制程序实验报告
lr语法分析实验报告
lr语法分析实验报告LR语法分析实验报告引言在计算机科学领域,语法分析是编译器设计中非常重要的一个环节。
它负责将输入的源代码按照给定的文法规则进行解析,并生成语法树或分析表。
本实验报告将介绍LR语法分析器的设计与实现,并通过实验结果进行分析和评估。
一、背景知识1.1 语法分析语法分析是编译器的一个重要组成部分,它负责将输入的源代码转化为抽象语法树或分析表。
语法分析器根据给定的文法规则,逐个读取输入的字符并进行规约或移进操作,最终确定输入串是否符合给定的文法。
1.2 LR语法分析LR语法分析是一种自底向上的语法分析方法,它利用有限状态自动机进行分析。
LR分析器根据输入的文法规则和状态转移表,逐步推导输入串,直到达到最终的语法树或分析表。
二、实验设计2.1 实验目标本实验旨在设计和实现一个LR语法分析器,包括以下主要内容:- 设计和实现文法规则- 构建LR分析表- 实现LR分析器的状态转移和语法规约操作2.2 实验环境本实验使用Python语言进行实现,使用了Python的语法分析库PLY(Python Lex-Yacc)。
三、实验过程3.1 文法规则设计在本实验中,选择了一个简单的算术表达式文法作为示例:```E -> E + T| E - T| TT -> T * F| T / F| FF -> ( E )| number```该文法规则描述了四则运算表达式的语法结构,其中E表示表达式,T表示项,F表示因子。
3.2 构建LR分析表根据给定的文法规则,我们可以构建LR分析表。
该表记录了分析器在不同状态下的状态转移和规约操作。
3.3 实现LR分析器基于PLY库,我们可以很方便地实现LR分析器的状态转移和规约操作。
首先,我们需要定义文法规则的各个产生式对应的处理函数。
然后,通过PLY库提供的API,我们可以构建分析器对象,并进行状态转移和规约操作。
四、实验结果与分析4.1 实验结果经过实验,我们成功地实现了LR语法分析器,并对多个测试用例进行了分析。
北邮编译原理LR语法分析程序实验报告
LR语法分析程序实验报告说明:该程序使用实现对算术表达式自底向上的语法分析,并且在对输入表达式进行分析的过程中,输出分析动作,移进或者用哪个产生式进行规约,该程序使用的是LR语法分析程序,手动构造了识别所有活前缀的DFA,为给定文法构造LR分析表,并通过预测分析表对输入的表达式进行分析,并将栈顶状态和预测分析过程详细输出,如果匹配成功则接受,如果匹配不成功则返回错误信息。
特别的是,该程序参照书上129页的有关LR分析的错误处理与恢复表对一些可能出现的错误进行报错和局部恢复,在action表中设置相应的错误处理过程入口,调用相应的过程进行错误处理和恢复,使语法分析能继续进行。
给定文法的产生式为:E->E+T | TT->T*F | FF-> id | (E)源代码:#include<iostream>#include<stack>using namespace std;stack<char> symbol;stack<int> state;char sen[50];char sym[12][6]={//符号表{'s','e','e','s','e','e'},{'e','s','e','e','e','a'},{'r','r','s','r','r','r'},{'r','r','r','r','r','r'},{'s','e','e','s','e','e'},{'r','r','r','r','r','r'},{'s','e','e','s','e','e'},{'s','e','e','s','e','e'},{'e','s','e','e','s','e'},{'r','r','s','r','r','r'},{'r','r','r','r','r','r'},{'r','r','r','r','r','r'}};char snum[12][6]={//数字表{5,1,1,4,2,1},{3,6,5,3,2,0},{2,2,7,2,2,2},{4,4,4,4,4,4},{5,1,1,4,2,1},{6,6,6,6,6,6},{5,1,1,4,2,1},{5,1,1,4,2,1},{3,6,5,3,11,4},{1,1,7,1,1,1},{3,3,3,3,3,3},{5,5,5,5,5,5}};int go2[12][3]={//goto表{1,2,3},{0,0,0},{0,0,0},{0,0,0},{8,2,3},{0,0,0},{0,9,3},{0,0,10},{0,0,0},{0,0,0},{0,0,0},{0,0,0}};void action(int i,char *&a,char &how,int &num,char &A,int &b)//action函数[i,a] {int j;switch(*a){case 'i':j=0;break;case '+':j=1;break;case '*':j=2;break;case '(':j=3;break;case ')':j=4;break;case '#':j=5;break;default:j=-1;break;}printf("%c\t\t",*a);if(j!=-1){how=sym[i][j];num=snum[i][j];if(how=='r'){switch(num){case 1:A='E',b=3;cout<<"reduce by E->E+T"<<endl;break;case 2:A='E',b=1;cout<<"reduce by E->T"<<endl;break;case 3:A='T',b=3;cout<<"reduce by T->T*F"<<endl;break;case 4:A='T',b=1;cout<<"reduce by T->F"<<endl;break;case 5:A='F',b=3;cout<<"reduce by F->(E)"<<endl;break;case 6:A='F',b=1;cout<<"reduce by F->id"<<endl;break;default:break;}}}}int go(int t,char A)//goto[t,A]{switch(A){case 'E':return go2[t][0];break;case 'T':return go2[t][1];break;case 'F':return go2[t][2];break;}}void error(int i,int j,char *&a)//error处理函数{switch(j){case 1://期望输入id或左括号,但是碰到+,*,或$,就假设已经输入id了,转到状态5 cout<<"error:缺少运算对象id"<<endl;symbol.push('i');//必须有这个,如果假设输入id的话,符号栈里必须有....printf("i\t\t");state.push(5);printf("5\t\t");break;case 2://从输入中删除右括号a++;cout<<"error:不配对的右括号"<<endl;break;case 3://期望碰到+,但是输入id或左括号,假设已经输入算符+,转到状态6 cout<<"error:缺少运算符"<<endl;symbol.push('+');printf("+\t\t");state.push(6);printf("6\t\t");break;case 4://缺少右括号,假设已经输入右括号,转到状态11cout<<"error:缺少右括号"<<endl;symbol.push(')');printf(")\t\t");state.push(11);printf("11\t\t");break;case 5:a++;cout<<"error:*号无效,应该输入+号!"<<endl;case 6:a++;}}int main(){int s;char *a;char how;int num;int b;char A;cout<<"请输入表达式(以i表示标识符,以#结束):"<<endl;while(1){cin>>sen;a=sen;state.push(0);//先输入0状态printf("\t\t-------分析过程-------\n");printf("符号栈栈顶\t状态栈栈顶\t当前读入符号\t分析动作\n");printf(" \t\t0\t\t");while(*a!='\0'){b=0;num=0;how='\0';A='\0';s=state.top();action(s,a,how,num,A,b);if(how=='s')//移进{cout<<"Shift"<<endl;symbol.push(*a);printf("%c\t\t",*a);state.push(num);printf("%d\t\t",num);a++;}else if(how=='r')//规约{for(int i=0;i<b;i++){if(!state.empty())state.pop();if(!symbol.empty())symbol.pop();}int t=state.top();symbol.push(A);printf("%c\t\t",A);state.push(go(t,A));printf("%d\t\t",go(t,A));}else if(how=='a')//接受break;else{error(s,num,a);//错误处理}}cout<<"accept"<<endl;}return 0;}输入的表达式正确则不报错并接受:输入错误的表达式i*(i+i*i#报错并进行恢复:输入错误的表达式i+*i#报错并恢复:输入错误表达式i*ii+i)#进行报错并恢复:。
编译原理-语法分析程序报告
编译原理实验实验二语法分析器实验二:语法分析实验一、实验目的根据给出的文法编制LR(1)分析程序,以便对任意输入的符号串进行分析。
本次实验的目的主要是加深对LR(1)分析法的理解。
二、实验预习提示1、LR(1)分析法的功能LR(1)分析法的功能是利用LR(1)分析表,对输入符号串自下而上的分析过程。
2、LR(1)分析表的构造及分析过程。
三、实验内容对已给语言文法,构造LR(1)分析表,编制语法分析程序,要求将错误信息输出到语法错误文件中,并输出分析句子的过程(显示栈的内容);实验报告必须包括设计的思路,以及测试报告(输入测试例子,输出结果)。
语法分析器一、功能描述:语法分析器,顾名思义是用来分析语法的。
程序对给定源代码先进行词法分析,再根据给定文法,判断正确性。
此次所写程序是以词法分析器为基础编写的,由于代码量的关系,我们只考虑以下输入为合法:数字自定义变量+ * ()$作为句尾结束符。
其它符号都判定为非法。
二、程序结构描述:词法分析器:class wordtree;类,内容为字典树的创建,插入和搜索。
char gettype(char ch):类型处理代入字串首字母ch,分析字串类型后完整读入字串,输出分析结果。
因读取过程会多读入一个字母,所以函数返回该字母进行下一次分析。
bool isnumber(char str[]):判断是否数字代入完整“数字串”str,判断是否合法数字,若为真返回1,否则返回0。
bool isoperator(char str[]):判断是否关键字代入完整“关键字串”str,搜索字典树判断是否存在,若为存在返回1,否则返回0。
语法分析器:int action(int a,char b):代入当前状态和待插入字符,查找转移状态或归约。
node2 go(int a):代入当前状态,返回归约结果和长度。
void printstack():打印栈。
int push(char b):将符号b插入栈中,并进行归约。
实验三编译原理综合实验报告——(LR(0)语法分析的实现)
m_pTree->SetControlInfo(IDC_TREE1, RESIZE_BOTH);
m_pTree->SetControlInfo(IDOK, ANCHORE_BOTTOM | ANCHORE_RIGHT);
void CAnalyzeDlg::OnOK()
{
// TODO: Add extra validation here
//CDialog::OnOK();
}
void CAnalyzeDlg::OnCancel()
{
// TODO: Add extra cleanup here
六、实验原理、数据(程序)记录
(一)实验原理:
利用LR(k)类分析算法的四个步骤,分别实现"移进"、"归约"、"成功"、"报错"的分析能力。同时采用相应的数据结构实现分析表的描述。
(二)程序框架:
#include "stdafx.h"
#include "GoData.h"
GoData::GoData()
assert(j != -1);
out.WriteString(GetStepInfo(iStep, Status, Symbol, m_input.Right(m_input.GetLength() - iPos), ToDo, j));
for(i = 0; i < m_g.GetPrecept(ToDo.two).GetRight().length(); i++)
编译原理报告二 LR分析器
LR分析器一、目的和要求通过设计、编制、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析方法。
1、选择最有代表性的语法分析方法,如LL(1) 语法分析程序、算符优先分析程序和LR 分析分析程序,并至少完成两个题目。
2、选择对各种常见程序语言都用的语法结构,如赋值语句(尤指表达式)作为分析对象,并且与所选语法分析方法要比较贴切。
⑴实验前的准备按实验的目的和要求,编写语法分析程序,同时考虑相应的数据结构。
⑵调试调试例子应包括符合语法规则的算术表达式,以及分析程序能够判别的若干错例。
⑶输出对于所输入的算术表达式,不论对错,都应有明确的信息告诉外界。
⑷扩充有余力的同学,可适当扩大分析对象。
譬如:①算术表达式中变量名可以是一般标识符,还可含一般常数、数组元素、函数调用等等。
②除算术表达式外,还可扩充分析布尔、字符、位等不同类型的各种表达式。
③加强语法检查,尽量多和确切地指出各种错误。
⑸编写上机实习报告。
二、背景知识※自下而上分析技术-LR(K)方法LR(K)方法是一种自下而上的语法分析方法,是当前最广义的无回溯的“移进- 归约”方法。
它根据栈中的符号串和向前查看的k(k 0)个输入符号,就能唯一确定分析器的动作是移进还是归约,以及用哪个产生式进行归约。
优点:文法适用范围广;识别效率高;查错能力强;可自动构造。
逻辑组成:总控程序+LR分析表LR分析器的结构:一个LR分析器实际是一个带先进后出存储器(栈)的确定下推自动机,它由一个输入串、一个下推栈和一个带有分析表的总控程序组成。
栈中存放着由“历史”和“展望”材料抽象而来的各种“状态”。
任何时候,栈顶的状态都代表了整个的历史和已推测出的展望。
为了有助于明确归约手续,我们把已归约出的文法符号串也同时放进栈里。
LR分析器的每一动作都由栈顶状态和当前输入符号所唯一确定。
LR分析器模型图分析器的任何一次移动都是根据栈顶状态S m和当前输入符号a i,去查看ACTION表并执行ACTION(S m,a i)规定的动作,直至分析成功或失败。
(完整word版)编译原理报告二LR分析器
LR分析器一、目的和要求通过设计、编制、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析方法。
1、选择最有代表性的语法分析方法,如LL(1) 语法分析程序、算符优先分析程序和LR分析分析程序,并至少完成两个题目。
2、选择对各种常见程序语言都用的语法结构,如赋值语句(尤指表达式)作为分析对象,并且与所选语法分析方法要比较贴切。
⑴实验前的准备按实验的目的和要求,编写语法分析程序,同时考虑相应的数据结构。
⑵调试调试例子应包括符合语法规则的算术表达式,以及分析程序能够判别的若干错例。
⑶输出对于所输入的算术表达式,不论对错,都应有明确的信息告诉外界。
⑷扩充有余力的同学,可适当扩大分析对象。
譬如:①算术表达式中变量名可以是一般标识符,还可含一般常数、数组元素、函数调用等等。
②除算术表达式外,还可扩充分析布尔、字符、位等不同类型的各种表达式。
③加强语法检查,尽量多和确切地指出各种错误。
⑸编写上机实习报告。
二、背景知识※自下而上分析技术-LR(K)方法LR(K)方法是一种自下而上的语法分析方法,是当前最广义的无回溯的“移进- 归约”方法。
它根据栈中的符号串和向前查看的k(k³0)个输入符号,就能唯一确定分析器的动作是移进还是归约,以及用哪个产生式进行归约。
优点:文法适用范围广;识别效率高;查错能力强;可自动构造。
逻辑组成:总控程序+LR分析表LR分析器的结构:一个LR分析器实际是一个带先进后出存储器(栈)的确定下推自动机,它由一个输入串、一个下推栈和一个带有分析表的总控程序组成。
栈中存放着由“历史”和“展望”材料抽象而来的各种“状态”。
任何时候,栈顶的状态都代表了整个的历史和已推测出的展望。
为了有助于明确归约手续,我们把已归约出的文法符号串也同时放进栈里。
LR分析器的每一动作都由栈顶状态和当前输入符号所唯一确定。
LR分析器模型图分析器的任何一次移动都是根据栈顶状态S m和当前输入符号a i,去查看ACTION表并执行ACTION (S m,a i)规定的动作,直至分析成功或失败。
编译原理实验报告LR(1)分析法
河南工业大学实验报告课程编译原理实验名称实验四LR(1)分析法一.实验目的1.掌握LR(1)分析法的基本原理;2.掌握LR(1)分析表的构造方法;3.掌握LR(1)驱动程序的构造方法。
二.实验内容及要求根据某一文法编制调试LR(1)分析程序,以便对任意输入的符号串进行分析。
本次实验的目的主要是加深对LR(1)分析法的理解。
对下列文法,用LR(1)分析法对任意输入的符号串进行分析:(0)E->S(1)S->BB(2)B->aB(3)B->b程序输入一以#结束的符号串(包括a、b、#),如:abb#。
输出过程如下:步骤状态栈符号栈输入串ACTION GOTO1 0 # abb# S3... ... ... ... ... ...三.实验过程及结果(说明:实验结果可以是运行画面的抓屏,抓屏图片要尽可能的小。
)实验代码:#include<stdio.h>#include<string.h>char *action[10][3]={"S3#","S4#",NULL, /*ACTION表*/ NULL,NULL,"acc","S6#","S7#",NULL,"S3#","S4#",NULL,"r3#","r3#",NULL,NULL,NULL,"r1#","S6#","S7#",NULL,NULL,NULL,"r3#","r2#","r2#",NULL,NULL,NULL,"r2#"};int goto1[10][2]={1,2, /*GOTO表*/0,0,0,5,0,8,0,0,0,0,0,9,0,0,0,0,0,0};char vt[3]={'a','b','#'}; /*存放非终结符*/ char vn[2]={'S','B'}; /*存放终结符*/ char *LR[4]={"E->S#","S->BB#","B->aB#","B->b#"};/*存放产生式*/int a[10];char b[10],c[10],c1;int top1,top2,top3,top,m,n;void main(){int g,h,i,j,k,l,p,y,z,count;char x,copy[10],copy1[10];top1=0;top2=0;top3=0;top=0;a[0]=0;y=a[0];b[0]='#';count=0;z=0;printf("请输入表达式\n");/*输出状态栈、输出符号栈、输出输入串*/do{scanf("%c",&c1);c[top3]=c1;top3=top3+1;}while(c1!='#');printf("步骤\t状态栈\t\t符号栈\t\t输入串\t\tACTION\tGOTO\n"); do{y=z;m=0;n=0; /*y,z指向状态栈栈顶*/ g=top;j=0;k=0;x=c[top];count++;printf("%d\t",count);while(m<=top1){ /*输出状态栈*/printf("%d",a[m]);m=m+1;}printf("\t\t");while(n<=top2){ /*输出符号栈*/printf("%c",b[n]);n=n+1;}printf("\t\t");while(g<=top3){ /*输出输入串*/ printf("%c",c[g]);g=g+1;}printf("\t\t");while(x!=vt[j]&&j<=2) j++;if(j==2&&x!=vt[j]){printf("error\n");return;}if(action[y][j]==NULL){printf("error\n");return;}elsestrcpy(copy,action[y][j]);if(copy[0]=='S'){ /*处理移进*/ z=copy[1]-'0';top1=top1+1;top2=top2+1;a[top1]=z;b[top2]=x;i=0;while(copy[i]!='#'){printf("%c",copy[i]);i++;}printf("\n");}if(copy[0]=='r'){ /*处理归约*/ i=0;while(copy[i]!='#'){printf("%c",copy[i]);i++;}h=copy[1]-'0';strcpy(copy1,LR[h]);while(copy1[0]!=vn[k]) k++;l=strlen(LR[h])-4;top1=top1-l+1;top2=top2-l+1;y=a[top1-1];a[top1]=p;b[top2]=copy1[0];z=p;printf("\t");printf("%d\n",p);} }while(action[y][j]!="acc");printf("acc\n");getchar();}截屏如下:四.实验中的问题及心得同前面一样。
编译原理语法分析器实验报告
西安邮电大学编译原理实验报告学院名称:计算机学院****:***实验名称:语法分析器的设计与实现班级:计科1405班学号:04141152时间:2017年5月12日一.实验目的1.熟悉语法分析的过程2.理解相关文法分析的步骤3.熟悉First集和Follow集的生成二.实验要求对于给定的文法,试编写调试一个语法分析程序:要求和提示:1)可选择一种你感兴趣的语法分析方法(LL(1)、算符优先、递归下降、SLR(1)等)作为编制语法分析程序的依据。
2)对于所选定的分析方法,如有需要,应选择一种合适的数据结构,以构造所给文法的机内表示。
3)能进行分析过程模拟。
如输入一个句子,能输出与句子对应的语法树,能对语法树生成过程进行模拟;能够输出分析过程每一步符号栈的变化情况。
设计一个由给定文法生成First集和Follow集并进行简化的算法动态模拟三.实验内容1.文法:E->TE’E’->+TE’|εT->FT’T’->*FT’|εF->(E)|i:2.程序描述(LL(1)文法)本程序是基于已构建好的某一个语法的预测分析表来对用户的输入字符串进行分析,判断输入的字符串是否属于该文法的句子。
基本实现思想:接收用户输入的字符串(字符串以“#”表示结束)后,对用做分析栈的一维数组和存放分析表的二维数组进行初始化。
然后取出分析栈的栈顶字符,判断是否为终结符,若为终结符则判断是否为“#”且与当前输入符号一样,若是则语法分析结束,输入的字符串为文法的一个句子,否则出错若不为“#”且与当前输入符号一样则将栈顶符号出栈,当前输入符号从输入字符串中除去,进入下一个字符的分析。
若不为“#”且不与当前输入符号一样,则出错。
3.判断是否LL(1)文法要判断是否为LL(1)文法,需要输入的文法G有如下要求:具有相同左部的规则的SELECT集两两不相交,即:SELECT(A→?)∩SELECT(A→?)= ?如果输入的文法都符合以上的要求,则该文法可以用LL(1)方法分析。
编译原理语法分析器实验报告
编译原理语法分析器实验报告西安邮电大学编译原理实验报告学院名称:计算机学院****:***实验名称:语法分析器的设计与实现班级:计科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("****分析失败了****");}}}。
编译原理 LR分析法实验报告
实验五、LR分析法实验报告计算机与信息技术学院程序功能描述通过设计、编写和构造LR(0)项目集规范簇和LR 分析表、对给定的符号串进行LR 分析的程序,了解构造LR(0)分析表的步骤,对文法的要求,能够从文法G 出发生成LR(0)分析表,并对给定的符号串进行分析。
要求以表格或图形的方式实现。
G[E]:E→aA∣bBA→cA∣dB→cB∣d设计要求:(1)构造LR(0)项目集规范簇;要求输入LR(0)文法时,可以直接输入,也可以读取文件,并能够以表格的形式输出项目集规范簇集识别活前缀的有穷自动机(2)构造LR(0)分析表。
要求要求输入LR(0)文法时,可以直接输入,也可以读取文件;输出项目集规范簇,可以调用前一处理部分的结果,输出为LR(0)分析表(3)LR(0)分析过程【移进、归约、接受、报错】的实现。
要求调用前一部分处理结果的分析表,输入一个符号串,依据LR(0)分析表输出与句子对应的语法树,或直接以表格形式输出分析过程。
主要数据结构描述程序结构描述1.首先要求用户输入规则,并保存,分析出规则的数目,规则里的非终结符号和终结符号等信息,为下一步分析备用。
2.根据产生式构造分析表,首先分析每个状态里有哪些产生式,逐步将状态构造完整,最后的规约状态数应该等于产生式的个数。
3.在构造状态的时候,首先将所有的内容均填为出错情况,在每一步状态转换时可以将移进项目填进action表中,对于最后的规约项目,则再用规约覆盖掉之前填的移进。
4.要求用户输入分析串,并保存在输入序列数组中。
5.每一步根据当前的状态栈栈顶状态和输入符号查分析表,若是移进,则直接将符号和相应的状态添进栈中,否则弹出与产生式右部相同个数的字符和状态,并用剩下的状态和产生式的左部在goto表中进行查找,将非终结符和得到的状态压入两个栈内。
6.无论是规约还是移进都要输出当前三个栈内保存内容的情况。
7.如果碰到acc则输出accept,若碰到error则输出error,否则则继续进行规约和移进,不进行结果输出,直至输出接受或出错。
编译原理实验报告——实验三 语法分析分析器
//判断文法是否合法
if(st[i][j]>='A'&&st[i][j]<='Z') { if(st[i][j+1]>='A'&&st[i][j+1]<='Z') { printf("不是算符文法!\n"); exit(-1); } } } } for(i=0;i<r;i++) { for(j=0;st[i][j]!='\0';j++) { if((st[i][j]<'A'||st[i][j]>'Z')&&st[i][j]!='-'&&st[i][j]!='>'&&st[i][j]!='|') lable[k++]=st[i][j]; } } lable[k]='#'; lable[k+1]='\0'; table();
return六实验者自评主要从实验态度方法效果上给一个客观公正的自我评价这次实验编写了两个词法分析方法的程序但是在ll1分析器的编写中我只达到了最低要求就是自己手动输入的select集first集follow集然后通过程序将预测分析表构造出来了并且没有做出对输入串的分析
编译原理实验报告
实验名称: 实验类型: 指导教师: 专业班级: 姓 学 名: 号:
first[i][0]=0;
ቤተ መጻሕፍቲ ባይዱ
/*first[i][0]和 last[i][0]分别表示 st[i][0]非终极
编译原理实验——语法分析器报告
组员学号姓名实验名称对各算术表达式进行语法分析实验室实验目的或要求实验目的:1、掌握语法分析器生成工具的使用和了解编译器的设计;2、了解自上而下语法分析器的构造过程;3、能够构造LR分析表,编写由该分析表驱动的语法分析器程序;4、借助语法制导翻译,可在语法分析的同时,完成对语义的翻译;5、借助语法分析,设计一个表达式的判断分析器,即从键盘上输入算术表达式,分析器将显示该表达式的正确与否。
实验原理(算法流程)实验算法流程图如下所示:开始输入表达式表达式保存到数ch第一个元素为)+-*/YCh[i]=’(’i++YNCh[i]=NULLNCh[i]是0~9i++YCh[i]是0~9Ch[i]=+ -*/)N多了+ -*/)Y其他错误NYCh[i]=* /Ni++YCh[i]=+ -*/NY多了+ -*/Ch[i]=+ -NNCh[i]=)Y少了)N错误首部多了) +-*/结束程序界面(效果图)实验结果界面:只选择几个典型的例子进行分析,可进行任意表达式输入。
1)未进行语法分析时的界面;2)输入正确的表达式(1+2)*(6-3)+1进行语法分析时的界面结果;3)输入错误的表达式1*2+(2+3并进行语法分析时的界面结果;程序界面(效果图)4)输入错误的表达式1+(+5+6)并进行语法分析时的界面结果;程序界面(效果图)程序代码 #include "stdafx.h"#include "grammer.h"#include "mfc_语法分析器.h"#include "mfc_语法分析器Dlg.h"int flag;int i,j;int length;CString string;int grammer(CString str){i=0;flag=0;char ch[MAX];length=str.GetLength();strcpy(ch,str);if(length!=0){F(ch);if(flag==0){MessageBox(NULL,"输入表达式符合文法","正确",MB_OK|MB_ICONINFORMATION);}//str=ch;//return flag;}else{MessageBox(NULL,"表达式为空","提示",MB_OK|MB_ICONW ARNING);//MessageBox(NULL,"表达式为空","提示",MB_OK|MB_ICONERROR);return -1;}return flag;}void F(char ch[]){if(ch[0]=='+'){程序代码flag=0;MessageBox(NULL,"输入表达式不符合文法0","错误",MB_OK|MB_ICONERROR); MessageBox(NULL,"开始处多了+","提示",MB_OK|MB_ICONINFORMA TION);flag=1;}elseif(ch[0]=='-'){flag=0;MessageBox(NULL,"输入表达式不符合文法0","错误",MB_OK|MB_ICONERROR);MessageBox(NULL,"开始处多了-","提示",MB_OK|MB_ICONINFORMA TION);flag=1;}elseif(ch[0]=='*'){flag=0;MessageBox(NULL,"输入表达式不符合文法0","错误",MB_OK|MB_ICONERROR);MessageBox(NULL,"开始处多了*","提示",MB_OK|MB_ICONINFORMA TION);flag=1;}elseif(ch[0]=='/'){flag=0;MessageBox(NULL,"输入表达式不符合文法0","错误",MB_OK|MB_ICONERROR);MessageBox(NULL,"开始处多了/","提示",MB_OK|MB_ICONINFORMA TION);flag=1;}elseif(ch[0]==')'){flag=0;MessageBox(NULL,"输入表达式不符合文法0","错误",MB_OK|MB_ICONERROR);MessageBox(NULL,"开始处多了)","提示",MB_OK|MB_ICONINFORMA TION);flag=1;}/*上述为对第一个字符的特殊处理*/elseif(ch[i]!=NULL){if(ch[i]=='('){i++;F(ch);程序代码if(ch[i]!=')'){if(flag==0){MessageBox(NULL,"输入表达式不符合文法1","错误",MB_OK|MB_ICONERROR);MessageBox(NULL,"少了')'","提示",MB_OK|MB_ICONINFORMATION);}flag=1;}else{i++;if(ch[i]!=NULL)T(ch);}}elseif(ch[i]<='9'&&ch[i]>='0'){while(ch[i]<='9'&&ch[i]>='0')i++;if(ch[i]!=NULL)T(ch);}else{if(flag==0){if(ch[i]!=NULL&&ch[i]!=')'){MessageBox(NULL,"输入表达式不符合文法2.1","错误",MB_OK|MB_ICONERROR);if(ch[i]==' ') MessageBox(NULL,"含有空格","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i]=='+') {MessageBox(NULL,"多了'+'号","提示",MB_OK|MB_ICONINFORMA TION);}else if(ch[i]=='-') MessageBox(NULL,"多了'-'号","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i]=='*') MessageBox(NULL,"多了'*'号","提示",MB_OK|MB_ICONINFORMA TION);程序代码else if(ch[i]=='/') MessageBox(NULL,"多了'/'号","提示",MB_OK|MB_ICONINFORMA TION);}else if(ch[i]==NULL){MessageBox(NULL,"输入表达式不符合文法2.2","错误",MB_OK|MB_ICONERROR);if(ch[i-1]==' ') MessageBox(NULL,"含有空格","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i-1]=='+') MessageBox(NULL,"多了最后的'+'号","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i-1]=='-') MessageBox(NULL,"多了最后的'-'号","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i-1]=='*') MessageBox(NULL,"多了最后的'*'号","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i-1]=='/') MessageBox(NULL,"多了最后的'/'号","提示",MB_OK|MB_ICONINFORMA TION);}else if(ch[i]!=NULL&&ch[i]==')'){MessageBox(NULL,"输入表达式不符合文法2.3","错误",MB_OK|MB_ICONERROR);if(ch[i-1]==' ') MessageBox(NULL,"含有空格","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i-1]=='(') MessageBox(NULL,"含有一对空括号","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i-1]=='+') MessageBox(NULL,"多了最后的'+'号","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i-1]=='-') MessageBox(NULL,"多了最后的'-'号","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i-1]=='*') MessageBox(NULL,"多了最后的'*'号","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i-1]=='/') MessageBox(NULL,"多了最后的'/'号","提示",MB_OK|MB_ICONINFORMA TION);}}flag=1;}}}void T(char ch[]){if(ch[i]=='*'||ch[i]=='/')程序代码{i++;if(ch[i]!=NULL&&ch[i]!='+'&&ch[i]!='-'&&ch[i]!='*'&&ch[i]!='/')F(ch);else{if(flag==0){MessageBox(NULL,"输入表达式不符合文法3","错误",MB_OK|MB_ICONERROR);if(ch[i]==' ') MessageBox(NULL,"含有空格","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i]=='+') MessageBox(NULL,"多了'+'号","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i]=='-') MessageBox(NULL,"多了'-'号","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i]=='*') MessageBox(NULL,"多了'*'号","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i]=='/') MessageBox(NULL,"多了'/'号","提示",MB_OK|MB_ICONINFORMA TION);}flag=1;}}elseE(ch);}void E(char ch[]){if(ch[i]=='+'||ch[i]=='-'){i++;if(ch[i]!=NULL&&ch[i]!='+'&&ch[i]!='-'&&ch[i]!='*'&&ch[i]!='/')F(ch);else{if(flag==0){if(ch[i]!=NULL){MessageBox(NULL,"输入表达式不符合文法4.1","错误",MB_OK|MB_ICONERROR);if(ch[i]==' ') MessageBox(NULL,"含有空格","提示",MB_OK|MB_ICONINFORMA TION);程序代码else if(ch[i]=='+') MessageBox(NULL,"多了'+'号","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i]=='-') MessageBox(NULL,"多了'-'号","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i]=='*') MessageBox(NULL,"多了'*'号","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i]=='/') MessageBox(NULL,"多了'/'号","提示",MB_OK|MB_ICONINFORMA TION);}else if(ch[i]==NULL){MessageBox(NULL,"输入表达式不符合文法4.2","错误",MB_OK|MB_ICONERROR);if(ch[i-1]==' ') MessageBox(NULL,"含有空格","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i-1]=='+') MessageBox(NULL,"多了最后的'+'号","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i-1]=='-') MessageBox(NULL,"多了最后的'-'号","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i-1]=='*') MessageBox(NULL,"多了最后的'*'号","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i-1]=='/') MessageBox(NULL,"多了最后的'/'号","提示",MB_OK|MB_ICONINFORMA TION);}}flag=1;}}else if(ch[i]!=')'){if(flag==0){MessageBox(NULL,"输入表达式不符合文法5","错误",MB_OK|MB_ICONERROR);if(ch[i]=='('&&ch[i+2]==')') MessageBox(NULL,"含有一对多余的括号","提示",MB_OK|MB_ICONINFORMA TION);else MessageBox(NULL,"其他类型的错误","提示",MB_OK|MB_ICONINFORMA TION);}flag=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
的声明和赋值;
●允许声明和使用一个过程函数,比如:。
编译原理语法分析实验报告
编译原理语法分析实验报告一、实验目的本实验主要目的是学习和掌握编译原理中的语法分析方法,通过实验了解和实践LR(1)分析器的实现过程,并对比不同的文法对语法分析的影响。
二、实验内容1.实现一个LR(1)的语法分析器2.使用不同的文法进行语法分析3.对比不同文法对语法分析的影响三、实验原理1.背景知识LR(1)分析器是一种自底向上(bottom-up)的语法分析方法。
它使用一个分析栈(stack)和一个输入缓冲区(input buffer)来处理输入文本,并通过移进(shift)和规约(reduce)操作进行语法分析。
2.实验步骤1)构建文法的LR(1)分析表2)读取输入文本3)初始化分析栈和输入缓冲区4)根据分析表进行移进或规约操作,直至分析过程结束四、实验过程与结果1.实验环境本实验使用Python语言进行实现,使用了语法分析库ply来辅助实验。
2.实验步骤1)构建文法的LR(1)分析表通过给定的文法,根据LR(1)分析表的构造算法,构建出分析表。
2)实现LR(1)分析器使用Python语言实现LR(1)分析器,包括读取输入文本、初始化分析栈和输入缓冲区、根据分析表进行移进或规约操作等功能。
3)使用不同的文法进行语法分析选择不同的文法对编写的LR(1)分析器进行测试,观察语法分析的结果。
3.实验结果通过不同的测试案例,实验结果表明编写的LR(1)分析器能够正确地进行语法分析,能够识别出输入文本是否符合给定文法。
五、实验分析与总结1.实验分析本实验通过实现LR(1)分析器,对不同文法进行语法分析,通过实验结果可以观察到不同文法对语法分析的影响。
2.实验总结本实验主要学习和掌握了编译原理中的语法分析方法,了解了LR(1)分析器的实现过程,并通过实验提高了对语法分析的理解。
六、实验心得通过本次实验,我深入学习了编译原理中的语法分析方法,了解了LR(1)分析器的实现过程。
在实验过程中,我遇到了一些问题,但通过查阅资料和请教老师,最终解决了问题,并完成了实验。
编译原理 实验报告实验三 语法分析(LR分析程序)
华北水利水电学院编译原理实验报告2012~2013学年第一学期2011 级计算机科学与技术专业班级:2011179 学号:2011179 姓名:一、实验题目:语法分析(LR分析程序)(1)选择最有代表性的语法分析方法LR分析法;(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三、根据以上文法构造出的LR(1)分析表为:四、程序源代using System;using System.Text;using System.IO;namespace Syntax_Analyzer{class Syntax{StreamReader myStreamReader;int t;int[] lengh;int l =0;string[] grammar;int s=0;string[] Word;int w=0;int[] wordNum ;int n =0;int[,] LR;public Syntax(){lengh = new int[7];grammar=new string[7];Word=new string[100];wordNum = new int[100];LR=new int[30,30];}public void analyzer(){//读入grammarSyntax myTextRead=new Syntax();Console.WriteLine("-----------------------------语法分析开始---------------------------------\n");//***************************//循环读取文法//***************************string strStart;strStart="grammar.txt";myTextRead.myStreamReader=new StreamReader(strStart);string strBufferStart;int uu=0;do{strBufferStart =myTextRead.myStreamReader.ReadLine();if(strBufferStart==null)break;foreach (String subString in strBufferStart.Split()){grammar[uu]=subString; //每行文法存入grammar[]uu++;}}while (strBufferStart!=null);myTextRead.myStreamReader.Close();//***************************//循环读取lengh//***************************strStart="lengh.txt";myTextRead.myStreamReader=new StreamReader(strStart);uu=0;do{strBufferStart =myTextRead.myStreamReader.ReadLine();if(strBufferStart==null)break;foreach (String subString in strBufferStart.Split()){lengh[uu]=Convert.ToInt32(subString); //每行文法存入grammar[]uu++;}}while (strBufferStart!=null);myTextRead.myStreamReader.Close();//****************************// 读入文件,进行语法分析////****************************string strReadFile;strReadFile="input.txt";myTextRead.myStreamReader=new StreamReader(strReadFile);string strBufferText;int wid =0;Console.WriteLine("分析读入程序(记号ID):\n");do{strBufferText =myTextRead.myStreamReader.ReadLine();if(strBufferText==null)break;foreach (String subString in strBufferText.Split()){if(subString!=""){int ll;if(subString!=null){ll= subString.Length; //每一个长度}else{break;}int a=ll+1;char[] b = new char[a];StringReader sr = new StringReader(subString);sr.Read(b, 0, ll); //把substring 读到char[]数组里int sort=(int)b[0];// word[i] 和wordNum[i]对应//先识别出一整个串,再根据开头识别是数字还是字母Word[wid]=subString;if(subString.Equals("+")){wordNum[wid]=0;}else{if(subString.Equals("*")){wordNum[wid]=1;}else{if(subString.Equals("(")){wordNum[wid]=2;}else{if(subString.Equals(")")){wordNum[wid]=3;}else{if(subString.Equals("i")){wordNum[wid]=4;}}}}}Console.Write(subString+"("+wordNum[wid]+")"+" ");wid++;}}Console.WriteLine("\n");}while (strBufferText!=null);wordNum[wid]=5;myTextRead.myStreamReader.Close();//*********************************//读入LR分析表////***********************************string strLR;strLR="LR-table.txt";myTextRead.myStreamReader=new StreamReader(strLR);string strBufferLR;int pp=0;do{strBufferLR =myTextRead.myStreamReader.ReadLine();if(strBufferLR==null)break;else{int j=0;foreach (String subString in strBufferLR.Split()){if(subString!=null){int lllr=Convert.ToInt16(subString);LR[pp,j]=lllr; //把行与列读入数组j++;}}}pp++;}while (strBufferLR!=null);myTextRead.myStreamReader.Close();int[] state = new int[100];string[] symbol =new string[100];state[0]=0;symbol[0]="#";int p1=0;int p2=0;Console.WriteLine("\n按文法规则归约顺序如下:\n");//***************//归约算法//***************while(true){int j,k;j=state[p2];k=wordNum[p1];t=LR[j,k]; //当出现t为的时候if(t==0){//错误类型string error = "" ;if (k == 0)error = "+";elseif (k == 1)error = "*";elseif (k == 2)error = "(";elseif (k == 3)error = ")";elseif (k == 4)error = "i";elseerror = " 其它错误!";Console.WriteLine("\n检测结果:");Console.WriteLine("代码中存在语法错误");Console.WriteLine("错误状况:错误状态编号为"+j+" 读头下符号为"+error);break;}else{if(t==-100) //-100为达到接受状态{Console.WriteLine("\n");Console.WriteLine("\n检测结果:");Console.WriteLine("代码通过语法检测");break;}if(t<0&&t!=-100) //归约{string m=grammar[-t];Console.Write(m+" "); //输出开始符int length=lengh[-t];p2=p2-(length-1);Search mySearch=new Search();int right=mySearch.search(m);if(right==0){Console.WriteLine("\n");Console.WriteLine("代码中有语法错误");break;}int a=state[p2-1];int LRresult= LR[a,right];state[p2]=LRresult;symbol[p2]=m;}if(t>0){p2=p2+1;state[p2]=t;symbol[p2]=Convert.ToString(wordNum[p1]);p1=p1+1;}}}myTextRead.myStreamReader.Close();Console.WriteLine("-----------------------------语法分析结束---------------------------------\n");Console.Read();}}class Search{public int search(string x){string[] mysymbol=new string[3];mysymbol[0]="E";mysymbol[1]="T";mysymbol[2]="F";int r = 0;for(int s=0;s<=2;s++){if(mysymbol[s].Equals(x))r=s+6 ;}return r;}}}五、测试结果输入”( i + i ) * i”字符串,分析如下图所示输入”i + i ”字符串,分析如下图所示六、小结(包括收获、心得体会、存在的问题及解决问题的方法、建议等)本次实验是LR分析法,LR分析法是一种有效的自上而下分析技术,在自左向右扫描输入串时就能发现其中的任何错误。
编译原理-LR语法分析器的控制程序实验报告
编译原理实验报告学号姓名时间专业班级实验题目:LR语法分析器的控制程序实验目的:手工模拟控制程序计算,对源程序进行LR 语法分析主要是分析表的构造实验内容与步骤:1.将要进行LR 语法分析的源程序和LR 语法分析器控制程序放在同一文件夹中。
2.用 C 语言编写 LR 语法分析器控制程序,程序代码如下:#include <fstream.h>#include <iostream.h>#include <stdlib.h>#include <string.h>struct code_val{char code;char val[20];};const char *p[]={//产生式"S→ E","E → E+T","E → T","T → T*F","T → F","F → (E)","F → i"};const char TNT[ ]="+*()i#ETF";//LR 分析表列的字符const int M[][9]={//LR 分析表数字化,列字符 +*()i#ETF用数字 012345678 标识。
{ 0, 0, 4, 0, 5,0, 1, 2, 3},//0 表示出错, s4 用 4 表示。
{ 6, 0, 0, 0, 0,99},//Acc 用 99 表示{-2, 7, 0,-2, 0,-2},//r2 用 -2 表示{-4,-4, 0,-4, 0,-4},{ 0, 0, 4, 0, 5, 0, 8, 2, 3},{-6,-6, 0,-6, 0,-6}, { 0, 0,4, 0, 5, 0, 0, 9, 3},{ 0, 0, 4, 0, 5, 0, 0, 0,10},{ 6, 0, 0,11},{-1, 7, 0,-1, 0,-1},{-3,-3, 0,-3, 0,-3},{-5,-5, 0,-5, 0,-5}};int col(char);void main(){//列定位函数原型int state[50]={0};//状态栈初值char symbol[50]={'#'};//符号栈初值int top=0;//栈顶指针初值ofstream cout("par_r.txt");//语法分析结果输出至文件par_r.txtifstream cin("lex_r.txt");// lex_r.txt 存放词法分析结果,语法分析器从该文件输入数据。
北邮编译原理实验 LR语法分析 实验报告
LR语法分析实验报告班级:2010211308 姓名:杨娜学号:10211369一.题目:LR语法分析程序的设计与实现二.设计目的:(1)了解语法分析器的生成工具和编译器的设计。
(2)了解自上而下语法分析器的构造过程。
(3). 理解和掌握LR语法分析方法的基本原理;根据给出的LR)文法,掌握LR分析表的构造及分析过程的实现。
(4)掌握预测分析程序如何使用分析表和栈联合控制实现LR分析。
三.实验内容:编写语法分析程序,实现对算术表达式的语法分析,要求所分析算数表达式由如下的文法产生:E->E+T|E-T|TT->T/F|T*F|FF->i|n|(E)四.实验要求:编写LR语法分析程序,要求如下:(1)构造识别所有活动的DFA(2)构造LR分析表(3)编程实现算法4.3,构造LR分析程序五.算法流程分析程序可分为如下几步:六.算法设计1.数据结构s :文法开始符号line :产生式的个数G[i][0] :产生式的标号Vt[] :终结符Vn[] :非终结符id :项目集编号Prjt *next :指示下一个项目集Prjt[]:存储项目的编号,prjt[0]项目编号的个数Pointafter[] :圆点后的字符,pointafter[0]为字符个数Prjset*actorgo[]:存储出度Pointbefore:圆点前面的字符Form:动态数组下标,同时作为符号的编号Vn[] :非终结符序列Vt[]:终结符序列2.LR分析器由三个部分组成(1)总控程序,也可以称为驱动程序。
对所有的LR分析器总控程序都是相同的。
(2)分析表或分析函数,不同的文法分析表将不同,同一个文法采用的LR分析器不同时,分析表将不同,分析表又可以分为动作表(ACTION)和状态转换(GOTO)表两个部分,它们都可用二维数组表示。
(3)分析栈,包括文法符号栈和相应的状态栈,它们均是先进后出栈。
分析器的动作就是由栈顶状态和当前输入符号所决定。
编译原理-LR语法分析器的控制程序实验报告
编译原理实验报告实验目的:手工模拟控制程序计算,对源程序进行LR 语法分析 主要是分析表的构造实验内容与步骤:1•将要进行LR 语法分析的源程序和LR 语法分析器控制程序放在同一文件夹 中。
2.用C 语言编写LR 语法分析器控制程序,程序代码如下:#in elude <fstream.h> #in clude <iostream.h> #i nclude <stdlib.h> #in clude <stri ng.h> struct code_val{char code;char val[20]; };con st char *p[]={// 产生式"S T E","E T E+T","E T T","T T T*F","T T F","F T (E)","F T i };const char TNT[ ]="+*()i#ETF"; con st int M[][9]={{ 0, 0, 4, 0, 5,0, 1,2, 3}, { 6, 0, 0, 0, 0,99}, {-2, 7, 0,-2, 0,-2}, {-4,-4, 0,-4, 0,-4}, { 0, 0, 4, 0, 5, 0, 8, 2, 3}, {-6,-6, 0,-6, 0,-6},{ 0, 0, 4, 0, 5, 0, 0, 9, 3}, { 0, 0, 4, 0, 5, 0, 0, 0,10}, { 6, 0, 0,11}, {-1,7, 0,-1,0,-1}, {-3,-3, 0,-3, 0,-3}, {-5,-5, 0,-5, 0,-5} };//LR 分析表列的字符//LR 分析表数字化,列字符 +*()i#ETF 用数字012345678标识。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
cout<<"Err in col char>"<<c<<endl;
exit(0);//终止程序运行
}
3.查看生成的文件,对文件中的内容进行分析,更深刻理解LR语法分析的分析过程。
文件:
step状态栈符号栈输入符号
0)0#i
1)05#i*
2)03#F*
3)02#T*
编译原理实验报告
学号
姓名
时间
专业
班级
实验题目:LR语法分析器的控制程序
实验目的:
手工模拟控制程序计算,对源程序进行LR语法分析
主要是分析表的构造
实验内容与步骤:
1.将要进行LR语法分析的源程序和LR语法分析器控制程序放在同一文件夹中。
2.用C语言编写LR语法分析器控制程序,程序代码如下:
#include <>
top=top-(strlen(p[-action])-3);//"→"为汉字,占二字节,故减3。
state[top+1]=M[state[top]][col(p[-action][0])]; //产生式左部符号
symbol[++top]=p[-action][0];
}
else if(action==99){//接受
手工模拟控制程序计算,对源程序进行LR语法分析
通过本次实验,进一步对C语言的知识进行了复习,并编写代码对源程序进行LR语法分析,把其分析后的结果输入并保存到文件中。对LR分析有了更深的理解。LR(0)分析表构造的思想和方法是构造其他LR分析表的基础。
action=M[state[top]][col];
if(action>0 && action!=99){//移进
state[++top]=action;
symbol[top]=;
cin>>>>;//读一单词
}
else if(action < 0){//归约
if(strcmp(p[-action]+3,"ε"))//ε产生式的右部符号串长度为0,无需退栈。
{-3,-3, 0,-3, 0,-3},
{-5,-5, 0,-5, 0,-5}
};
inmain()
{
int state[50]={0};//状态栈初值
char symbol[50]={'#'};//符号栈初值
int top=0;//栈顶指针初值
ofstream cout("");//语法分析结果输出至文件
4)027#T*i
5)0275#T*i+
6)02710#T*F+
7)02#T+
8)01#E+
9)016#E+i
10)0165#E+i#
11)0163#E+F#
12)0169#E+T#
13)01#E#
Acc
分析与体会:
此通过上下文无关文法作为语法分析的基础,配合实例,探讨了编译原理构造中的自上而下语法分析法,并初步完成了语法分析器的实现。
do{
cout<<j++<<')'<<'\t';//输出step,并非必要。
for(i=0;i<=top;i++)cout<<state[i];cout<<'\t';//输出状态栈内容,并非必要。
for(i=0;i<=top;i++)cout<<symbol[i]; //输出符号栈内容,并非必要。
cout<<'\t'<<<<endl;//输出当前输入符号(单词种别),并非必要。
{-4,-4, 0,-4, 0,-4},
{ 0, 0, 4, 0, 5, 0, 8, 2, 3},
{-6,-6, 0,-6, 0,-6},
{ 0, 0, 4, 0, 5, 0, 0, 9, 3},
{ 0, 0, 4, 0, 5, 0, 0, 0,10},
{ 6, 0, 0,11},
{-1, 7, 0,-1, 0,-1},
cout<<'\t'<<"Acc"<<endl;
break;
}
else{//出错
cout<<"Err in main()>"<<action<<endl;
break;
}
}while(1);
}
int col(char c)//将字符+* ()i#ETF分别转换为数字0
{
for(int i=0;i<(int)strlen(TNT);i++)
#include <>
#include <>
#include <>
struct code_val{
char code;char val[20];
};
const char *p[]={//产生式
"S→E","E→E+T","E→T","T→T*F","T→F","F→(E)","F→i"
};
const char TNT[ ]="+*()i#ETF";//LR分析表列的字符
ifstream cin("");//存放词法分析结果,语法分析器从该文件输入数据。
struct code_val t;//结构变量,存放单词二元式。
cin>>>>;//读一单词
int action;
int i,j=0;//输出时使用的计数器,并非必要。
cout<<"step"<<'\t'<<"状态栈"<<'\t'<<"符号栈"<<'\t'<<"输入符号"<<endl;//输出标题并非必要。
const int M[][9]={//LR分析表数字化,列字符+*()i#ETF用数字0标识。
{ 0, 0, 4, 0, 5,0, 1, 2, 3},//0表示出错,s4用4表示。
{ 6, 0, 0, 0, 0,99},//Acc用99表示
{-2, 7, 0,-2, 0,-2},//r2用-2表示