递归下降语法分析程序的设计说明

合集下载

递归下降语法分析程序设计

递归下降语法分析程序设计

编译方法实验报告实验名称:简单的语法分析程序设计实验要求1.功能:对简单的赋值语句进行语法分析随机输入赋值语句,输出所输入的赋值语句与相应的四元式2.采用递归下降分析程序完成(自上而下的分析)3.确定各个子程序的功能并画出流程图4.文法如下:5.编码、调试通过采用标准输入输出方式。

输入输出的样例如下:【样例输入】x:=a+b*c/d-(e+f)【样例输出】(说明,语句和四元式之间用5个空格隔开)T1:=b*c (*,b,c,T1)T2:=T1/d (/,T1,d,T2)T3:=a+T2 (+,a,T2,T3)T4:=e+f (+,e,f,T4)T5:=T3-T4 (-,T3,T4,T5)x:=T5 (:=,T5,-,x)【样例说明】程序除能够正确输出四元式外,当输入的表达式错误时,还应能检测出语法错误,给出相应错误提示。

6.设计3-5个赋值语句测试实例,检验程序能否输出正确的四元式;当输入错误的句子时,检验程序能够给出语法错误的相应提示信息。

7.报告容包括:递归程序的调用过程,各子程序的流程图和总控流程图,详细设计,3-5个测试用例的程序运行截图及相关说明,有详细注释的程序代码清单等。

目录1.语法分析递归下降分析算法41.1背景知识41.2消除左递归62.详细设计及流程图62.1 函数void V( ) // V -> a|b|c|d|e...|z62.2 函数void A( ) // A -> V:=E72.3 函数void E() //E -> TE'72.4函数void T( ) // T -> FT'82.5函数void E1( ) //E'-> +TE'|-TE'|null82.6函数void T1() // T'-> *FT'|/FT'|null83.测试用例及截图93.1测试用例1及截图93.2测试用例2及截图103.3测试用例3及截图11代码清单111.语法分析递归下降分析算法1.1背景知识无回溯的自上向下分析技术可用的先决条件是:无左递归和无回溯。

语法分析程序(递归下降法)

语法分析程序(递归下降法)

语法分析程序(递归下降法)班级学号姓名:指导老师:一. 实验目的:1、学习语法分析的主要方法;2、熟悉复习词法分析的方法;3、判断表达式的正确性;4、熟悉C语言并提高动手能力;二. 实验内容:用递归下降分析法编写一个用于判断数学表达式是否正确的语法分析三.实验硬件和软件平台:INTEL C433MHz Cpu128Mb SDRAMTurbo C 2.0Microsoft Windows XP SP1四.步骤和算法描述:1.调用词法分析程序,转换表达式成为内号;2.调用语法分析程序,判断表达式正确与否;五.源程序:#include <stdio.h>#include <string.h>#include <io.h>#define yy swy=adv()FILE *fp1;char ch;int swy;main(){void CS();int chz(char str[15]);int adv();void CT();void E(); void EB();void ERROR();void ET();void F();void IT();void T();void sentence();clrscr();ch=' ';fp1=fopen("pas.txt","r");if(!fp1){printf("Can not open ljx.txt!!\n”); exit(0);}/* while(!feof(fp1)) */{yy;sentence();fclose(fp1);}}void ERROR(){printf("%d ERROR!\n ",swy); }void E(){T();while(swy==34||swy==35){yy;T();}}void T(){F();while(swy==36||swy==37){yy;F();}}void F(){if(swy==21||swy==22) yy;else if(swy==27){yy;E();if(swy==28) yy;else ERROR();}else ERROR();}void sentence(){ switch(swy){case 21 :{yy;if(swy==44){yy;E();}else ERROR();break;}case 1:CS();break;case 8:{yy;EB();if(swy!=4)ERROR();yy;sentence();break;}case 19:{yy;EB();if(swy!=4)ERROR();yy;sentence();}break;case 14:{yy;if(swy!=27) ERROR();yy;IT();if(swy!=28)ERROR();yy;break;}case 20:{yy;if(swy!=27) ERROR();yy;ET();if(swy!=28)ERROR();yy;break;}}}void CS(){yy;sentence();while(swy==24){yy;sentence();}if(swy==6)yy;else ERROR();}void CT(){if(swy==5){yy;sentence();}}void EB(){E();if(swy<=43&&swy>=38){yy;E();}else ERROR();}void IT(){if(swy!=21)ERROR();yy;while(swy==23){yy;if(swy!=21)ERROR();else ERROR();} }void ET(){E();while(swy==23){yy;E();}}int chz(char str1[15]){charstr[21][15]={"and","begin","const","div","do", "else","end","function","if","integer","not","or","pro cdure","program","read","real","then","type","var","while","write"};int i,max,min,mid;for(i=0;i<=14;i++)if(str1[i]<='Z'&&str1[i]>='A')str1[i]=str1[i]+'a'-'A';max=20;min=0;mid=10;while(min<=max){i=strcmp(str1,str[mid]);if(i==0) return mid;elseif(i>0){min=mid+1;mid=(max+min)/2;}else{max=mid-1;mid=(max+min)/2;}}return 0;}int adv(){char str1[15];int t,i=0,sk=0;float num,xs;if(ch==''||swy==24){fscanf(fp1,"%c",&(ch));printf("% c",ch);}while(!feof(fp1)&&i<100){if(((ch)>='a'&&(ch)<='z')||((ch)>='A'&&( ch)<='Z')){i=0;while((((ch)>='a'&&(ch)<='z')||((ch)>='A '&&(ch)<='Z')||((ch)>='0'&&(ch)<='9'))){str1[i]=(ch);i++;{fscanf(fp1,"%c",&(ch));printf("%c",ch);}}str1[i]='\0';t=chz(str1);if(!t)return 21;else return t;}else if(ch>='0'&&ch<='9'){num=0;while(ch>='0'&&ch<='9'){num=num*10+(ch)-'0';{fscanf(fp1,"%c",&(ch));printf("%c",ch); }}if(ch=='.'){xs=0.1;{fscanf(fp1,"%c",&(ch));printf("%c",ch); }while(ch>='0'&&ch<='9'){num+=(ch-'0')*xs;xs*=0.1;{fscanf(fp1,"%c",&(ch));printf("%c",ch); }}}return 22;}switch(ch){case '+' :{ch=' ';return 34;}case '*' :{ch=' ';return 36;}case ',' :{ch=' ';return 23;}case ';' :{ch=' ';return 24;}case '.' :{ch=' ';return 26;}case '(' :{ch=' ';return 27;}case ')' :{ch=' ';return 28;}case '[' :{ch=' ';return 29;}case ']' :{ch=' ';return 30;}case '{' :{ch=' ';return 45;}case '}' :{ch=' ';return 46;}case '-' :{ch=' ';return 35;}case '..' :{ch=' ';return 31;}case '/' :{ch=' ';return 37;}case '#' :{ch=' ';return 47;}case '<' : { {fscanf(fp1,"%c",&(ch));printf("%c",ch);}sk=1;if((ch)=='='){ch=' ';return 42;}else {return 39;}}case ':' :{{fscanf(fp1,"%c",&(ch));printf("%c",ch);}sk=1;if((ch)=='='){ch=' ';return 44;}else {return 25;}}case '>' :{{fscanf(fp1,"%c",&(ch));printf("%c",ch);}sk=1;if((ch)=='='){ch=' ';return 44;}else {return 40;}}default:break;}if(sk==0){fscanf(fp1,"%c",&(ch));printf( "%c",ch);}else sk=0;}}。

编译原理语法分析递归下降子程序实验报告

编译原理语法分析递归下降子程序实验报告

编译原理语法分析递归下降子程序实验报告编译课程设计-递归下降语法分析课程名称编译原理设计题目递归下降语法分析一、设计目的通过设计、编制、调试一个具体的语法分析程序,加深对语法分析原理的理解,加深对语法及语义分析原理的理解,并实现对文法的判断,是算符优先文法的对其进行FirstVT集及LastVT集的分析,并对输入的字符串进行规约输出规约结果成功或失败。

二、设计内容及步骤内容:在C++ 6.0中编写程序代码实现语法分析功能,调试得到相应文法的判断结果:是算符优先或不是。

若是,则输出各非终结符的FirstVT与LastVT集的结果,还可进行字符串的规约,输出详细的规约步骤,程序自动判别规约成功与失败。

步骤:1.看书,找资料,了解语法分析器的工作过程与原理2.分析题目,列出基本的设计思路1定义栈,进栈,出栈函数○2栈为空时的处理○3构造函数判断文法是否是算符文法,算符优先文法○4构造FirstVT和LastVT函数对文法的非终结符进行分析○5是算符优先文法时,构造函数对其可以进行输入待规约○串,输出规约结果○6构造主函数,对过程进行分析3.上机实践编码,将设计的思路转换成C++语言编码,编译运行4.测试,输入不同的文法,观察运行结果详细的算法描述详细设计伪代码如下:首先要声明变量,然后定义各个函数1.void Initstack(charstack &amp;s){//定义栈s.base=new charLode[20];s.top=-1; }2. void push(charstack&amp;s,charLode w){//字符进栈s.top++;s.base[s.top].E=w.E;s.base[s.top].e=w.e;}3. void pop(charstack&amp;s,charLode &amp;w){//字符出栈w.E=s.base[s.top].E; 三、w.e=s.base[s.top].e;s.top--;}4. int IsEmpty(charstack s){//判断栈是否为空if(s.top==-1)return 1;else return 0;}5.int IsLetter(char ch){//判断是否为非终结符if(ch=&#39;A&#39;&amp;&amp;ch= &#39;Z&#39;)return 1;else return 0;}6.int judge1(int n){ //judge1是判断是否是算符文法:若产生式中含有两个相继的非终结符则不是算符文法}7. void judge2(int n){//judge2是判断文法G是否为算符优先文法:若不是算符文法或若文法中含空字或终结符的优先级不唯一则不是算符优先文法8.int search1(char r[],int kk,char a){ //search1是查看存放终结符的数组r中是否含有重复的终结符}9.void createF(int n){ //createF函数是用F数组存放每个终结符与非终结符和组合,并且值每队的标志位为0;F数组是一个结构体}10.void search(charLode w){ //search函数是将在F数组中寻找到的终结符与非终结符对的标志位值为1 }分情况讨论://产生式的后选式的第一个字符就是终结符的情况//产生式的后选式的第一个字符是非终结符的情况11.void LastVT(int n){//求LastVT}12.void FirstVT(int n){//求FirstVT}13.void createYXB(int n){//构造优先表分情况讨论://优先级等于的情况,用1值表示等于}//优先级小于的情况,用2值表示小于//优先级大于的情况,用3值表示大于}14.int judge3(char s,char a){//judge3是用来返回在归约过程中两个非终结符相比较的值}15.void print(char s[],charSTR[][20],int q,int u,int ii,int k){//打印归约的过程}16. void process(char STR[][20],int ii){//对输入的字符串进行归约的过程}四、设计结果分两大类,四种不同的情况第一类情况:产生式的候选式以终结符开始候选式以终结符开始经过存在递归式的非终结符后再以终结符结束篇二:编译原理递归下降子程序北华航天工业学院《编译原理》课程实验报告课程实验题目:递归下降子程序实验作者所在系部:计算机科学与工程系作者所在专业:计算机科学与技术作者所在班级:xxxx作者学号:xxxxx_作者姓名:xxxx指导教师姓名:xxxxx完成时间:2011年3月28日一、实验目的通过本实验,了解递归下降预测分析的原理和过程以及可能存在的回溯问题,探讨解决方法,为预测分析表方法的学习奠定基础。

设计3语法分析之递归下降分析法剖析

设计3语法分析之递归下降分析法剖析

词法分析程序一、设计目的编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。

二、设计要求利用C语言编制递归下降分析程序,并对简单语言进行语法分析。

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三、设计说明(含主要算法的流程图)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-6 term分析函数示意图否是图2-7 factor分析过程示意图5、实验源代码#include "stdio.h"#include "string.h"char prog[100],token[8],ch;char *rwtab[6]={"begin","if","then","while","do","end"}; int syn,p,m,n,sum;int kk;factor();expression();yucu();term();statement();lrparser();scaner();main(){p=kk=0;printf("\nplease input a string (end with '#'): \n");do{ scanf("%c",&ch);prog[p++]=ch;}while(ch!='#');p=0;scaner();lrparser();getch();}lrparser(){if(syn==1){scaner(); /*读下一个单词符号*/yucu(); /*调用yucu()函数;*/if (syn==6){ scaner();if ((syn==0)&&(kk==0))printf("success!\n");}else { if(kk!=1) printf("the string haven't got a 'end'!\n"); kk=1;}}else { printf("haven't got a 'begin'!\n");kk=1;}return;}yucu(){statement(); /*调用函数statement();*/ while(syn==26){scaner(); /*读下一个单词符号*/if(syn!=6)statement(); /*调用函数statement();*/ }return;}statement(){ if(syn==10){scaner(); /*读下一个单词符号*/if(syn==18){ scaner(); /*读下一个单词符号*/expression(); /*调用函数statement();*/}else { printf("the sing ':=' is wrong!\n");kk=1;}}else { printf("wrong sentence!\n");kk=1;}return;}expression(){ term();while((syn==13)||(syn==14)){ scaner(); /*读下一个单词符号*/ term(); /*调用函数term();*/}return;}term(){ factor();while((syn==15)||(syn==16)){ scaner(); /*读下一个单词符号*/ factor(); /*调用函数factor(); */ }return;}factor(){ if((syn==10)||(syn==11)) scaner();else if(syn==27){ scaner(); /*读下一个单词符号*/expression(); /*调用函数statement();*/if(syn==28)scaner(); /*读下一个单词符号*/else { printf("the error on '('\n");kk=1;}}else { printf("the expression error!\n");kk=1;}return;}scaner(){ sum=0;for(m=0;m<8;m++)token[m++]=NULL;m=0;ch=prog[p++];while(ch==' ')ch=prog[p++];if(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))){ while(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))||((ch>='0')&&(ch< ='9'))){token[m++]=ch;ch=prog[p++];}p--;syn=10;token[m++]='\0';for(n=0;n<6;n++)if(strcmp(token,rwtab[n])==0) { syn=n+1;break;}}else if((ch>='0')&&(ch<='9')) { while((ch>='0')&&(ch<='9')) { sum=sum*10+ch-'0';ch=prog[p++];}p--;syn=11;}else switch(ch){ case '<':m=0;ch=prog[p++];if(ch=='>'){ syn=21;}else if(ch=='='){ syn=22;}else{ syn=20;p--;}break;case '>':m=0;ch=prog[p++];if(ch=='='){ syn=24;}else{ syn=23;p--;}break;case ':':m=0;ch=prog[p++];if(ch=='='){ syn=18;}else{ syn=17;p--;}break;case '+': syn=13; break; case '-': syn=14; break; case '*': syn=15;break; case '/': syn=16;break; case '(': syn=27;break; case ')': syn=28;break; case '=': syn=25;break; case ';': syn=26;break;case '#': syn=0;break;default: syn=-1;break;}}4、运行结果及分析输入 begin a:=9; x:=2*3; b:=a+x end # 后输出success!如图4-1所示:图4-1输入 x:=a+b*c end # 后输出 error 如图4-2所示:图4-2五、总结通过本次试验,了解了语法分析的运行过程,主程序大致流程为:“置初值”调用scaner函数读下一个单词符号调用IrParse结束。

编译原理之递归下降语法分析程序(实验)

编译原理之递归下降语法分析程序(实验)

编译原理之递归下降语法分析程序(实验)⼀、实验⽬的利⽤C语⾔编制递归下降分析程序,并对简单语⾔进⾏语法分析。

编制⼀个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。

⼆、实验原理每个⾮终结符都对应⼀个⼦程序。

该⼦程序根据下⼀个输⼊符号(SELECT集)来确定按照哪⼀个产⽣式进⾏处理,再根据该产⽣式的右端:每遇到⼀个终结符,则判断当前读⼊的单词是否与该终结符相匹配,若匹配,再读取下⼀个单词继续分析;不匹配,则进⾏出错处理每遇到⼀个⾮终结符,则调⽤相应的⼦程序三、实验要求说明输⼊单词串,以“#”结束,如果是⽂法正确的句⼦,则输出成功信息,打印“success”,否则输出“error”,并指出语法错误的类型及位置。

例如:输⼊begin a:=9;b:=2;c:=a+b;b:=a+c end #输出success输⼊a:=9;b:=2;c:=a+b;b:=a+c end #输出‘end' error四、实验步骤1.待分析的语⾔的语法(参考P90)2.将其改为⽂法表⽰,⾄少包含–语句–条件–表达式E -> E+T | TT -> T*F | FF -> (E) | i3. 消除其左递归E -> TE'E' -> +TE' | εT -> FT'T' -> *FT' | εF -> (E) | i4. 提取公共左因⼦5. SELECT集计算SELECT(E->TE) =FIRST(TE')=FIRSI(T)-FIRST(F)U{*}={(, i, *}SELECT(E'->+TE')=FIRST(+TE')={+}SELECT(E'->ε)=follow(E')=follow(E)={#, )}SELECT(T -> FT')=FRIST(FT')=FIRST(F)={(, i}SELECT(T'->*FT')=FRIST(*FT')={*}SELECT(T'->ε)=follow(T')=follow(T)={#, ), +}SELECT(F->(E))=FRIST((E)) ={(}SELECT(F->i)=FRIST(i) ={i}6. LL(1)⽂法判断 其中SELECT(E'->+TE')与SELECT(E'->ε)互不相交,SELECT(T'->*FT')与SELECT(T'->ε)互不相交,SELECT(F->(E))与SELECT(F->i)互不相交,故原⽂法为LL(1)⽂法。

递归下降程序实验报告

递归下降程序实验报告

一、实验目的1. 理解递归下降分析法的原理和实现方法。

2. 掌握递归下降分析程序的设计和调试。

3. 加深对编译原理中语法分析部分的理解。

二、实验环境1. 操作系统:Windows 102. 编程语言:C++3. 开发环境:Visual Studio 2019三、实验内容1. 递归下降分析法原理介绍2. 递归下降分析程序的设计与实现3. 递归下降分析程序的调试与测试四、实验步骤1. 递归下降分析法原理介绍递归下降分析法是一种自顶向下的语法分析方法,它将文法中的非终结符对应为分析过程中的递归子程序。

当遇到一个非终结符时,程序将调用对应的递归子程序,直到处理完整个输入串。

2. 递归下降分析程序的设计与实现(1)定义文法以一个简单的算术表达式文法为例,文法如下:E -> E + T| TT -> T F| FF -> ( E )| id(2)消除左递归由于文法中存在左递归,我们需要对其进行消除,消除后的文法如下:E -> T + E'E' -> + T E' | εT -> F T'T' -> F T' | εF -> ( E ) | id(3)设计递归下降分析程序根据消除左递归后的文法,设计递归下降分析程序如下:```cpp#include <iostream>#include <string>using namespace std;// 定义终结符const char PLUS = '+';const char MUL = '';const char LPAREN = '(';const char RPAREN = ')';const char ID = 'i'; // 假设id为'i'// 分析器状态int index = 0;string input;// 非终结符E的分析程序void E() {T();while (input[index] == PLUS) {index++;T();}}// 非终结符T的分析程序void T() {F();while (input[index] == MUL) {index++;F();}}// 非终结符F的分析程序void F() {if (input[index] == LPAREN) {index++; // 跳过左括号E();if (input[index] != RPAREN) {cout << "Error: Missing right parenthesis" << endl; return;}index++; // 跳过右括号} else if (input[index] == ID) {index++; // 跳过标识符} else {cout << "Error: Invalid character" << endl;return;}}// 主函数int main() {cout << "Enter an arithmetic expression: ";cin >> input;index = 0; // 初始化分析器状态E();if (index == input.size()) {cout << "The expression is valid." << endl;} else {cout << "The expression is invalid." << endl;}return 0;}```3. 递归下降分析程序的调试与测试将以上代码编译并运行,输入以下表达式进行测试:```2 +3 (4 - 5) / 6```程序输出结果为:```The expression is valid.```五、实验总结通过本次实验,我们了解了递归下降分析法的原理和实现方法,掌握了递归下降分析程序的设计与调试。

语法分析递归下降分析法

语法分析递归下降分析法

语法分析递归下降分析法递归下降分析法是一种常用的语法分析方法,它通过构建递归子程序来解析输入的语法串。

该方法可以分为两个步骤:构建语法树和构建语法分析器。

首先,我们需要构建语法树。

语法树是一个表示语言结构的树形结构,它由各类语法片段(非终结符)和终结符组成。

构建语法树的过程就是根据文法规则从根节点开始递归地扩展子节点,直到达到文法推导出的终结符。

具体来说,我们可以通过以下步骤来构建语法树:1.设计满足语言结构的文法规则。

文法规则定义了语法片段之间的关系和转换规则。

2.将文法规则转换为程序中的递归子程序。

每个递归子程序对应一个语法片段,并按照文法规则递归地扩展子节点。

3.设计词法分析器将输入的语法串分词为单个有效的词法单元。

4.从语法树的根节点开始,根据递归子程序逐步扩展子节点,直到达到终结符。

同时,将每一步的扩展结果记录在语法树中。

接下来,我们需要构建语法分析器。

语法分析器是一个根据语法规则判断输入语法串是否符合语法规则的程序。

它可以通过递归下降分析法来实现。

具体来说,我们可以通过以下步骤来构建语法分析器:1.定义一个语法分析器的函数,作为程序的入口。

2.在语法分析器函数中,根据文法规则调用递归子程序,分析输入的语法串。

3.每个递归子程序对应一个语法片段,它会对输入的语法串进行识别和匹配,并根据文法规则进行扩展。

4.如果递归子程序无法匹配当前的输入,那么意味着输入的语法串不符合文法规则。

5.如果递归子程序成功扩展,并继续匹配下一个输入,则语法分析器会一直进行下去,直到分析完整个语法串。

总结起来,递归下降分析法是一种简单而有效的语法分析方法。

它通过构建递归子程序来解析输入的语法串,并构造出对应的语法树。

虽然递归下降分析法在处理左递归和回溯等问题上存在一定的困难,但它仍然是一种重要的语法分析方法,被广泛应用于编译器和自然语言处理等领域。

语法分析——递归下降分析法

语法分析——递归下降分析法

实验2 语法分析——递归下降分析法一、实验目的1、通过该课程设计要学会用消除左递归的方法来使文法满足进行确定自顶向下分析的条件。

2、学会用C/C++高级程序设计语言来设计一个递归下降分析法的语法分析器;3、通过该课程设计,加深对语法分析理论的理解,培养动手实践的能力。

二、设计内容参考算数运算的递归子程序构造方法及代码,完成以下任务:构造布尔表达式的文法,并编写其递归子程序。

程序设计语言中的布尔表达式有两个作用,一是计算逻辑值,更多的情况是二,用作改变控制流语句中条件表达式,如在if-then,if-then-else或是while-do 语句中使用。

布尔表达式是由布尔算符(and,or,not)施予布尔变量或关系运算表达式而成。

为简单起见,以如下文法生成的布尔表达式作为设计对象:E→E and E | E or E | not E | i rop i | true | falsei→标识符|数字rop→>= | > | <= | < | == | <>以上文法带有二义性,并且未消除左递归,请对之处理后,再构造递归下降程序。

可适当减少工作量,暂时忽略id的定义,输入时直接用数字或字母表示。

三、语法分析器的功能该语法分析器能够分析词法分析器的结果,即单词二元式。

在输入单词二元式后,能输出分析的结果。

四、算法分析1、语法分析的相关知识;2、递归子程序法的相关理论知识;3、根据递归子程序法相关理论,具体针对文法的每一条规则编写相应得递归子程序以及分析过程等。

//在递归子程序的编写过程中,当要识别一个非终结符时,需时刻留意该非终结符的FIRST集与FOLLOW集。

程序示例一:G:P→begin d;X end G’:P→begin d;X endX→d;X|Y X→d;X|YY→Y;s|s Y→sZ Z→;sZ|ε相应的递归子程序设计如下:P(){ if(token==“begin“){ Read(token);If(token==’d’)Read(token);ElseERROR;If (token==’;’)Read(token);ElseERROR;If (token==’d’ || ‘s’)X();Else ERROR;If(token==’end’) OK;}Else ERROR;}X() //X→d;X|Y{if(token==’d’){read(token);if(token==’;’)read(token);elseERROR;If(token==’d’)X();Else if (token==’s’) //注意:对Y的识别也可以是在X的过程中一开始就进行,所以在最外层分支中,加上一个token==s的分支Y();Else ERROR;}Else ERROR;}Y() //Y→sZ{if(token==’s’){read(token);If(token==’;’ || ‘end’)Z();Else ERROR;Else ERROR;}Z() //Z→;s Z|ε{if(token==’;’){read(token);If(token==’s’)Read(token);Else ERROR;If(token==’;’)Z();Else if (token==’end’) // 类似的,这里对于读到end,也要最外层添加一个分支Return;Else ERROR;}Else ERROR;}程序示例二(参考代码):构造文法G[E]:E→E + T | T T→T * F | F F→(E)| d的递归子程序(即语法分析器)。

编译原理实验报告二递归下降语法分析程序 (1)

编译原理实验报告二递归下降语法分析程序 (1)

编译原理实验报告实验名称:编写递归下降语法分析程序实验类型:验证型实验指导教师:专业班级:姓名:学号:电子邮件:实验地点:实验成绩:日期:201 年 5 月 25 日一、实验目的通过设计、调试递归下降语法分析程序,实现用词法分析从源程序中分出各种单词并对词法分析程序提供的单词序列进行语法检查和结构分析,熟悉并掌握常用的语法分析方法。

明确语法分析器的功能,在词法分析的基础上进一步分析程序;加深对课堂教学的理解;提高语法分析方法的实践能力;通过本实验,应达到以下目标:1、掌握递归下降的结构模型。

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

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

二、实验过程有了第一次的经验,这次还是先画出流程图。

流程图如下:三、实验结果语法分析实验成功。

赋值时少写数字:缺少括号时:附(txt文档内容):程序运行后写入的:四、讨论与分析这个程序是在实验一的基础上写的,用的递归下降的方法。

不止能识别,还能判断一些语法的正误。

刚看书上附录的代码时,头都大了,觉得自己完成不了。

但是真正一步一步看下去,画出了流程图,就很清晰明白了。

一个函数嵌套一个函数,一步一步往细处走,刚开始是大体轮廓,然后就深入,直到最低层的判断。

书上的程序还是有一些漏洞,比如要写多个语句时,if,for,while在语句内不能加括号,不然只能分析至第一个,遇到“}”就结束了,所以在txt文件里写程序代码的时候要注意不能加{},这样才可以全部printf出来。

五、附录:关键代码(给出适当注释,可读性高)全部代码附vc++,这里粘贴主程序,以及各类函数。

int TESTparse();int TESTscan();int program();int compound_stat();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();#include<stdio.h>#include<ctype.h>int TESTscan();int TESTparse();FILE *fin,*fout;void main(){int es=0;es=TESTscan();if(es>0)printf("词法分析有错!编译停止!\n");else{printf("词法分析成功!\n");}if(es==0){es=TESTparse();if(es==0)printf("语法分析成功!\n");elseprintf("语法分析错误!\n");}}六、实验者自评这个实验比第一个有难度,是在第一个完成的基础上进行的。

递归下降分析实验报告

递归下降分析实验报告

一、实验目的通过本次实验,加深对递归下降分析法的理解,掌握递归下降分析法的原理和应用,并能够根据给定的文法编写相应的递归下降分析程序。

二、实验原理递归下降分析法是一种自顶向下的语法分析方法,它将文法中的每个非终结符对应一个递归过程(函数),分析过程就是从文法开始符触发执行一组递归过程(函数),向下推到直到推出句子。

递归下降分析法的前提是文法应满足以下条件:1. 消除二义性:确保文法中每个产生式都只有一个确定的意义。

2. 消除左递归:避免产生式出现如A -> A...A的形式。

3. 提取左因子:将产生式中的左因子提取出来,避免出现左递归。

4. 判断是否为LL(1)文法:LL(1)文法是指文法满足左递归和右递归的文法。

三、实验内容1. 根据给定的文法编写递归下降分析程序。

2. 对输入的符号串进行分析,判断其是否属于该文法。

3. 输出分析过程和结果。

四、实验步骤1. 阅读相关资料,了解递归下降分析法的原理和应用。

2. 根据给定的文法,设计递归下降分析程序的结构。

3. 编写递归下降分析程序,实现分析过程。

4. 编写测试用例,验证递归下降分析程序的正确性。

5. 分析实验结果,总结实验经验。

五、实验结果与分析1. 实验结果根据给定的文法,编写了递归下降分析程序,并进行了测试。

以下为部分测试用例及结果:(1)输入:eBaA输出:分析成功,属于该文法。

(2)输入:abAcB输出:分析成功,属于该文法。

(3)输入:dEdaC输出:分析成功,属于该文法。

(4)输入:edc输出:分析成功,属于该文法。

2. 实验分析通过本次实验,我们深入了解了递归下降分析法的原理和应用。

在编写递归下降分析程序的过程中,我们学会了如何根据文法设计程序结构,以及如何实现分析过程。

同时,我们还掌握了如何对输入的符号串进行分析,并输出分析结果。

实验过程中,我们遇到了一些问题,如消除二义性、消除左递归、提取左因子等。

通过查阅资料和不断尝试,我们成功解决了这些问题。

递归下降分析课程设计

递归下降分析课程设计

递归下降分析课程设计一、课程目标知识目标:1. 理解递归下降分析的基本概念,掌握其工作原理和应用场景。

2. 学会运用递归下降分析法对简单程序代码进行语法分析,识别语法错误。

3. 了解递归下降分析在编译原理中的应用,明确其在编程语言处理中的重要性。

技能目标:1. 能够运用递归下降分析法编写简单的语法分析程序,对给定程序进行语法检查。

2. 能够通过递归下降分析,识别并修复程序中的语法错误。

3. 能够运用所学知识,对实际编程问题进行递归下降分析,提高编程能力。

情感态度价值观目标:1. 培养学生对编译原理学科的兴趣,激发学习热情。

2. 培养学生的团队协作意识,学会与他人共同解决问题。

3. 培养学生的批判性思维,敢于质疑、勇于探索,形成积极向上的学习态度。

本课程针对高年级学生,课程性质为理论联系实际,注重培养学生的实际操作能力。

根据学生特点,课程设计力求深入浅出,通过实例分析,帮助学生更好地理解和掌握递归下降分析法的应用。

在教学过程中,关注学生的学习反馈,及时调整教学策略,确保课程目标的实现。

将课程目标分解为具体的学习成果,为后续教学设计和评估提供依据。

本章节教学内容主要包括以下三个方面:1. 递归下降分析基本概念:- 介绍语法分析的基本任务和递归下降分析法的原理。

- 解释递归下降分析在编译原理中的作用。

2. 递归下降分析法的应用:- 分析简单程序代码的语法结构,识别语法错误。

- 通过实例讲解递归下降分析法在实际编程中的应用。

教学大纲安排:- 第一节课:语法分析基本概念,递归下降分析法原理。

- 第二节课:简单程序代码的递归下降分析实例。

3. 编写递归下降分析程序:- 指导学生编写简单的递归下降分析程序,进行语法检查。

- 分析实际编程中遇到的语法问题,运用递归下降分析法进行解决。

教学大纲安排:- 第三节课:递归下降分析程序编写方法。

- 第四节课:递归下降分析在编程实践中的应用。

教材章节关联:本教学内容与教材中关于编译原理、语法分析以及递归下降分析的相关章节紧密关联。

实验2 递归下降语法分析

实验2 递归下降语法分析

实验二递归下降语法分析一、实验目的构造文法的语法分析程序,要求采用递归下降语法分析方法对输入的字符串进行语法分析,进一步掌握递归下降的语法分析方法。

二、实验内容编写为一上下文无关文法(文法如下)构造其递归下降语法分析程序,并对任给的一个输入串进行语法分析检查。

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

E-->E+T|TT-->T*F|FF-->(E)|i三、实验参考:算法思想为每个非终结符设计一个识别的子程序,寻找该非终结符也就是调用相应的子程序。

由于单词在语法分析中作为一个整体,故在语法识别中仅使用其内码。

在这里将词法分析作为语法分析的一个子程序,当语法分析需要单词时,就调用相应的词法分析程序获得一个单词。

语法分析的作用是识别输入符号串是否是文法上定义的句子,即判断输入符号串是否是满足“程序”定义的要求。

也就是当语法识别程序从正常退出表示输入符号串是正确的“程序”;若从出错退出,则输入符号串不是正确的“程序”。

出错时,可以根据读字符的位置判断出错的位置。

四、实验说明:1.时间安排:安排在“词法分析”后。

2.实验环境:WINDOWS下,工具为Visual C++ 6.0五、上交:程序源代码;已经测试通过的3组数据(全部存在一个文本文件test1.txt中,以“第一组输入/输出;第二组输入/输出;第三组输入/输出”的顺序存放);实验报告:实验结果和分析中应包括:(1)功能描述:该程序具有什么功能?(2)程序结构描述:函数调用格式、参数含义、返回值描述、函数功能;另外可以附加函数之间的调用关系图、程序总体执行流程图(参考课本第二章)。

(3)实验总结:你在编程过程中花时多少?多少时间在纸上设计?多少时间上机编程和调试?多少时间在思考问题?遇到了哪些难题?你是怎么克服的?你对你的程序的评价?你的收获有哪些?。

递归下降语法分析实验报告

递归下降语法分析实验报告

编译原理实验报告一、实验目的:(1)掌握自上而下语法分析的要求与特点。

(2)掌握递归下降语法分析的基本原理和方法。

(3)掌握相应数据结构的设计方法。

二、实验内容:编程实现给定算术表达式的递归下降分析器。

算术表达式文法如下:S→a|∧|(T)T→T,S|S三、设计说明:首先改写文法为LL(1)文法;然后为每一个非终结符,构造相应的递归过程,过程的名字表示规则左部的非终结符;过程体按规则右部符号串的顺序编写。

四、设计分析这个题目属于比较典型的递归下降语法分析。

需要先将原算术表达式方法改写为LL(1)文法为:S→a|∧|(T)T→ST’T’→,ST’|ε然后再为每个非终结符设计一个对应的函数,通过各函数之间的递归调用从而实现递归下降语法分析的功能。

具体方法为:(1)当遇到终结符a时,则编写语句If(当前读到的输入符号==a)读入下一个输入符号(2)当遇到终结符∧时,则编写语句If(当前读到的输入符号==∧)读入下一个输入符号(3)当遇到终结符﹙时,则编写语句If(当前读到的输入符号==﹙)读入下一个输入符号(4)当遇到非终结符T时,则编写scaner()函数读取下一个单词符号并将它放在全程变量sym中(5)当遇到非终结符S时,则编写S()函数(6)当遇到非终结符T’时,则编写T’()(7)当遇到终结符,时,则编写语句If(当前读到的输入符号==,)读入下一个输入符号(8)当遇到非终结符T时,则编写T()五、实验代码#include"stdio.h"void S();void T();void scaner();void error();char sym;char s[100];int i=0;int main(){printf("请输入一个语句,以#号结束语句(直接输入#号推出)\n");scanf("%s",&s);scaner();S();if (sym=='#'){printf("success");return 1;}else{printf("fail");return 0;}}void scaner(){sym=s[i];i++;}void T'(){if(sym==','){scaner();S();T'();}else if(sym!=')')error();}void error(){printf("语句有误!\n");}void T(){S();T'();}void S(){if (sym=='a'||sym=='^')scaner();else if(sym=='('){scaner();T();if(sym==')')scaner();elseerror();}elseerror();}六、测试用例和实验结果(1)输入a,预期显示语句正确!(2)输入∧,预期显示语句正确!(3)输入(a,b),预期显示语句有误!(4)输入(a ,a),预期显示语句正确!(5)输入(a,(a,a)),预期显示语句正确!七、测试结果截图(1)输入a的测试结果(2)输入^的测试结果(3)输入(a,b)的测试结果(4)输入(a ,a)的测试结果(5)输入(a,(a,a))测试结果八、实验总结通过该实验,我深入的学习了递归下降分析法的内容和原理,它是确定的自上而下的分析法,这种分析法是要求文法是LL(1)的,它的基本思想是对文法中的每个非终结符编写一个函数,每个函数的功能是识别由该终结符所表示的语法成分,由于描述语言的文法常常是递归定义的,因此相应的这组函数必然是相互递归的方式进行调用的,所以将此种分析法称为递归下降分析法。

实验递归下降语法分析程序设计

实验递归下降语法分析程序设计
void input1()。
void output()。
void main() /*递归分析*/
{
int f,p,j=0。
char x。
d[0]='E'。d[1]='='。d[2]='>'。d[3]='T'。d[4]='G'。d[5]='#'。
printf("请输入字符串(长度<50,以#号结束)\n")。
实验二递归下降语法分析程序设计
[实验目的]:
1.了解语法分析的主要任务。
2.熟悉编译程序的编制。
[实验内容]:根据某文法,构造一基本递归下降语法分析程序。给出分析过程中所用的产生式序列。
[实验要求]:
1.构造一个小语言的文法,例如,Pascal语言子集的文法,考虑其中的算术表达式文法:
G[<表达式>]:G[E]:
交各班课代表汇总后,由课代表打包后,发送至老师的邮箱
班级命名规则:2013-14医智(1)实验二
截止日期:第14周周五晚11点30分
测试的结果举例
源代码:
#include <stdio.h>
#include <dos.h>
#include <stdlib.h>
#include <string.h>
char a[50],b[50],d[200],e[10],ch。
}
int T()
{
int f,t。
printf("%d\tT-->FS\t",total)。total++。
e[0]='T'。e[1]='='。e[2]='>'。e[3]='F'。e[4]='S'。e[5]='#'。

实验报告四递归下降语法分析程序设计

实验报告四递归下降语法分析程序设计

实验报告四递归下降语法分析程序设计《编译原理》实验报告实验序号: 4 实验项⽬名称:递归下降语法分析程序设计SELECT(E’ →ε)={ε,),#}对T SELECT(T→FT’)={(,i}对T’ SELECT(T’ →*FT’)={ * }SELECT(T’ →⁄FT’)={ ⁄ }SELECT(T’ →ε)={ε,+,?,),#}对F SELECT(F→(E) )={ ( }SELECT(F→i)={ i }∴SELECT(E’ →+TE’)∩SELECT(E’ →?TE’)∩SELECT(E’ →ε)=ΦSELECT(T’ →*FT’)∩SELECT(T’→⁄FT’)∩SELECT(T’ →ε)=ΦSELECT(F→(E) )∩SELECT(F→i)= Φ由上可知,有相同左部产⽣式的SELECT集合的交集为空,所以⽂法是LL (1)⽂法。

因此,转化后的⽂法可以⽤递归下降分析法作语法分析。

(2)设计这⾥采⽤递归下降分析法形象描述递归⼦程序。

程序中将要⽤到的⼏个重要数据如下:⼀个全局变量ch,存放由⽂件输⼊得到的字符。

⼀个函数宏READ(ch),实现读取⽂件中的字符。

五个⼦函数:P(E)、P(E’)、P(T)、P(T’)、P(F)。

(3)程序代码如下/******************************************************************** ***** ⽂件名:ana.c* ⽂件描述:递归下降语法分析器。

分析如下⽅法:* E->E+T | E-T | T* T->T*F | T/F |F* F->(E) | i* 输⼊:每⾏含⼀个表达式的⽂本⽂件。

* 输出:分析成功或不成功信息。

* 创建⼈:余洪周 2006-12-8* 版本号:1.0********************************************************************* **/#include#include#define READ(ch) ch=getc(fp) /*宏:READ(ch)*/char ch; /*声明为全局变量*/int right=0;FILE *fp;struct struCH{char ch;struct struCH *next;}struCH,*temp,*head,*shift;/*head指向字符线性链表的头结点*//*shift指向动态建成的结点(游标)*/void main(int argc,char *argv[]){void E (); /* P(E) */void E1(); /* P(E')*/void T (); /* P(T) */void T1(); /* P(T')*/void F (); /* P(F) */int errnum=0,k=0,m=0,countchar=0,rownum;int charerr=0; /*开关控制量*//************************以只读⽅式打开⽂件*********************/ if((fp=fopen(argv[1],"r"))==NULL){printf("\n\tCan not open file %s,or not exist it!\n",argv[1]);exit(0); /*⽂件不存在or打不开时,正常退出程序*/}else printf("\n\tSuccess open file: %s\n",argv[1]); /*成功打开⽂件*//******************遍历整个⽂件检测是否有⾮法字符********************//*如果⽤while(!feof(fp))语⾔,将会多出⼀个字符*所以这⾥采⽤以下⽅法遍历整个⽂件检测其否有⾮法字符*//*[1]计算⽂件中字符数量*/while(!feof(fp)){READ(ch); /*这⾥读取字符只是让⽂件指针往前移*/countchar++; /*统计⽂件中的字符数(包括换⾏符及⽂件结束符)*/}rewind(fp); /*将fp⽂件指针重新指向⽂件头处,以备后⾯对⽂件的操作*/if(countchar==0){ /*空⽂件*/printf("\t%s is a blank file!\n",argv[1]);exit(0); /*正常退出本程序*/}/*[2]开始遍历⽂件*/while(k<(countchar-1)){ /*加换⾏符后countchar仍多了⼀个,不知为何*/ ch=getc(fp);if(!(ch=='('||ch==')'||ch=='i'||ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='#'||ch=='\n')){ charerr=1;errnum++; /*charerror出错标记,errnum统计出错个数*/}k++;}rewind(fp); /*将fp⽂件指针重新指向⽂件头处,以备后⾯的建链表操作*/if(charerr==1){ /*⽂件中有⾮法字符*/printf("\n\t%d Unindentify characters in file %s \n",errnum,argv[1]);exit(0); /*正常退出本程序*/}/*******************⾮空且⽆⾮法字符,则进⾏识别操作*****************/for(rownum=1;m<(countchar-1);rownum++){ /*识别所有⾏,rownum记录⾏号*/ /*初始变量及堆栈和*/right=1;/*初始存放待识别的表达式的线性链表头*/shift=malloc(sizeof(struCH));/**/shift->next=NULL;head=shift;/*读取⼀⾏形成线性链表*/READ(ch);putchar(ch);m++;while(ch!='\n'&&m<(countchar)){ /*⾏末or到⽂件尾。

递归下降语法分析器实验报告

递归下降语法分析器实验报告

一、实验目的使用递归子程序法设计一个语法分析程序,理解自顶向下分析方法的原理,掌握手工编写语法分析程序的方法。

二、实验原理1. 基本原理递归下降法是语法分析中最易懂的一种方法。

它的主要原理是,对每个非终极符按其产生式结构构造相应语法分析子程序,其中终极符产生匹配命令,而非终极符则产生过程调用命令。

因为文法递归相应子程序也递归,所以称这种方法为递归子程序下降法或递归下降法。

其中子程序的结构与产生式结构几乎是一致的。

2. 文法要求递归下降法要满足的条件:假设A的全部产生式为Aα1|α2|……|αn ,则必须满足如下条件才能保证可以唯一的选择合适的产生式predict(Aαi)∩predict(Aαj)=Φ,当i≠j.3. 实现原理假设文法中有如下的产生式A1 | 2 | … | n,则应按如下方法编写语法分析子程序procedure A()begin if tokenPredict(A1) then θ(1) elseif tokenPredict(A2) then θ(2) else……if tokenPredict(An) then θ(n) elseerror()end其中对i =X1X2…Xn,θ(i) =θ’(X1); θ’(X2);…; θ’(Xn);● 如果XiVN,θ’(Xi)= Xi● 如果XiVT,θ’(Xi)= Match(Xi)● 如果Xi= , θ’(λ) = skip(空语句)三、实验要求1、使用递归下降分析算法分析表达式文法:exp ::= exp addop term | termaddop ::= + | -term ::= term mulop factor | factormulop ::= * | /factor ::= (exp) | number其中number可以是多位的十进制数字串(整数即可),因此这里还需要一个小的词法分析器来得到number的值。

2、该词法分析器以子程序形式出现,当需要进行词法分析时进行调用;3、能够识别正确和错误的表达式;4、在进行语法分析的过程中,计算输入表达式的值。

递归下降分析法课程设计

递归下降分析法课程设计

递归下降分析法课程设计一、课程目标知识目标:1. 学生能理解递归下降分析法的概念和原理;2. 学生能掌握递归下降分析法在语法分析中的应用;3. 学生能了解递归下降分析法与其它语法分析方法的区别和联系。

技能目标:1. 学生能运用递归下降分析法对简单程序设计语言的语法进行分析;2. 学生能通过递归下降分析法编写简单的语法分析程序;3. 学生能通过案例分析和团队合作,解决递归下降分析过程中的问题。

情感态度价值观目标:1. 学生对程序设计语言的学习产生兴趣,增强学习积极性;2. 学生在递归下降分析法的实践过程中,培养解决问题的能力和团队协作精神;3. 学生通过递归下降分析法的学习,认识到程序设计语言在计算机科学中的重要性。

课程性质:本课程为计算机科学领域的一门专业课程,旨在让学生掌握递归下降分析法的基本原理和应用。

学生特点:学生具备一定的程序设计基础,对语法分析有一定了解,但可能对递归下降分析法较为陌生。

教学要求:结合学生的特点,采用案例教学、团队合作等方式,使学生能够将递归下降分析法应用于实际语法分析中,提高学生的实践能力和理论知识水平。

在教学过程中,注重引导学生积极思考,培养学生的问题解决能力和创新意识。

通过本课程的学习,使学生在知识、技能和情感态度价值观方面取得具体的学习成果。

二、教学内容1. 引言:介绍语法分析在程序设计语言中的作用,引出递归下降分析法的重要性。

2. 递归下降分析法基本原理:- 语法分析的基本概念;- 递归下降分析法的定义;- 递归下降分析法的工作流程。

3. 递归下降分析法的应用:- 简单程序设计语言的语法分析;- 递归下降分析法的具体实现步骤;- 递归下降分析法在实际案例中的应用。

4. 递归下降分析法与其它语法分析方法的比较:- LL分析法;- LR分析法;- 与递归下降分析法的区别和联系。

5. 实践环节:- 编写简单的递归下降分析程序;- 分析和讨论递归下降分析过程中的问题;- 团队合作完成复杂语法分析任务。

递归下降语法分析程序设计

递归下降语法分析程序设计
return 1; } else if(str[index]>='a'&&str[index]<='z' ) { return 1; } else 报错请尝试更换浏览器或网络环境
#include<stdio.h> #include<string.h> char str[10]; int index=0; void E(); //E->TX; void X(); //X->+TX|-TX| e void T(); //T->FY void Y(); //Y->*FY |/fy| e void F(); //F->(E) | id int id(); //id int main() { int len; int m;
printf("请输入算数表达式:"); scanf("%s",str); len=strlen(str); str[len]='#'; str[len+1]='\0'; E(); printf("正确语句!\n"); strcpy(str,""); index=0;
return 0; } void E() { T(); X(); } void X() { if(str[index]=='+') { index++; T(); X(); } else if(str[index]=='-') { index++; T(); X(); } } void T() { F(); Y(); } void Y() { if(str[index]=='*') { index++; F(); Y(); } else if(str[index]=='/') { index++; F(); Y();

递归下降分析课程设计

递归下降分析课程设计

递归下降分析课程设计一、教学目标本课程的教学目标是使学生掌握递归下降分析的基本概念、原理和方法,能够运用递归下降分析解决简单的语言处理问题。

具体来说,知识目标包括:了解递归下降分析的基本原理,掌握递归下降分析的方法和技巧,理解递归下降分析在语言处理中的应用。

技能目标包括:能够运用递归下降分析方法设计和实现简单的语法分析器,能够运用递归下降分析方法解决简单的语言处理问题。

情感态度价值观目标包括:培养学生的创新意识和团队合作精神,提高学生对计算机科学和语言处理的兴趣和热情。

二、教学内容本课程的教学内容主要包括递归下降分析的基本概念、原理和方法。

具体来说,教学大纲如下:第1周:递归下降分析简介,递归下降分析的基本概念和原理。

第2周:递归下降分析的方法和技巧,递归下降分析的应用实例。

第3周:递归下降分析的设计和实现,递归下降分析在语言处理中的应用。

三、教学方法为了实现教学目标,我们将采用多种教学方法,包括讲授法、讨论法、案例分析法、实验法等。

通过多样化的教学方法,激发学生的学习兴趣和主动性,帮助学生更好地理解和掌握递归下降分析的知识和技能。

四、教学资源为了支持教学内容和教学方法的实施,我们将选择和准备适当的教学资源,包括教材、参考书、多媒体资料、实验设备等。

教学资源将能够丰富学生的学习体验,帮助学生更好地理解和掌握递归下降分析的知识和技能。

五、教学评估为了全面、客观地评估学生的学习成果,我们将采用多元化的评估方式。

评估内容包括平时表现、作业、考试等。

平时表现将根据学生在课堂上的参与度、提问和回答问题的表现来评估。

作业将包括练习题和项目任务,以考察学生对递归下降分析的理解和应用能力。

考试将包括笔试和上机考试,以考察学生的理论知识和实际操作能力。

评估方式将公正、客观,能够全面反映学生的学习成果。

六、教学安排本课程的教学安排将紧凑、合理,确保在有限的时间内完成教学任务。

教学进度将根据教学大纲进行,教学时间将安排在课堂上,教学地点将选择适合教学的环境。

递归下递语法分析

递归下递语法分析

递归下递语法分析递归下降语法分析是一种自上而下的分析方法,基于产生式规则和递归函数的方式来进行语法分析。

在递归下降语法分析中,每个非终结符对应一个递归函数,该函数负责对该非终结符所对应的产生式进行分析。

这种分析方法的优点是简单易懂,容易实现,但是对于左递归、回溯以及二义性文法的处理较为困难。

递归下降语法分析的核心思想是根据当前输入符号和预测分析表,选择适当的递归函数进行调用,直到遇到终结符或无法继续推导为止。

下面我们将详细介绍递归下降语法分析的步骤。

1.定义语法产生式规则:首先需要定义待分析的文法的产生式规则。

产生式规则由左部和右部组成,左部表示非终结符,右部表示由终结符和非终结符组成的字符串。

例如,对于表达式文法E->E+T,T,E为非终结符,+为终结符,T为非终结符,表示一个表达式可以是一个表达式加一个项,或者仅仅是一个项。

2.构建预测分析表:根据产生式规则,构建一个预测分析表。

预测分析表是一个二维表,由非终结符和终结符构成,表中的每个元素表示哪个产生式规则应该被应用。

例如,对于表达式文法,预测分析表可能如下所示:, + , * , id , ( , ) ,---,---,---,---,---,---,--E,-,-,T,T,-,T,F,-,F,F,-,F , - , - , id , (E), - ,表中的'-'代表无动作。

3.实现递归函数:根据预测分析表中的产生式规则,实现对应的递归函数。

每个非终结符对应一个递归函数,函数的实现根据当前输入符号和预测分析表中选择对应的产生式规则进行推导。

例如,对于表达式文法,可以定义如下的递归函数:```pythondef E(:if symbol == '+':match('+')TEelif symbol == 'id' or symbol == '(':TEelse:# Errordef T(:if symbol == '+':FTelif symbol == 'id' or symbol == '(':FTelse:# Errordef F(:if symbol == 'id':match('id')elif symbol == '(':match('(')Ematch(')')else:# Error```在每个递归函数中,首先需要判断当前输入符号与预测分析表的元素是否匹配,如果匹配则进行相应的操作(例如推导产生式、移动指针等),如果不匹配则报错。

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

编译方法实验报告实验名称:简单的语法分析程序设计实验要求1.功能:对简单的赋值语句进行语法分析随机输入赋值语句,输出所输入的赋值语句与相应的四元式2.采用递归下降分析程序完成(自上而下的分析)3.确定各个子程序的功能并画出流程图4.文法如下:5.编码、调试通过采用标准输入输出方式。

输入输出的样例如下:【样例输入】x:=a+b*c/d-(e+f)【样例输出】(说明,语句和四元式之间用5个空格隔开)T1:=b*c (*,b,c,T1)T2:=T1/d (/,T1,d,T2)T3:=a+T2 (+,a,T2,T3)T4:=e+f (+,e,f,T4)T5:=T3-T4 (-,T3,T4,T5)x:=T5 (:=,T5,-,x)【样例说明】程序除能够正确输出四元式外,当输入的表达式错误时,还应能检测出语法错误,给出相应错误提示。

6.设计3-5个赋值语句测试实例,检验程序能否输出正确的四元式;当输入错误的句子时,检验程序能够给出语法错误的相应提示信息。

7.报告容包括:递归程序的调用过程,各子程序的流程图和总控流程图,详细设计,3-5个测试用例的程序运行截图及相关说明,有详细注释的程序代码清单等。

目录1.语法分析递归下降分析算法 (5)1.1背景知识 (5)1.2消除左递归 (6)2.详细设计及流程图 (6)2.1 函数void V( ) // V -> a|b|c|d|e...|z . (6)2.2 函数void A( ) // A -> V:=E (7)2.3 函数void E() //E -> TE' (7)2.4函数void T( ) // T -> FT' (8)2.5函数void E1( ) //E'-> +TE'|-TE'|null (8)2.6函数void T1() // T'-> *FT'|/FT'|null (9)3.测试用例及截图 (9)3.1测试用例1及截图 (9)3.2测试用例2及截图 (10)3.3测试用例3及截图 (11)代码清单 (11)1.语法分析递归下降分析算法1.1背景知识无回溯的自上向下分析技术可用的先决条件是:无左递归和无回溯。

无左递归:既没有直接左递归,也没有间接左递归。

无回溯:对于任一非终结符号U的产生式右部x1|x2|…|xn,其对应的字的首终结符号两两不相交。

如果一个文法不含回路,也不含以ε为右部的产生式,那么可以通过执行消除文法左递归的算法消除文法的一切左递归(改写后的文法可能含有以ε为右部的产生式)。

文法的左递归消除算法:1、将文法G的所有非终结符排序为U1 ,U2 ,… ,Un;2、For(i=1;i++;i≥n){for j→1 to i-1把产生式Ui→Ujα替换成Ui→β1α| β2α|…|βmα;其中:Uj→ β1| β2 |… |βm 消除Ui产生式中的直接左递归;}3.化简改写之后的文法,删除多余产生式。

文法的直接左递归消除公式:直接左递归形式:U→Ux|y;其中:x,y∈(V N∪V T)* ,y不以U打头。

直接左递归的消除:U→yU‟U‟→xU‟|ε直接左递归的一般形式:U→Ux1|Ux2|…|Ux m|y1|y2|…|y n;其中:x i≠ε ,y i都不以U打头。

一般形式直接左递归的消除:U→y1U‟| y2U‟|…| y n U‟U‟→x1U‟| x2U‟| …| x m U‟|ε回溯的消除的前提是文法不得含有左递归,可提左因子来消除回溯。

1.2消除左递归根据实验中给出的文法,进行消除左递归及回溯,得到下列的式子A -> V:=EE -> TE'E'-> +TE'|-TE'|nullT -> FT'T'-> *FT'|/FT'|nullF -> V|(E)V -> a|b|c|d|e...|z2.详细设计及流程图根据消除左递归后的文法,可以编写相应的函数。

2.1 函数void V( ) // V -> a|b|c|d|e...|zvoid V() // V -> a|b|c|d|e...|z函数设计主要用来识别小写字母的,如果是小写字母的话,放入字符表,不是的话,输出语法错误。

函数比较简单,代码如下:if(islower(s[sym])){Table[list_n][0] = s[sym]; //把读取的小写字母存入符号表,便于分析是生成中间代码Table[list_n][1] = '\0';list_n++;sym++;}else{printf("Operand Errors!\n"); //运算对象错误SIGN=1;exit(0);}2.2 函数void A( ) // A -> V:=Evoid A() // A -> V:=E 函数主要用来实现赋值的操作,流程图如图1所示。

开始V( )s[sym]==':'&&s[sym+1]=='='sym+=2;E( );Y输出表达式N输出错误结束图1 A( ) 函数流程图2.3 函数void E() //E -> TE'函数E()里面主要递归调用函数T( )和E'( )。

当没有出现语法错误时就可正常的运行。

函数比较简单,代码如下:{if(SIGN==0){T();E1();}}2.4函数void T( ) // T -> FT'函数T( )里面主要递归调用函数F ( )和T''( )。

当没有出现语法错误时就可正常的运行。

函数比较简单,代码如下:if(SIGN==0){F();T1();}2.5函数void E1( ) //E'-> +TE'|-TE'|null函数void E1() //E'-> +TE'|-TE'|null,主要用来实现加减法的语义分析。

流程图如图2所示。

开始SIGN==0s[sym] == '+'||s[sym]=='-'输出三地址式和四元表达式p=sym; sym++T()Y E1()结束NN图2 E1 ( ) 函数流程图2.6函数void T1() // T'-> *FT'|/FT'|null函数void T1() // T'-> *FT'|/FT'|null ,主要用来实现乘除法的语义分析。

流程图如图3所示。

开始SIGN==0s[sym] == '*'||s[sym]=='/'输出三地址式和四元表达式p=sym; sym++F()Y T1()结束NN图3 T1 ( ) 函数流程图3.测试用例及截图3.1测试用例1及截图用例1为实验要求上的的用例。

测试结果图4所示。

图4 测试用例1及结果截图3.2测试用例2及截图用例2为出现大写字母,出现报错。

测试结果图5所示。

图5 测试用例2及结果截图3.3测试用例3及截图用例3为随意编写用例。

测试结果图6所示。

图6 测试用例3及结果截图代码清单#include<stdio.h>#include<stdlib.h>#include<string.h>#include <ctype.h>void A(); // A -> V:=Evoid E(); // E -> TE'void T(); // T -> FT'void E1(); // E'-> +TE'|-TE'|nullvoid T1(); // T'-> *FT'|/FT'|nullvoid F(); // F -> V|(E)void V(); // V -> a|b|c|d|e...|zchar s[50],n='1'; //s[50]用于存放输入的赋值表达式char Table[50][3]; //产生中间代码所需的符号表int SIGN,sym; //sym为s[50]中当前读入符号的下标int list_n=0; //符号表的下标/*消除左递归及回溯A -> V:=EE -> TE'E'-> +TE'|-TE'|nullT -> FT'T'-> *FT'|/FT'|nullF -> V|(E)V -> a|b|c|d|e...|z*/int main(){SIGN = 0; //SIGN用于指示赋值表达式是否出现错误sym=0;scanf("%s",&s);if( s[0] == '\0') //没有输入的情况直接退出return 0;A();if(s[sym]!='\0'&&SIGN==0){printf("ERROR!\n");exit(0);}return 0;}void A() // A -> V:=E{V();if(s[sym]==':'&&s[sym+1]=='=') //判断赋值号是否有拼写错误{sym+=2;E();printf("%s:=%s",Table[list_n-2],Table[list_n-1]);printf(" (:=,%s,-,%s)\n",Table[list_n-1],Table[list_n-2]);}else{printf("The assignment Symbol spelling mistakes!\n"); //赋值号拼写错误SIGN=1;exit(0);}}void V() // V -> a|b|c|d|e...|z{if(islower(s[sym])){Table[list_n][0] = s[sym]; //把读取的小写字母存入符号表,便于分析是生成中间代码Table[list_n][1] = '\0';list_n++;sym++;}else{printf("Operand Errors!\n"); //运算对象错误SIGN=1;exit(0);}}void E() //E -> TE'{if(SIGN==0){T();E1();}}void T() // T -> FT'{if(SIGN==0){F();T1();}}void E1() //E'-> +TE'|-TE'|null{int p;if(SIGN==0){if(s[sym] == '+'||s[sym]=='-'){p=sym; //用p记录出现'+'或'-'时sym的值sym++;T();char ch[3];ch[0] = 'T';ch[1] = n;ch[2] = '\0';if(s[p] == '+'){printf("%s:=%s+%s",ch,Table[list_n-2],Table[list_n-1]); //输出三地址代码printf(" (+,%s,%s,%s)\n",Table[list_n-2],Table[list_n-1],ch); //输出四元式}else{printf("%s:=%s-%s",ch,Table[list_n-2],Table[list_n-1]); //输出三地址代码printf(" (-,%s,%s,%s)\n",Table[list_n-2],Table[list_n-1],ch); //输出四元式}strcpy(Table[list_n-2],ch); //将当前结果归结式放在符号表中list_n--;n++;E1();}}}void T1() // T'-> *FT'|/FT'|null{int p;if(SIGN==0){if(s[sym] == '*'||s[sym]=='/'){p=sym;sym++;F();char ch[3];ch[0] = 'T';ch[1] = n;ch[2] = '\0';if(s[p] == '*'){printf("%s:=%s*%s",ch,Table[list_n-2],Table[list_n-1]); //输出三地址代码printf(" (*,%s,%s,%s)\n",Table[list_n-2],Table[list_n-1],ch);//输出四元式}else{printf("%s:=%s/%s",ch,Table[list_n-2],Table[list_n-1]); //输出三地址代码printf(" (/,%s,%s,%s)\n", Table[list_n-2],Table[list_n-1],ch);//输出四元式}strcpy(Table[list_n-2],ch); //将当前结果归结式放在符号表中list_n--;n++;T1();}}}void F() //F -> V|(E){if(SIGN==0){if(s[sym]=='('){sym++;E();if(s[sym]==')')sym++;else{printf("ERROR!\n");SIGN=1;exit(0);}}else if(islower(s[sym])) //判断s[sym]是否是小写字母V();else{printf("ERROR!\n");SIGN=1;exit(0);}}}。

相关文档
最新文档