语法分析实验
实验原理ll1分析法

实验原理ll1分析法
LL(1)分析法是一种语法分析方法,是从上到下递归分析的一种方式。
LL指的是“Left to right, leftmost derivation”,表示从左到右、最左派生。
1表示在当前读入符号下,只需要向前看一个符号即可确定使用哪个产生式进行推导。
其核心思想是通过预测分析表来进行语法分析,预测分析表是一个二维数组,横坐标是非终结符号,纵坐标是终结符号。
在分析过程中,根据当前读入的终结符号和栈顶的非终结符号,查找分析表中对应的表项,判断使用哪个产生式进行推导。
如果表项为空,则表示当前输入串不符合语法规则。
LL(1)分析法的优点是实现简单、可自动化,同时可以处理大部分常见的上下文无关文法,且分析的速度较快,适合在语法分析器中应用。
缺点是只能处理LL(1)文法,对于LL(k)文法或其他类型的文法稍显局限。
语法法分析实验报告

一、实验目的1. 理解语法分析的基本概念和原理。
2. 掌握语法分析器的构建方法。
3. 培养实际操作能力,提高编程水平。
二、实验环境1. 操作系统:Windows 102. 编程语言:Python3.83. 开发工具:PyCharm三、实验内容1. 语法分析概述2. 词法分析3. 语法分析4. 实验实现四、实验步骤1. 语法分析概述(1)了解语法分析的定义、作用和意义。
(2)掌握语法分析的基本原理和流程。
2. 词法分析(1)编写词法分析器代码,将源代码分解成单词序列。
(2)实现词法分析器的各个功能,如:识别标识符、关键字、运算符等。
3. 语法分析(1)设计语法分析器,将单词序列转换为抽象语法树(AST)。
(2)实现语法分析器的各个功能,如:识别表达式、语句、函数等。
4. 实验实现(1)创建Python项目,导入相关库。
(2)编写词法分析器代码,实现单词序列的分解。
(3)编写语法分析器代码,实现抽象语法树的构建。
(4)测试语法分析器,验证其正确性。
五、实验结果与分析1. 词法分析结果实验中,我们成功地将源代码分解成单词序列,包括标识符、关键字、运算符等。
词法分析器的输出结果如下:```identifier: akeyword: intoperator: +identifier: boperator: =integer: 5```2. 语法分析结果通过语法分析器,我们将单词序列转换成抽象语法树。
以下是一个示例的抽象语法树:```Program├── Declaration│ ├── Type│ │ ├── Identifier│ │ └── Integer│ └── Identifier│ └── a└── Statement├── Expression│ ├── Identifier│ └── a└── Operator└── =└── Expression├── Identifier└── b└── Integer└── 5```从实验结果可以看出,我们的语法分析器能够正确地将源代码转换为抽象语法树。
《编译原理》实验3_PL0语法分析

《编译原理》实验3_PL0语法分析编译原理是计算机科学中的重要课程,它涉及了程序语言的设计、编译器的构建以及编程语言的解释和执行等方面。
在编译原理的实验部分中,PL0语法分析是一个重要的实验项目。
PL0语法分析是基于PL0语言的语法规则来构建语法分析器,实现对PL0代码的分析和解释。
在这个实验中,我们将完成PL0语法分析器的设计和实现,并对其进行测试。
首先,我们需要了解PL0语言的语法规则。
PL0语言是一种过程型语言,类似于Pascal语言。
它有一套严格的语法规则,包括声明语句、赋值语句、条件语句、循环语句等。
我们需要先从PL0语言文法中提取出规则,然后将其转化为一个语法分析器。
接下来,我们需要设计和实现语法分析器。
语法分析器的主要任务是根据PL0语言的文法规则来分析和解释PL0代码。
我们可以选择使用自顶向下的语法分析方法,如递归下降分析法。
递归下降分析法是一种简单直观的语法分析方法,它通过递归调用子程序来分析和解释代码。
在设计语法分析器时,我们需要根据PL0语言的文法规则来设计相应的文法产生式和语法分析程序。
文法产生式描述了PL0语言的句子结构,它由非终结符和终结符组成,并用箭头“->”来表示产生关系。
语法分析程序则是根据产生式来解释和分析代码。
最后,我们需要编写测试代码来验证语法分析器的正确性。
测试代码应该包含PL0语言的各种语法结构和语法错误,从而验证语法分析器在不同情况下的正确性和鲁棒性。
通过完成这个实验项目,我们能够深入了解编译原理中的语法分析技术,并提升我们的编程能力和问题解决能力。
同时,我们也能够加深对PL0语言的理解,为以后的编程工作打下坚实的基础。
实验5LL语法分析程序的设计与实现

实验5LL语法分析程序的设计与实现引言:LL语法分析器是一种自顶向下的语法分析方法,它从语法开始符号开始,通过向前看的一个或者多个输入符号预测产生式的选择,并且通过栈来保存未处理的非终结符。
本实验将设计并实现一个LL语法分析器,包括设计程序的数据结构,算法以及实现细节,并进行相应的测试。
设计概述:1. 实验环境:本实验采用Java编程语言进行实现。
2.数据结构:本实验的数据结构包括文法集合、FIRST集合和FOLLOW 集合、预测分析表等。
3.算法:a)根据给定的文法,构建文法集合和FIRST集合和FOLLOW集合。
b)根据构建的文法集合、FIRST集合和FOLLOW集合,构建预测分析表。
c)根据预测分析表,进行语法分析,实现LL语法分析器。
4.实现细节:本实验实现的LL语法分析器具备错误恢复和语法错误报告的功能。
具体设计与实现:1.构建文法集合:读取给定的文法文件,将每条文法规则分解成产生式的推导式,构建文法集合。
2.构建FIRST集合和FOLLOW集合:遍历文法集合,根据FIRST集合和FOLLOW集合的定义,递归计算每个非终结符的FIRST集合和FOLLOW集合。
3.构建预测分析表:根据构建的文法集合、FIRST集合和FOLLOW集合,生成预测分析表。
4.语法分析过程:根据预测分析表,进行语法分析。
具体过程如下:a)初始化分析栈和输入串,将开始符号和输入串的结束符号入栈;b)重复以下步骤:i)如果栈顶元素是终结符且与输入符号相同,则将栈顶元素出栈,输入串指针前移;ii) 如果栈顶元素是非终结符,则根据预测分析表,选择产生式进行推导,并将该产生式右侧的符号逆序入栈;iii) 如果栈顶元素是结束符号且输入指针也指向结束符号,分析成功;iv) 如果输入指针指向错误的终结符,进行错误恢复处理;v)如果预测分析表中没有对应的产生式,进行错误恢复处理。
5.错误恢复:错误恢复是语法分析器中一个重要的功能,它通过跳过错误符号,继续进行下一步分析来恢复错误。
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语言进行语法分析。
实验5---语法分析器(自下而上):LR(1)分析法

实验5---语法分析器(自下而上):LR(1)分析法一、实验目的构造LR(1)分析程序,利用它进行语法分析,判断给出的符号串是否为该文法识别的句子,了解LR(K)分析方法是严格的从左向右扫描,和自底向上的语法分析方法。
二、实验内容程序输入/输出示例(以下仅供参考):对下列文法,用LR(1)分析法对任意输入的符号串进行分析:(1)E->E+T(2)E->E—T(3)T->T*F(4)T->T/F(5)F-> (E)(6)F->i输出的格式如下:(1)LR(1)分析程序,编制人:姓名,学号,班级(2)输入一个以#结束的符号串(包括+—*/()i#):在此位置输入符号串(3)输出过程如下:3.对学有余力的同学,测试用的表达式事先放在文本文件中,一行存放一个表达式,同时以分号分割。
同时将预期的输出结果写在另一个文本文件中,以便和输出进行对照。
三、实验方法1.实验采用C++程序语言进行设计,文法写入程序中,用户可以自定义输入语句;2.实验开发工具为DEV C++。
四、实验步骤1.定义LR(1)分析法实验设计思想及算法①若ACTION[sm , ai] = s则将s移进状态栈,并把输入符号加入符号栈,则三元式变成为:(s0s1…sm s , #X1X2…Xm ai , ai+1…an#);②若ACTION[sm , ai] = rj则将第j个产生式A->β进行归约。
此时三元式变为(s0s1…sm-r s , #X1X2…Xm-rA , aiai+1…an#);③若ACTION[sm , ai]为“接收”,则三元式不再变化,变化过程终止,宣布分析成功;④若ACTION[sm , ai]为“报错”,则三元式的变化过程终止,报告错误。
2.定义语法构造的代码,与主代码分离,写为头文件LR.h。
3.编写主程序利用上文描述算法实现本实验要求。
五、实验结果1. 实验文法为程序既定的文法,写在头文件LR.h中,运行程序,用户可以自由输入测试语句。
实验三 LR(1)分析表语法分析报告

学生实验报告(理工类)课程名称:编译原理专业班级:08计算机科学与技术(单)本所属院部:信息技术学院指导教师:洪蕾20 10 ——20 11 学年第二学期金陵科技学院教务处制实验报告书写要求实验报告原则上要求学生手写,要求书写工整。
若因课程特点需打印的,要遵照以下字体、字号、间距等的具体要求。
纸张一律采用A4的纸张。
实验报告书写说明实验报告中一至四项内容为必填项,包括实验目的和要求;实验仪器和设备;实验内容与过程;实验结果与分析。
各院部可根据学科特点和实验具体要求增加项目。
填写注意事项(1)细致观察,及时、准确、如实记录。
(2)准确说明,层次清晰。
(3)尽量采用专用术语来说明事物。
(4)外文、符号、公式要准确,应使用统一规定的名词和符号。
(5)应独立完成实验报告的书写,严禁抄袭、复印,一经发现,以零分论处。
实验报告批改说明实验报告的批改要及时、认真、仔细,一律用红色笔批改。
实验报告的批改成绩采用百分制,具体评分标准由各院部自行制定。
实验报告装订要求实验批改完毕后,任课老师将每门课程的每个实验项目的实验报告以自然班为单位、按学号升序排列,装订成册,并附上一份该门课程的实验大纲。
实验项目名称: LR(1)分析表语法分析实验学时: 6 同组学生姓名:无实验地点: B513 实验日期: 2011.4.7/4.21 实验成绩:批改教师:批改时间:一、实验目的和要求语法分析主要目的是按照程序语言的语法规则,从由词法分析输出的源程序符号串中识别出各类语法成分,同时进行语法检查,为语义分析和代码生成作准备.语法分析程序在分析过程中检查符号串是否为该程序的句子.若是则输出该句子的分析树,否则就表示源程序存在语法错误,并报告错误的性质与位置.二、实验仪器和设备主机一台:有Visual Studio 2005工具三、实验过程说明:此程序共有两个类,Lexical进行词法分析,Syntax进行语法分析.对于语法分析,采用LR(1)分析法,判断程序是否满足规定的结构.1:LR-table.txt:存放分析表,其中正数表示移进,负数表示归约,100表示接受状态,0表示不操作。
语法分析器实验报告

词法分析器实验报告实验名称:语法分析器实验内容:利用LL(1)或LR(1)分析语句语法,判断其是否符合可识别语法。
学会根据状态变化、first、follow或归约转移思想构造状态分析表,利用堆栈对当前内容进行有效判断实验设计:1.实现功能可对一段包含加减乘除括号的赋值语句进行语法分析,其必须以$为终结符,语句间以;隔离,判断其是否符合语法规则,依次输出判断过程中所用到的产生式,并输出最终结论,若有错误可以报错并提示错误所在行数及原因2.实验步骤3.算法与数据结构a)LLtable:left记录产生式左端字符;right记录产生式右端字符;ln记录产生式右端字符长度Status:记录token分析情况Token:category,类型;value,具体内容b)根据LL(1)算法,手工构造分析表,并将内容用数组存储,便于查找c)先将当前语句的各token按序存储,当前处理语句最后一个token以#标记,作为输入流与产生式比较,堆栈中初始放入#,x,a为处理输入流中当前读头内容✓若top=a=‘#‘表示识别成功,退出分析程序✓若top=a!=‘#‘表示匹配,弹出栈顶符号,读头前进一个✓若top为i或n,但top!=a,出错,输出当前语句所在行,出错具体字符✓若top不为i或n,查预测分析表,若其中存放关于top产生式,则弹出top,将产生式右部自右向左压入栈内,输出该产生式,若其中没有产生式,出错,输出当前语句所在行,出错具体字符d)以;作为语句终结,每次遇到分号则处理之前语句并清空后预备下语句处理,当遇到$表示该段程序结束,停止继续处理4.分析表构造过程a)x->i=ee->e+t|e-t|tt->t*f|t/f|ff->(e)|i|nnote: i表示变量,n表示数字,!表示空串b)提取左公因子x->i=ee->ea|ta->+t|-tt->tb|fb->*f|/ff->(e)|i|nc)消除左递归x->i=ee->tcc->ac|!a->+t|-tt->fdd->bd|!b->*e|/ff->(e)|i|n5.类class parser{public:LLtable table[100][100]; //LL(1)表void scanner(); //扫描输入流中内容并分析parser(istream& in); //初始化,得到输入文件地址int getLine() const; //得到当前行数private:int match(); //分析语法stack <char> proStack; //分析堆栈void constructTable(); //建立LL(1)表int getRow(char ch); //取字符所在表中行int getCol(char ch); //取字符所在表中列istream* pstream; //输入流void insertToken(token& t); //插入当前tokenstatus getToken(token& t); //找到tokenint getChar(); //得到当前字符int peekChar(); //下一个字符void putBackChar(char ch); //将字符放回void skipChar(); //跳过当前字符void initialization(); //初始化堆栈等int line; //当前行数token tokens[1000]; //字符表int counter; //记录当前字符表使用范围}6.主要代码void parser::constructTable() //建立LL(1)表{for (int i=0;i<8;i++){for (int j=0;j<9;j++){table[i][j].left=' ';for (int k=0;k<3;k++)table[i][j].right[k]=' ';}}table[0][6].left='x';table[0][6].ln=3;table[0][6].right[0]='i';table[0][6].right[1]='=';table[0][6].right[2]='e';table[1][4].left='e';table[1][4].ln=2;table[1][4].right[0]='t';table[1][4].right[1]='c';table[1][6].left='e';table[1][6].ln=2;table[1][6].right[0]='t';table[1][6].right[1]='c';table[1][7].left='e';table[1][7].ln=2;table[1][7].right[0]='t';table[1][7].right[1]='c';table[2][0].left='c';table[2][0].ln=2;table[2][0].right[0]='a';table[2][0].right[1]='c';table[2][1].left='c';table[2][1].ln=2;table[2][1].right[0]='a';table[2][1].right[1]='c';table[2][5].left='c';table[2][5].ln=0;table[2][5].right[0]='!';table[2][8].left='c';table[2][8].ln=0;table[2][8].right[0]='!';table[3][0].left='a';table[3][0].ln=2;table[3][0].right[0]='+'; table[3][0].right[1]='t'; table[3][1].left='a';table[3][1].ln=2;table[3][1].right[0]='-'; table[3][1].right[1]='t'; table[4][4].left='t';table[4][4].ln=2;table[4][4].right[0]='f'; table[4][4].right[1]='d'; table[4][6].left='t';table[4][6].ln=2;table[4][6].right[0]='f'; table[4][6].right[1]='d'; table[4][7].left='t';table[4][7].ln=2;table[4][7].right[0]='f'; table[4][7].right[1]='d'; table[5][0].left='d';table[5][0].ln=0;table[5][0].right[0]='!'; table[5][1].left='d';table[5][1].ln=0;table[5][1].right[0]='!'; table[5][2].left='d';table[5][2].ln=2;table[5][2].right[0]='b'; table[5][2].right[1]='d'; table[5][3].left='d';table[5][3].ln=2;table[5][3].right[0]='b'; table[5][3].right[1]='d'; table[5][5].left='d';table[5][5].ln=0;table[5][5].right[0]='!'; table[5][8].left='d';table[5][8].ln=0;table[5][8].right[0]='!'; table[6][2].left='b';table[6][2].ln=2;table[6][2].right[0]='*'; table[6][2].right[1]='f'; table[6][3].left='b';table[6][3].ln=2;table[6][3].right[0]='/'; table[6][3].right[1]='f'; table[7][4].left='f';table[7][4].ln=3;table[7][4].right[0]='(';table[7][4].right[1]='e';table[7][4].right[2]=')';table[7][6].left='f';table[7][6].ln=1;table[7][6].right[0]='i';table[7][7].left='f';table[7][7].ln=1;table[7][7].right[0]='n';}int parser::match() //分析语法{ofstream ofs("out.txt",ios::app);char a;int i=0;for (int p=0;p<counter;p++){cout<<tokens[p].value;ofs<<tokens[p].value;}cout<<endl;ofs<<endl<<"ANALYSIS:"<<endl;while(1){if(tokens[i].category=='n' || tokens[i].category=='i')a=tokens[i].category;elsea=(tokens[i].value)[0];if(a==proStack.top()){if(a=='#'){cout<<"This is valid!"<<endl<<endl;ofs<<"This is valid!"<<endl<<endl;return 0;}else{proStack.pop();i++;}}else{if(proStack.top() =='n'|| proStack.top() =='i'){if(a!='#'){cout<<"ERROR(LINE "<<getLine()<<" ): "<<a<<" cannot be matched"<<endl;ofs<<"ERROR(LINE "<<getLine()<<" ): "<<a<<" cannot be matched"<<endl;}else{cout<<"ERROR(LINE "<<getLine()<<" ): Unexpected ending"<<endl;ofs<<"ERROR(LINE "<<getLine()<<" ): Unexpected ending"<<endl;}cout<<"This is invalid!"<<endl<<endl;ofs<<"This is invalid!"<<endl<<endl;return 0;}else{if((table[getRow(proStack.top())][getCol(a)]).left!=' '){char pst=proStack.top();int n=table[getRow(pst)][getCol(a)].ln;int k=0;ofs<<table[getRow(pst)][getCol(a)].left<<"->"<<table[getRow(pst)][getCol(a)].right[0]<<table[getRow(pst)][g etCol(a)].right[1]<<table[getRow(pst)][getCol(a)].right[2]<<endl;proStack.pop();while (n>0){//cout<<n<<" "<<table[getRow(pst)][getCol(a)].right[n-1]<<endl;proStack.push(table[getRow(pst)][getCol(a)].right[n-1]);n--;}}else{if(a!='#'){cout<<"ERROR(LINE "<<getLine()<<" ): "<<a<<" cannot be matched"<<endl;ofs<<"ERROR(LINE "<<getLine()<<" ): "<<a<<" cannot be matched"<<endl;}else{cout<<"ERROR(LINE "<<getLine()<<" ): Unexpected ending"<<endl;ofs<<"ERROR(LINE "<<getLine()<<" ): Unexpected ending"<<endl;}cout<<"This is invalid!"<<endl<<endl;ofs<<"This is invalid!"<<endl<<endl;return 0;}}}}}实验结果:●输入(in.txt)●输出1输出2(out.txt)实验总结:原本以为处理四则运算赋值将会很困难,但在使用LL(1)后发现,思路还是挺清晰简单的,但在实验过程中,由于LL(1)不能出现左递归和左公因子,不得不将其消除,原本简单的产生式一下变多了,而在产生式理解上也没有原来直观,不过其状态复杂度没有LR高,故仍选择该方法。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一、实验目的及内容实现下述我们定义的语言的语法分析器这种语言的程序结构很简单,语法相当于c的函数体,即由一对大括号括起来的语句序列,没有过程或函数。
声明语句、表达式语句及控制语句的写法都与c 类似,但规定:一条声明语句只能声明一个整型变量,没有数组;控制语句只是if、for和while三个语句,这三个语句本身也可以包含语句序列;表达式仅局限于布尔表达式和整型算术表达式,布尔表达式由对两个算术表达式的比较组成,该比较使用<,>,<=,>=,= =,!=比较运算符;算术表达式可以包括整型常数、变量以及+,-,*,/这四个运算符。
另外,还可以有复合语句。
用read和write语句实现输入输出。
注释用/*和*/括起来,但注释不能嵌套。
二、实验原理及基本技术路线图(方框原理图或程序流程图)实验所用的产生式:<程序> →‘{’ <声明序列> <语句序列> ‘}’<声明序列> → <声明语句> { <声明语句> }<声明语句> → int <标志符>;<语句序列> → <语句> { <语句> }<语句> → <if语句> | <while语句> | <for语句> | <read语句> | <write 语句> | <复合语句> | <表达式语句><if语句> → if (<表达式>) <语句> [ else <语句> ]<while语句> → while (<表达式>) <语句><for语句> → for (<表达式>;<表达式>;<表达式>) <语句><read语句> → read <标识符>;<write语句> → write <表达式>;<复合语句> →‘{ ’ <语句序列>‘ }’<表达式语句> → <表达式>; | ;<表达式> → <布尔表达式> | <标志符> = <布尔表达式><布尔表达式> → <算术表达式> | <算术表达式> ( > | < | >= | <= | == | !=)<算术表达式><算术表达式> → <项> { ( + | - ) <项> }<项> → <因子> { ( * | / ) <因子> }<因子> → (<算术表达式>) | <标识符> | <无符号整数>实验中自定义的函数:int parse();语法分析主函数int program();<程序>int statement();<语句>int expression_stat();<表达式语句>int expression();<表达式>int bool_expr();<布尔表达式>int additive_expr();<算术表达式>int term();<项>int factor();<因子>int if_stat();<if语句>int while_stat();<while语句>int for_stat();<for语句>int write_stat();<write语句>int read_stat();<read语句>int declaration_stat();<声明语句>int declaration_list();<声明序列>int statement_list();<语句序列>int compound_stat();<复合语句>三、所用仪器、材料(设备名称、型号、规格等或使用软件)开发环境/平台:vc++6.0实验器材:兼容计算机一台四、实验方法、步骤(或:程序代码或操作过程)实验源代码:#include <stdio.h>#include <ctype.h>#include <conio.h>#include <string.h>int parse();int program();int statement();int expression_stat();int expression();int bool_expr();int additive_expr();int term();int factor();int if_stat();int while_stat();int for_stat();int write_stat();int read_stat();int declaration_stat();int declaration_list();int statement_list();int compound_stat();char token[20],token1[40];//token保存单词符号,token1保存单词值char Scanout[300]; //保存词法分析输出文件名long count=0;FILE *fp; //用于指向输入输出文件的指针void main(){strcpy(Scanout,"输出.txt");parse();}//语法分析程序int parse(){int es=0;if((fp=fopen(Scanout,"r"))==NULL){printf("\n打开%s错误!\n",Scanout);es=10;}if (es==0) es=program();printf("=====语法分析结果!======\n");switch(es){case 0: printf("语法分析成功!\n");break;case 10: printf("打开文件 %s失败!\n",Scanout);break;case 1: printf("缺少{!\n");break;case 2: printf("缺少}!\n");break;case 3: printf("缺少标识符!\n");break;case 4: printf("少分号!\n");break;case 5: printf("缺少(!\n");break;case 6: printf("缺少)!\n");break;case 7: printf("缺少操作数!\n");break;case 8: printf("缺少运算符!\n");break;}fclose(fp);return(es);}void get(){fscanf(fp,"%s %s\n",&token,&token1);printf("%s %s\n",token,token1);count++;}void back(int j)//文件指针回退一位{int i;printf("文件指针回退%d位!\n",j);rewind(fp);for(i=0;i<count;i++){fscanf(fp,"%s %s\n",&token,&token1);}}//<程序>::={<声明序列><语句序列>}//program::= '{'<declaration_list><statement_list> '}' int program(){int es=0;get();if(strcmp(token,"{"))//判断是否'{'{es=1;return(es);}es=declaration_list();if (es>0) return(es);es=statement_list();if (es>0) return(es);if(strcmp(token,"}"))//判断是否'}'{es=2;return(es);}return(es);}//<声明序列>::=<声明序列><声明语句>|<声明语句>//<declaration_list>::=//<declaration_list><declaration_stat>|<declaration_stat> //改成<declaration_list>::={<declaration_stat>}int declaration_list(){int es=0;get();while (strcmp(token,"int")==0){es=declaration_stat();if (es>0) return(es);}return(es);//<声明语句> ::=int <变量>;//<declaration_stat>::=int ID;int declaration_stat(){int es=0;get();if (strcmp(token,"ID")) return(es=3); //不是标识符get();if (strcmp(token,";") ) return(es=4);get();return(es);}//<语句序列>::=<语句序列><语句>|<语句>//<statement_list>::=<statement_list><statement>|<statement>//改成<statement_list>::={<statement>}int statement_list(){int es=0;while(strcmp(token,"(")==0||strcmp(token,"NUM")==0||strcmp(token,"ID")==0||s trcmp(token,"if")==0||strcmp(token,"while")==0||strcmp(token,"for")==0| |strcmp(token,"read")==0||strcmp(token,"write")==0||strcmp(token,"{")=={es=statement();if (es>0) return(es);get();}return es;}//<语句>::=<if语句>|<while语句>|<for语句>|<read语句> // |<write语句>|<复合语句>|<表达式语句>//<statement>::= <if_stat>|<while_stat>|<for_stat> // |<compound_stat> |<expression_stat>int statement() //error;;;;;;{int es=0;if(strcmp(token,"if")==0){es=if_stat();return es;}if(strcmp(token,"while")==0) {es=while_stat();return es;}if(strcmp(token,"for")==0) {es=for_stat();return es;}if(strcmp(token,"read")==0) {es=read_stat();return es;}if(strcmp(token,"write")==0) {es=write_stat();return es;}if(strcmp(token,"{")==0){es=compound_stat();return es;}else{es=expression_stat();return es;}return es;}//<IF 语句>::= if (<表达式>) <语句 > [else <语句 >]//<IF_stat>::= if (<expr>) <statement > [else < statement >]int if_stat(){int es=0;int temp=0;get();if(strcmp(token,"(")==0){get();if(strcmp(token,"ID")==0||strcmp(token,"NUM")==0||strcmp(token,"(")= =0){es=expression();}elseif(strcmp(token,"ID"))return (es=3);elseif(strcmp(token,"NUM"))return (es=7);get();if(strcmp(token,")")==0){get();es=statement();temp=es;if(es>0) return es;get();if(strcmp(token,"else")==0){ get();es=statement(); }else{count-=1;back(1);es=temp;}//需要做回退操作}else{es=6;return es;}}elsees=5;return es;}//<while语句>::=while(<表达式>) <语句>//<while_stat>::= while (<expr >) < statement > int while_stat(){int es=0;get();if(strcmp(token,"(")==0){get();if(strcmp(token,"ID")==0||strcmp(token,"NUM")==0||strcmp(token,"(")= =0){es=expression();}elseif(strcmp(token,"ID"))return (es=3);elseif(strcmp(token,"NUM"))return (es=7);get();if(strcmp(token,")")==0){get();es=statement();return es;}}else{es=5;return es;}return es;}//<for语句>::=for(<表达式>;<表达式>;<表达式>) <语句 >//<for_stat>::= for(<expr>,<expr>,<expr>)<statement>int for_stat(){int es=0;get();if(strcmp(token,"(")==0){get();if(strcmp(token,"ID")==0||strcmp(token,"NUM")==0||strcmp(token,"(")= =0){es=expression();if(es>0) return es;}elseif(strcmp(token,"ID"))return (es=3);elseif(strcmp(token,"NUM"))return (es=7);get();if(strcmp(token,";")==0){get();if(strcmp(token,"ID")==0||strcmp(token,"NUM")==0||strcmp(token,"(")= =0){es=expression();if(es>0) return es;}elseif(strcmp(token,"ID"))return (es=3);elseif(strcmp(token,"NUM"))return (es=7);get();if(strcmp(token,";")==0){get();if(strcmp(token,"ID")==0||strcmp(token,"NUM")==0||strcmp(token,"(")= =0){es=expression();if(es>0) return es;}elseif(strcmp(token,"ID"))return (es=3);elseif(strcmp(token,"NUM"))return (es=7);get();if(strcmp(token,")")==0){get();es=statement();return es;}else{es=6;return es;}}else{es=4;return es;}}else{es=4;return es;}}else{es=5;return es;}return es;}//<write_语句>::=write <表达式>;//<write_stat>::=write <expression>;int write_stat(){int es=0;get();if(strcmp(token,"ID")==0||strcmp(token,"NUM")==0||strcmp(token,"(")= =0){es=expression();if(es>0) return es;get();if(strcmp(token,";")) return 4;}elseif(strcmp(token,"ID"))return (es=3);elseif(strcmp(token,"NUM"))return (es=7);return es;}//<read_语句>::=read <变量>;//<read_stat>::=read ID;int read_stat(){int es=0;get();if (strcmp(token,"ID"))return(es=3); //不是标识符get();if(strcmp(token,";")) return 4;return es;}//<复合语句>::={<语句序列>}//<compound_stat>::= '{'<statement_list> '}' int compound_stat(){ //复合语句函数int es=0;get();es=statement_list();if(es>0) return es;if(strcmp(token,"}")) return (es=2);return es;}//<表达式语句>::=<表达式>;|;//<expression_stat>::=<expression>;|;int expression_stat(){int es=0;if(strcmp(token,";")==0) return es;else{if(strcmp(token,"ID")==0||strcmp(token,"NUM")==0||strcmp(token,"(")= =0){es=expression();if(es>0) return es;}get();if(strcmp(token,";")) return 4;}return es;}//<表达式>::=<标识符>=<布尔表达式>|<布尔表达式>//<expr>::=ID=<bool_expr>|<bool_expr>int expression(){int es=0;if(strcmp(token,"ID")==0){get();if(strcmp(token,"=")==0){get();if(strcmp(token,"ID")==0||strcmp(token,"NUM")==0||strcmp(token,"(")= =0)es=bool_expr();if(es>0) return es;}else{count-=2;back(2);get();if(strcmp(token,"ID")==0||strcmp(token,"NUM")==0||strcmp(token,"(")= =0)es=bool_expr();}}return es;}//<布尔表达式>::=<算术表达式>|<算术表达式>(>|<|>=|<=|==|!=)<算术表达式> //<bool_expr>::=<additive_expr>// |< additive_expr >(>|<|>=|<=|==|!=)< additive_expr >int bool_expr(){int es=0;es=additive_expr();if(es>0) return es;get();if(strcmp(token,">")==0||strcmp(token,"<")==0||strcmp(token,">=")==0||s trcmp(token,"<=")==0||strcmp(token,"==")==0||strcmp(token,"!=")==0) {get();if(strcmp(token,"ID")==0||strcmp(token,"NUM")==0||strcmp(token,"(")= =0)es=additive_expr();if(es>0) return es;}else //keystep{count--;back(1);}return es;}//<算术表达式>::=<项>{(+|-)<项>}//<additive_expr>::=<term>{(+|-)< term >}int additive_expr(){int es=0;es=term();if(es>0) return es;get();if(strcmp(token,"+")==0||strcmp(token,"-")==0){get();if(strcmp(token,"ID")==0||strcmp(token,"NUM")==0||strcmp(token,"(")= =0)es=term();if(es>0) return es;}else //keystep{count--;back(1);}return es;}//<项>::=<因子>{(*|/)<因子>}//< term >::=<factor>{(*| /)< factor >}int term(){int es=0;es=factor();if(es>0) return es;get();if(strcmp(token,"*")==0||strcmp(token,"/")==0){get();if(strcmp(token,"ID")==0||strcmp(token,"NUM")==0||strcmp(token,"(")= =0)es=factor();if(es>0) return es;}else //keystep{count--;back(1);}return es;}//<因子>::=(<算术表达式>)|<标识符>|<无符号整数>//< factor >::=(<additive_expr>)| ID|NUMint factor(){int es=0;if(strcmp(token,"(")==0){get();if(strcmp(token,"ID")==0||strcmp(token,"NUM")==0||strcmp(token,"(")= =0)es=additive_expr();if(es>0) return es;get();if(strcmp(token,")")) return 6;goto a;}elseif(strcmp(token,"ID")==0) goto a;else es=3;if(strcmp(token,"NUM") && es!=0) return(es=7);else es=0;a:return es;}五、实验过程原始记录( 测试数据、图表、计算等)二元组信息运行结果截图:六、实验结果、分析和结论(误差分析与数据处理、成果总结等。