语法分析实验

合集下载

实验原理ll1分析法

实验原理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语法分析

《编译原理》实验3_PL0语法分析编译原理是计算机科学中的重要课程,它涉及了程序语言的设计、编译器的构建以及编程语言的解释和执行等方面。

在编译原理的实验部分中,PL0语法分析是一个重要的实验项目。

PL0语法分析是基于PL0语言的语法规则来构建语法分析器,实现对PL0代码的分析和解释。

在这个实验中,我们将完成PL0语法分析器的设计和实现,并对其进行测试。

首先,我们需要了解PL0语言的语法规则。

PL0语言是一种过程型语言,类似于Pascal语言。

它有一套严格的语法规则,包括声明语句、赋值语句、条件语句、循环语句等。

我们需要先从PL0语言文法中提取出规则,然后将其转化为一个语法分析器。

接下来,我们需要设计和实现语法分析器。

语法分析器的主要任务是根据PL0语言的文法规则来分析和解释PL0代码。

我们可以选择使用自顶向下的语法分析方法,如递归下降分析法。

递归下降分析法是一种简单直观的语法分析方法,它通过递归调用子程序来分析和解释代码。

在设计语法分析器时,我们需要根据PL0语言的文法规则来设计相应的文法产生式和语法分析程序。

文法产生式描述了PL0语言的句子结构,它由非终结符和终结符组成,并用箭头“->”来表示产生关系。

语法分析程序则是根据产生式来解释和分析代码。

最后,我们需要编写测试代码来验证语法分析器的正确性。

测试代码应该包含PL0语言的各种语法结构和语法错误,从而验证语法分析器在不同情况下的正确性和鲁棒性。

通过完成这个实验项目,我们能够深入了解编译原理中的语法分析技术,并提升我们的编程能力和问题解决能力。

同时,我们也能够加深对PL0语言的理解,为以后的编程工作打下坚实的基础。

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

实验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语言语法分析器实验报告

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)分析法

实验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)分析表语法分析报告

实验三 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高,故仍选择该方法。

编译原理实验三-自下而上语法分析及语义分析.docx

编译原理实验三-自下而上语法分析及语义分析.docx

电力学院编译原理课程实验报告实验名称:实验三自下而上语法分析及语义分析院系:计算机科学与技术学院专业年级:学生:学号:指导老师:实验日期:实验三自上而下的语法分析一、实验目的:通过本实验掌握LR分析器的构造过程,并根据语法制导翻译,掌握属性文法的自下而上计算的过程。

二、实验学时:4学时。

三、实验容根据给出的简单表达式的语法构成规则(见五),编制LR分析程序,要求能对用给定的语法规则书写的源程序进行语法分析和语义分析。

对于正确的表达式,给出表达式的值。

对于错误的表达式,给出出错位置。

四、实验方法采用LR分析法。

首先给出S-属性文法的定义(为简便起见,每个文法符号只设置一个综合属性,即该文法符号所代表的表达式的值。

属性文法的定义可参照书137页表6.1),并将其改造成用LR分析实现时的语义分析动作(可参照书145页表6.5)。

接下来给出LR分析表。

然后程序的具体实现:● LR分析表可用二维数组(或其他)实现。

●添加一个val栈作为语义分析实现的工具。

编写总控程序,实现语法分析和语义分析的过程。

注:对于整数的识别可以借助实验1。

五、文法定义简单的表达式文法如下:(1)E->E+T(2)E->E-T(3)E->T(4)T->T*F(5)T->T/F(6)T->F(7)F->(E)(8)F->i五、处理程序例和处理结果例示例1:20133191*(20133191+3191)+ 3191#六、源代码【cifa.h】//cifa.h#include<string>using namespace std;//单词结构定义struct WordType{int code;string pro;};//函数声明WordType get_w();void getch();void getBC();bool isLetter();bool isDigit();void retract();int Reserve(string str);string concat(string str);【Table.action.h】//table_action.hclass Table_action{int row_num,line_num;int lineName[8];string tableData[16][8];public:Table_action(){row_num=16;line_num=8;lineName[0]=30;lineName[1]=7;lineName[2]=13;lineName[3]=8;lineName[4]=14;lineName[5]=1;lineName[6]=2;lineName[7]=15;lineName[8]=0;for(int m=0;m<row_num;m++)for(int n=0;n<line_num;n++)tableData[m][n]="";tableData[0][0]="S5";tableData[0][5]="S4";tableData[1][1]="S6";tableData[1][2]="S12";tableData[1][7]="acc";tableData[2][1]="R3";tableData[2][2]="R3";tableData[2][3]="S7";tableData[2][4]="S13";tableData[2][6]="R3";tableData[2][7]="R3";tableData[3][1]="R6";tableData[3][3]="R6"; tableData[3][4]="R6"; tableData[3][6]="R6"; tableData[3][7]="R6"; tableData[4][0]="S5"; tableData[4][5]="S4"; tableData[5][1]="R8"; tableData[5][2]="R8"; tableData[5][3]="R8"; tableData[5][4]="R8"; tableData[5][6]="R8"; tableData[5][7]="R8"; tableData[6][0]="S5"; tableData[6][5]="S4"; tableData[7][0]="S5"; tableData[7][5]="S4"; tableData[8][1]="S6"; tableData[8][2]="S12"; tableData[8][6]="S11"; tableData[9][1]="R1"; tableData[9][2]="R1"; tableData[9][3]="S7"; tableData[9][4]="S13"; tableData[9][6]="R1"; tableData[9][7]="R1"; tableData[10][1]="R4"; tableData[10][2]="R4"; tableData[10][3]="R4"; tableData[10][4]="R4"; tableData[10][6]="R4"; tableData[10][7]="R4"; tableData[11][1]="R7"; tableData[11][2]="R7"; tableData[11][3]="R7"; tableData[11][4]="R7"; tableData[11][6]="R7"; tableData[11][7]="R7"; tableData[12][0]="S5"; tableData[12][5]="S4"; tableData[13][0]="S5"; tableData[13][5]="S4"; tableData[14][1]="R2"; tableData[14][2]="R2";tableData[14][4]="S13";tableData[14][6]="R2";tableData[14][7]="R2";tableData[15][1]="R5";tableData[15][2]="R5";tableData[15][3]="R5";tableData[15][4]="R5";tableData[15][5]="R5";tableData[15][6]="R5";tableData[15][7]="R5";}string getCell(int rowN,int lineN){int row=rowN;int line=getLineNumber(lineN);if(row>=0&&row<row_num&&line>=0&&line<=line_num) return tableData[row][line];elsereturn"";}int getLineNumber(int lineN){for(int i=0;i<line_num;i++)if(lineName[i]==lineN)return i;return -1;}};【Table_go.h】//table_go.hclass Table_go{int row_num,line_num;//行数、列数string lineName[3];int tableData[16][3];public:Table_go(){row_num=16;line_num=3;lineName[0]="E";lineName[1]="T";lineName[2]="F";for(int m=0;m<row_num;m++)for(int n=0;n<line_num;n++)tableData[m][n]=0;tableData[0][0]=1;tableData[0][1]=2;tableData[0][2]=3;tableData[4][0]=8;tableData[4][1]=2;tableData[4][2]=3;tableData[6][1]=9;tableData[6][2]=3;tableData[7][2]=10;tableData[12][1]=14;tableData[12][2]=3;tableData[13][2]=15;}int getCell(int rowN,string lineNa){int row=rowN;int line=getLineNumber(lineNa);if(row>=0&&row<row_num&&line<=line_num) return tableData[row][line];elsereturn -1;}int getLineNumber(string lineNa){for(int i=0;i<line_num;i++)if(lineName[i]==lineNa)return i;return -1;}};【Stack_num.h】class Stack_num{int i; //栈顶标记int *data; //栈结构public:Stack_num() //构造函数{data=new int[100];i=-1;}int push(int m) //进栈操作{i++;data[i]=m;return i;}int pop() //出栈操作{i--;return data[i+1];}int getTop() //返回栈顶{return data[i];}~Stack_num() //析构函数{delete []data;}int topNumber(){return i;}void outStack(){for(int m=0;m<=i;m++)cout<<data[m];}};【Stack_str.h】class Stack_str{int i; //栈顶标记string *data; //栈结构public:Stack_str() //构造函数{data=new string[50];i=-1;}int push(string m) //进栈操作{i++;data[i]=m;return i;}int pop() //出栈操作{data[i]="";i--;return i;}string getTop() //返回栈顶{return data[i];}~Stack_str() //析构函数{delete []data;}int topNumber(){return i;}void outStack(){for(int m=0;m<=i;m++)cout<<data[m];}};【cifa.cpp】//cifa.cpp#include<iostream>#include<string>#include"cifa.h"using namespace std;//关键字表和对应的编码string codestring[10]={"main","int","if","then","else","return","void","cout","endl"}; int codebook[10]={26,21,22,23,24,25,27,28,29};//全局变量char ch;int flag=0;/*//主函数int main(){WordType word;cout<<"请输入源程序序列:";word=get_w();while(word.pro!="#")//#为自己设置的结束标志{cout<<"("<<word.code<<","<<"“"<<word.pro<<"”"<<")"<<endl;word=get_w();};return 0;}*/WordType get_w(){string str="";int code;WordType wordtmp;getch();//读一个字符getBC();//去掉空白符if(isLetter()){ //以字母开头while(isLetter()||isDigit()){str=concat(str);getch();}retract();code=Reserve(str);if(code==-1){wordtmp.code=0;wordtmp.pro=str;}//不是关键字else{wordtmp.code=code;wordtmp.pro=str;}//是关键字}else if(isDigit()){ //以数字开头while(isDigit()){str=concat(str);getch();}retract();wordtmp.code=30;wordtmp.pro=str;}else if(ch=='(') {wordtmp.code=1;wordtmp.pro="(";}else if(ch==')') {wordtmp.code=2;wordtmp.pro=")";}else if(ch=='{') {wordtmp.code=3;wordtmp.pro="{";}else if(ch=='}') {wordtmp.code=4;wordtmp.pro="}";}else if(ch==';') {wordtmp.code=5;wordtmp.pro=";";}else if(ch=='=') {wordtmp.code=6;wordtmp.pro="=";}else if(ch=='+') {wordtmp.code=7;wordtmp.pro="+";}else if(ch=='*') {wordtmp.code=8;wordtmp.pro="*";}else if(ch=='>') {wordtmp.code=9;wordtmp.pro=">";}else if(ch=='<') {wordtmp.code=10;wordtmp.pro="<";}else if(ch==',') {wordtmp.code=11;wordtmp.pro=",";}else if(ch=='\'') {wordtmp.code=12;wordtmp.pro="\'";}else if(ch=='-') {wordtmp.code=13;wordtmp.pro="-";}else if(ch=='/') {wordtmp.code=14;wordtmp.pro="/";}else if(ch=='#') {wordtmp.code=15;wordtmp.pro="#";}else if(ch=='|') {wordtmp.code=16;wordtmp.pro="|";}else {wordtmp.code=100;wordtmp.pro=ch;} return wordtmp;}void getch(){if(flag==0) //没有回退的字符ch=getchar();else //有回退字符,用回退字符,并设置标志flag=0;}void getBC(){while(ch==' '||ch=='\t'||ch=='\n')ch=getchar();}bool isLetter(){if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z')return true;elsereturn false;}bool isDigit(){if(ch>='0'&&ch<='9')return true;elsereturn false;}string concat(string str){return str+ch;}void retract(){flag=1;}int Reserve(string str){int i;for(i=0;i<=8;i++){if(codestring[i]==str) //是某个关键字,返回对应的编码return codebook[i];}if(i==9) //不是关键字return -1;}【LR.cpp】#include<iostream>#include<string>#include<cstdlib>#include"cifa.h"#include"stack_num.h"#include"stack_str.h"#include"table_action.h"#include"table_go.h"using namespace std;void process(){int stepNum=1;int topStat;Stack_num statusSTK; //状态栈Stack_str symbolSTK; //符号栈Stack_num valueSTK; //值栈WordType word;Table_action actionTAB; //行为表Table_go goTAB; //转向表cout<<"请输入源程序,以#结束:";word=get_w();//总控程序初始化操作symbolSTK.push("#");statusSTK.push(0);valueSTK.push(0);cout<<"步骤\t状态栈\t符号栈\t值栈\t当前词\t动作\t转向"<<endl;//分析while(1){topStat=statusSTK.getTop(); //当前状态栈顶string act=actionTAB.getCell(topStat,word.code);//根据状态栈顶和当前单词查到的动作//输出cout<<stepNum++<<"\t";statusSTK.outStack(); cout<<"\t";symbolSTK.outStack(); cout<<"\t";valueSTK.outStack(); cout<<"\t";cout<<word.pro<<"\t";//行为为“acc”,且当前处理的单词为#,且状态栈里就两个状态//说明正常分析结束if(act=="acc"&&word.pro=="#"&&statusSTK.topNumber()==1){cout<<act<<endl;cout<<"分析成功!"<<endl;cout<<"结果为:"<<valueSTK.getTop()<<endl;return;}//读到act表里标记为错误的单元格else if(act==""){cout<<endl<<"不是文法的句子!"<<endl;cout<<"错误的位置为单词"<<word.pro<<"附近。

语法分析实验报告

语法分析实验报告

语法分析实验报告语法分析实验报告引言语法分析是自然语言处理中的一项重要任务,它旨在根据给定的语法规则和输入句子,确定句子的结构和语法成分,并进行语义解析。

本实验旨在探索语法分析的基本原理和方法,并通过实际操作来加深对其理解。

实验目标本实验的主要目标是实现一个简单的自底向上的语法分析器,即基于短语结构文法的分析器。

具体而言,我们将使用Python编程语言来实现一个基于CYK 算法的语法分析器,并对其进行评估和分析。

实验过程1. 语法规则的定义在开始实验之前,我们首先需要定义一个适当的语法规则集。

为了简化实验过程,我们选择了一个简单的文法,用于分析包含名词短语和动词短语的句子。

例如,我们定义了以下语法规则:S -> NP VPNP -> Det NVP -> V NP2. 实现CYK算法CYK算法是一种自底向上的语法分析算法,它基于动态规划的思想。

我们将使用Python编程语言来实现CYK算法,并根据定义的语法规则进行分析。

具体而言,我们将根据输入的句子和语法规则,构建一个二维的表格,用于存储句子中各个子串的语法成分。

通过填充表格并进行推导,我们可以确定句子的结构和语法成分。

3. 实验结果与分析我们使用几个示例句子来测试我们实现的语法分析器,并对其结果进行分析。

例如,对于句子"the cat eats fish",我们的语法分析器可以正确地识别出该句子的结构,并给出相应的语法成分。

具体而言,我们的分析器可以识别出句子的主语是"the cat",谓语是"eats",宾语是"fish"。

通过对多个句子的测试,我们可以发现我们实现的语法分析器在大多数情况下都能正确地分析句子的结构和语法成分。

然而,在一些复杂的句子中,我们的分析器可能会出现一些错误。

这可能是由于语法规则的不完备性或者算法的限制所致。

结论与展望通过本实验,我们深入了解了语法分析的基本原理和方法,并实现了一个简单的自底向上的语法分析器。

语法分析实验报告

语法分析实验报告

语法分析实验报告一: 实验内容:编写语法分析程序, 实现对算术表达式的语法分析, 要求所分析的算术表达式由如下的文法产生。

E->E+T|E-T|TT->T*F|T/F|FF->id|(E)|num二: 实验要求:在对表达式进行分析的同时, 输出所采用的产生式。

1.编写LL(1)语法分析程序, 要求:编程实现算法4.2, 为给定的文法自动构造预测分析表编程实现算法4.1, 构造LL(1)预测分析程序,2.编写语法分析程序, 实现自底向上的分析, 要求:构造识别所有活前缀的DFA构造LR分析表编程实现算法4.3, 构造LR分析程序1.三: 实验分析:2.方法二(编写LL(1)语法分析程序)1.步骤:(1)根据题目所给出的文法构造相应的无左递归文法, 并求出该文法各非终结符的FIRST、FOLLOW集合;(2)构造文法的LL(1)分析表;(3)由此构造LL分析程序。

2.实现方法:1.输入缓冲区为一个字符型数组, 读入输入的算术表达式并保存在此, 以’$’结束;2.为构造文法的LL(1)分析表, 构建一个相对应的字符串数组;3.在实际程序中P代表E', Q代表T', e代表ε,i代表id, n代表num;4.处理输入表达式中代表id和num的子串, 分别将它们转化为'i'和'n'进行分析;5.LL(1)预测分析程序的总控程序在任何时候都是按STACK栈顶符号X和当前的输入符号a做哪种过程的。

对于任何(X,a),总控程序每次都执行下述三种可能的动作之一:(1)若X = a =‘$’, 则宣布分析成功, 停止分析过程。

(2)若X = a!=‘$’, 则把X从STACK栈顶弹出, 让a指向下一个输入符号。

①如果是终结符合, 则栈不加入新符号②如果是非终结符合, 则把表达式右边入栈(3)若M[A, a]中存放着“出错标志”, 则调用出错诊断程序ERROR。

语义分析——精选推荐

语义分析——精选推荐

语义分析实验四、语法分析实验⼀、实验⽬的(1)编制⼀个语义分析程序(2)语义分析程序是在语法分析程序的基础上进⾏编写的,主要任务是根据语法分析来插⼊中间代码、语义规则以及⽣成四元式。

(3)通过语义分析的练习,能够进⼀步了解编译原理。

(4)通过了解语义分析程序的设计原则、语义规则的描述技术、识别机制及语义分析程序的⾃动构造原理。

⼆、实验内容和要求(1)根据语法分析程序进⾏改写语义分析程序(2)根据语⾔的语义规则,插⼊中间代码、语义规则以及⽣成四元式等(3)并在分析过程中进⾏语义检查,四元式作为输出或以某种形式的语法树作报告错误三、实验⽅法、步骤及结果测试1、实验⽅法、步骤:完成静态语义审查和处理a) 上下⽂相关性审查b) 类型匹配审查c) 类型转换d) 如:s:=2*3.1416*r*(h+r);i. 赋值语句的语义:计算赋值符号右边表达式的值,送到赋值号左边的变量中。

ii. 检查赋值号左右两边的类型是否匹配iii. 根据赋值语句的语义,将它翻译成四元式中间代码2、原理分析:我是在语法分析程序的基础上进⾏修改的,是根据语法分析来插⼊中间代码、制定语义规则以及⽣成四元式。

void S(){char y=str[t-1];int x;if(syn==10){scaner();if(syn==18){scaner(); x=E();printf("\n(':=',%d, ,%c)\n",x,y);}}}int E(){int x;printf("E ");x=T();return E1(x);}int E1(int x){int y;printf("E1 ");if (syn==13) {scaner();y=T();gen4('+',x,y);return E1(x+y);}else if (syn==14) {scaner();y=T();gen4('-',x,y);return E1(x-y);}else {if (syn==28 || syn==25)return(x);}}int T(){int x;printf("T ");x=F();return T1(x);}int T1(int x){int y;printf("T1 ");if (syn==15) {scaner();y=F();gen4('*',x,y);return T1(x*y);}else if (syn==16) {scaner();y=F();gen4('/',x,y);return T1(x/y);}else {if (syn==28 ||syn==25 || syn==13||syn==14)return (x);else error();}}int F(){int y; printf("F ");if (syn==27) {scaner();y=E();if(syn==28) {scaner();return (y);}else error();}else if (syn==11 || syn==10){ y=sum; scaner();return (y);}}四、实验总结由于时间的关系,这次实验我暂且做了语义分析的算术表达式与赋值语句,虽然做的不多,但也算把算术表达式做的不错,是有优先级的,我做的实验是以’#’为结束语,输出的四元式是⽤(‘运算符’,操作数1,操作数2,运算结果);还有就是赋值语句是S:=E;这次实验,我学会了语法分析和语义分析程序,利⽤⾃上⽽下的递归下降分析法来分析语法,然后进⾏赋予语义规则,再⽣产中间代码,最后输出四元式。

语法分析器实验报告

语法分析器实验报告

语法分析器的设计实验报告一、实验内容语法分析程序用LL(1)语法分析方法。

首先输入定义好的文法书写文件(所用的文法可以用LL(1)分析),先求出所输入的文法的每个非终结符是否能推出空,再分别计算非终结符号的FIRST集合,每个非终结符号的FOLLOW集合,以及每个规则的SELECT集合,并判断任意一个非终结符号的任意两个规则的SELECT集的交集是不是都为空,如果是,则输入文法符合LL(1)文法,可以进行分析。

对于文法:G[E]:E->E+T|TT->T*F|FF->i|(E)分析句子i+i*i是否符合文法。

二、基本思想1、语法分析器实现语法分析是编译过程的核心部分,它的主要任务是按照程序的语法规则,从由词法分析输出的源程序符号串中识别出各类语法成分,同时进行词法检查,为语义分析和代码生成作准备。

这里采用自顶向下的LL(1)分析方法。

语法分析程序的流程图如图5-4所示。

语法分析程序流程图该程序可分为如下几步:(1)读入文法(2)判断正误(3)若无误,判断是否为LL(1)文法(4)若是,构造分析表;(5)由句型判别算法判断输入符号串是为该文法的句型。

三、核心思想该分析程序有15部分组成:(1)首先定义各种需要用到的常量和变量;(2)判断一个字符是否在指定字符串中;(3)读入一个文法;(4)将单个符号或符号串并入另一符号串;(5)求所有能直接推出&的符号;(6)求某一符号能否推出‘& ’;(7)判断读入的文法是否正确;(8)求单个符号的FIRST;(9)求各产生式右部的FIRST;(10)求各产生式左部的FOLLOW;(11)判断读入文法是否为一个LL(1)文法;(12)构造分析表M;(13)句型判别算法;(14)一个用户调用函数;(15)主函数;下面是其中几部分程序段的算法思想:1、求能推出空的非终结符集Ⅰ、实例中求直接推出空的empty集的算法描述如下:void emp(char c){ 参数c为空符号char temp[10];定义临时数组int i;for(i=0;i<=count-1;i++)从文法的第一个产生式开始查找{if 产生式右部第一个符号是空符号并且右部长度为1,then将该条产生式左部符号保存在临时数组temp中将临时数组中的元素合并到记录可推出&符号的数组empty中。

词法分析、语法分析、语义分析实例解析及实验报告

词法分析、语法分析、语义分析实例解析及实验报告

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

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

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

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

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

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

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

例如:对源程序begin x:=9: if x>9 then x:=2*x+1/3; end #的源文件,经过词法分析后输出如下序列:(1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)……标识符(需进一步判断是否为关键字)数字+=+-=-词法分析状态转换图(终结状态右上角*表示多读一个符号)三、词法分析程序的算法思想:算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。

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

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

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

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

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

编译原理实验报告3

编译原理实验报告3

编译原理实验报告3编译原理实验报告——表达式语法分析——表达式语法分析表达式语法分析实验报告一、实验题目设计一个简单的表达式语法分析器(采用递归下降方法设计实现)二、实验目的1、了解形式语言基础及其文法运算;2、熟悉语法分析原理及 4 种常用的语法分析方法;其中:四种算法为(1)设计算术表达式的递归下降子程序分析算法(2)设计算术表达式的 LL(1) 分析算法(3)设计算术表达式的简单优先分析算法(4)设计算术表达式的SLR(1) 分析算法3、选择上述一种方法并设计一个表达式的语法分析器。

(本实验设计的是递归下降的表达式语法分析器)三、实验内容1.设计递归下降语法分析器算法;2.编写代码并上机调试运行通过; 3、写出试验体会及心得。

四、实验要求1、给出算术表达式文法2、进行适当的文法变换3、选择一种语法分析的方法,并说明其原理4、根据原理给出相应的算法设计,说明主要的数据结构并画出算法流程图5、编写代码并上机调试运行通过6、写出程序运行结果7、写出相应的文档以及代码注释8、输入——表达式;输出——表达式语法是否正确。

五、递归下降的表达式语法分析器设计概要1.算术表达式文法.G(E):E T F 2.文法变换:文法变换:G’(E): E->TE' E'->+TE'|ε T->FT' T'->*FT'|ε F->(E)|I E +T | T T* F | F i | (E)3. 递归下降子程序框图:递归下降子程序框图:六、实验设计源程序#includechar inputstream[50]; int temp=0; int right; void e(); void e1(); void t(); void t1(); void f(); void main() { right=1;//存储输入句子//数组下标 //判断输出信息cout<<"请输入您要分析的字符串以#结束(^为空字符):"<>inputstream; e(); if((inputstream[temp]=='#')&&right) cout<<"分析成功"<<<"e-="" cout<<"分析失败"<TE'"<<<"e'-="" e1()="" e1();="" if(inputstream[temp]="='+')" t();="" void="" {="" }="">+TE'"<e1(); } else if (inputstream[temp]!='#'||inputstream[temp]!=')') { cout<<"T'->^"<<<"t-="" else="" return="" right="0;" t()="" void="" {="" }="">FT'"<<<"t'-="" f();="" if(inputstream[temp]="='*')" t1()="" t1();="" void="" {="" }="">*FT'"<<<"t'-="" else="" f();="" if="" t1();="" temp++;="" {="" }="">^"<} } void f() { if(inputstream[temp]=='i') { cout<<"F->i"<if(inputstream[temp]=='(') { cout<<"F->(E)"<<<"f-="" e();="" if(inputstream[temp]="=')')" temp++;="" {="">(E)"<七、运行结果八、实验思考题语法分析的任务是什么?语法分析的任务是什么?答:语法分析器的任务是识别和处理比单词更大的语法单位,如:程序设计语言中的表达式、各种说明和语句乃至全部源程序,指出其中的语法错误;必要时,可生成内部形式,便于下一阶段处理。

实验二 语法分析程序设计与实现

实验二  语法分析程序设计与实现
/*类对象*/ /*预测分析表*/ /*输出分析栈*/
/*输出剩余串*/
/*输出对齐符*/
cout<<B[j]; cout<<"\t\t\t"; } void main() { int m,n,k=0,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; g1.origin='G'; strcpy(g1.array,"-TG"); g1.length=3; g2.origin='G'; g2.array[0]='^'; g2.length=1; s.origin='S';
g2
S->*FS s
T->/FS s1
S->^
s2
F->(E)
f
G->i
f1
分析表:
i
+
-
*
/
(
)
#
E
e
e
G
g
g1
g2
g2
T
t
t
S
s2
s2
s
s1
s2
s2
F
f1

语法分析实验报告

语法分析实验报告

一、实验目的1. 了解语法分析的基本概念和原理。

2. 掌握语法分析的方法和步骤。

3. 提高对自然语言处理领域中语法分析技术的理解和应用能力。

二、实验内容1. 语法分析的基本概念语法分析是指对自然语言进行结构分析,将句子分解成词、短语和句子成分的过程。

通过语法分析,可以了解句子的结构、语义和语用信息。

2. 语法分析方法语法分析方法主要有两种:句法分析和语义分析。

(1)句法分析:句法分析是指根据语法规则,对句子进行分解和组合的过程。

常见的句法分析方法有:词法分析、短语结构分析、句法分析。

(2)语义分析:语义分析是指对句子进行分析,以揭示句子所表达的意义。

常见的语义分析方法有:词汇语义分析、句法语义分析、语用语义分析。

3. 语法分析步骤(1)词法分析:将句子中的单词进行分类,提取词性、词义和词形变化等特征。

(2)短语结构分析:将词法分析得到的词组进行分类,提取短语结构、短语成分和短语关系等特征。

(3)句法分析:根据短语结构分析的结果,将句子分解成句子成分,分析句子成分之间的关系。

(4)语义分析:根据句法分析的结果,分析句子所表达的意义。

三、实验过程1. 实验环境:Python 3.8,NLTK(自然语言处理工具包)。

2. 实验步骤:(1)导入NLTK库。

(2)加载句子数据。

(3)进行词法分析,提取词性、词义和词形变化等特征。

(4)进行短语结构分析,提取短语结构、短语成分和短语关系等特征。

(5)进行句法分析,分解句子成分,分析句子成分之间的关系。

(6)进行语义分析,揭示句子所表达的意义。

四、实验结果与分析1. 词法分析结果实验句子:“我喜欢吃苹果。

”词性标注:我/代词,喜欢/动词,吃/动词,苹果/名词。

2. 短语结构分析结果实验句子:“我喜欢吃苹果。

”短语结构:主语短语(我),谓语短语(喜欢吃苹果)。

3. 句法分析结果实验句子:“我喜欢吃苹果。

”句子成分:主语(我),谓语(喜欢),宾语(吃苹果)。

4. 语义分析结果实验句子:“我喜欢吃苹果。

语法分析实验_2

语法分析实验_2

一、实验目的及内容实现下述我们定义的语言的语法分析器二、这种语言的程序结构很简单, 语法相当于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||strcmp(token,"if")==0||strcmp(token,"while")==0||strcmp(token,"for")==0| |strcmp(token,"read")==0||strcmp(token,"write")==0||strcmp(token,"{")== 0){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();}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();}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;}六、实验过程原始记录( 测试数据、图表、计算等)二元组信息运行结果截图:六、实验结果、分析和结论(误差分析与数据处理、成果总结等。

语法分析

语法分析

编译原理实验二·语法分析一、实验目的通过动手实践,使学生对构造编译系统的基本理论、编译程序的基本结构有更为深入的理解和掌握;使学生掌握编译程序设计的基本方法和步骤;能够设计实现编译系统的重要环节。

同时增强编写和调试程序的能力。

二、实验内容及要求对某特定语言A ,构造其语法规则。

该语言的语法单位如下:实现识别该语言的语法分析器, 可以选用:细化的递归下降程序,或者预测分析程序等。

按语法单位出现的顺序,返回识别出的语法单位序列出现的语法错误,可以指出错误位置,及错误原因。

出现的标识符存放在标识符表,整型常数存放在常数表三、实验过程1、文法描述语言A的文法的描述如下:程序P的文法:P → program ID;语句S文法:S → SA | SD | SW | SC | SIF赋值语句的文法:SA → ID := E | ID := NUM定义语句的文法:SD → var int ID D’D’→ ,ID D’|ε循环语句的文法:SW → while B do S判断语句的文法:SIF → if B then S | if B then S else S复合语句的文法:SC → begin S C’C’→ ;S C’| ;end布尔表达式B的文法:B → TB′B′→ and TB′|εT → FT′T′→ or FT′|εF → not F |(B)| E rop E | Erop → > | < | >= | <= | <> | =算术表达式E的文法(此中的T、T’和F与上面不同):E → TE'E'→ + TE' | εT → FT'T' → * FT' | εF → (E) | I注:ID与NUM的文法与语法分析器中的定义相同。

2、单词种别定义3、运行环境本次实验采用win-tc进行代码的编写和编译及运行程序的运行环境为windows4、关键算法描述本程序采用细化的递归下降程序进行描述,所用到的主要函数有:main() //主函数,程序的入口P() //程序P文法判定函数S(int i) //语句S文法实现程序,i表示递归层数,下同SA(int i) //赋值语句文法实现程序SD(int i) //定义语句文法实现程序SW(int i) //循环语句文法实现语句SIF(int i) //判断语句文法实现语句SC(int i) //复合语句文法实现判断语句E() //算数表达式B() //布尔表达式errProc(int type) //出错处理语句,参数type表示错误类型,此函数与词法分析中的出错函数相同,是在原函数的基础上添加新的错误类型struct binary *lexicalAnalyze() //词法分析主函数,本程序通过此函数实现了与词法分析程序的连接语句S的程序流程图如下所示:主函数main()程序流程图如下所示:其他的文法分析函数SA()、SD()、SW()、SIF()、SC()、E()、B()和P()按照文法的产生式就可以得到具体的代码了。

语法分析器实验报告

语法分析器实验报告

杭州电子科技大学班级: 12052312 专业: 计算机科学与技术实验报告【实验名称】实验二语法分析一. 实验目的编写一个语法分析程序, 实现对词法分析程序所提供的单词序列的语法检查和结构分析。

二. 实验内容利用编程语言实现语法分析程序, 并对简单语言进行语法分析。

2.1 待分析的简单语言的语法用扩充的BNF表示如下:⑴<程序>: : =begin<语句串>end⑵<语句串>: : =<语句>{;<语句>}⑶<语句>: : =<赋值语句>⑷<赋值语句>: : =ID: =<表达式>⑸<表达式>: : =<项>{+<项> | -<项>}⑹<项>: : =<因子>{*<因子> | /<因子>⑺<因子>: : =ID | NUM | (<表达式>)2.2 实验要求说明输入单词串, 以“#”结束, 如果是文法正确的句子, 则输出成功信息, 打印“success”, 否则输出“error”。

例如:输入begin a:=9; x:=2*3; b:=a+x end #输出success!输入x:=a+b*c end #输出error测试以上输入的分析, 并完成实验报告。

2.3 语法分析程序的算法思想(1)主程序示意图如图2-1所示。

图2-1 语法分析主程序示意图(2)递归下降分析程序示意图如图2-2所示。

(3)语句串分析过程示意图如图2-3所示。

图2-3 语句串分析示意图图2-2 递归下降分析程序示意图(4)statement 语句分析程序流程如图2-4.2-5.2-6.2-7所示。

图2-4 statement 语句分析函数示意图 图2-5 expression 表达式分析函数示意图图2-7 factor 分析过程示意图三.个人心得一、 通过该实验, 主要有以下几方面收获: 二、 对实验原理有更深的理解。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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;}五、实验过程原始记录( 测试数据、图表、计算等)二元组信息运行结果截图:六、实验结果、分析和结论(误差分析与数据处理、成果总结等。

相关文档
最新文档