实验三-递归下降法的语法分析器

合集下载

递归下降语法分析

递归下降语法分析

实验项目名称:递归下降语法分析实验学时: 6 同组学生姓名:实验地点:实验日期:实验成绩:批改教师:批改时间:一、实验目的和要求通过本实验,了解递归下降预测分析的原理和过程以及可能存在的回溯问题,探讨解决方法,为预测分析表方法的学习奠定基础。

分析递归下降子程序的优缺点。

二、实验仪器和设备硬件系统:586以上计算机、服务器要求内存256以上、Cpu 2.0GHz以上、Clinet内存128以上、CPU奔腾III以上,硬盘,光驱等软件系统:Visual Studio 2005中文版软件三、实验过程1、设计框架图1-1 递归下降程序框架图2、设计步骤1)给定文法:E→E+T|TT→T*F|FF→(E)|i2)构造FIRST()集和FOLLOW()集表2-1 FIRST()集和FOLLOW()集3、程序源代码using System;using System.Collections.Generic;using System.Text;namespace递归下降语法分析{public class Program{public static char []a=new char[50];public static char []b=new char[50];public static char []d=new char[200];public static char []e=new char[10];public static char ch;public static int n1,i1=0,flag=1,n=5;public static int total=0;/*步骤计数器*/public static int E1(){int f,t;Console.Write(total);Console.Write("\tE-->TG\t");total++;flag=1;input();input1();f=T();if (f==0) return(0);t=G();if (t==0) return(0);else return(1);}public static int E(){int f,t;Console.Write(total);Console.Write("\tE-->TG\t");total++;e[0]='E';e[1]='=';e[2]='>';e[3]='T';e[4]='G';e[5]='#'; output();flag=1;input();f=T();if (f==0) return(0);t=G();if (t==0) return(0);else return(1);}public static int T(){int f,t;Console.Write(total);Console.Write("\tT-->FS\t");total++;e[0]='T';e[1]='=';e[2]='>';e[3]='F';e[4]='S';e[5]='#';output();flag=1;input();input1();f=F();if (f==0) return(0);t=S();if (t==0) return(0);else return(1);}public static int G(){int f;if(ch=='+') {b[i1]=ch;Console.Write(total);Console.Write("\tG-->+TG\t");total++;e[0]='G';e[1]='=';e[2]='>';e[3]='+';e[4]='T';e[5]='G';e[6]='#'; output();flag=0;input();input1();ch=a[++i1];f=T();if (f==0) return(0);G();return(1);}Console.Write(total);Console.Write("\tG-->^\t");total++;e[0]='G';e[1]='=';e[2]='>';e[3]='^';e[4]='#';output();input();input1();return(1);}public static int S(){int f,t;if(ch=='*') {b[i1]=ch;Console.Write(total);Console.Write("\tS-->*FS\t");total++;e[0]='S';e[1]='=';e[2]='>';e[3]='*';e[4]='F';e[5]='S';e[6]='#'; output();flag=0;input();input1();ch=a[++i1];f=F();if (f==0) return(0);t=S();if (t==0) return(0);else return(1);}Console.Write(total);Console.Write("\tS-->^\t");total++;e[0]='S';e[1]='=';e[2]='>';e[3]='^';e[4]='#';output();flag=1;a[i1]=ch;input();input1();return(1);}public static int F(){int f;if(ch=='(') {b[i1]=ch;Console.Write(total);Console.Write("\tF-->(E)\t");total++;e[0]='F';e[1]='=';e[2]='>';e[3]='(';e[4]='E';e[5]=')';e[6]='#'; output();flag=0;input();input1();ch=a[++i1];f=E();if (f==0) return(0);if(ch==')') {b[i1]=ch;Console.Write(total);Console.Write("\tF-->(E)\t");total++;flag=0;input();input1();ch=a[++i1];}else {Console.Write("error\n");return(0);}}else if(ch=='i') {b[i1]=ch;Console.Write(total);Console.Write("\tF-->i\t");total++;e[0]='F';e[1]='=';e[2]='>';e[3]='i';e[4]='#';output();flag=0;input();input1();ch=a[++i1];}else {Console.Write("error\n");return(0);}return(1);}public static void input(){int j=0;for (;j<=i1-flag;j++)Console.Write(b[j]); /*输出分析串*/Console.Write("\t\t");Console.Write("\t\t",ch); /*输出分析字符*/ }public static void input1(){int j;for (j=i1+1-flag;j<n1;j++)Console.Write(a[j]); /*输出剩余字符*/ Console.Write("\n");}public static void output(){ /*推导式计算*/int m,k,j,q;int i=0;m=0;k=0;q=0;i=n;d[n]='=';d[n+1]='>';d[n+2]='#';n=n+2;i=n;i=i-2;while(d[i]!='>'&&i!=0) i=i-1;i=i+1;while(d[i]!=e[0]) i=i+1;q=i;m=q;k=q;while(d[m]!='>') m=m-1;m=m+1;while(m!=q) {d[n]=d[m];m=m+1;n=n+1;}d[n]='#';for(j=3;e[j]!='#';j++){d[n]=e[j];n=n+1;}k=k+1;while(d[k]!='=') {d[n]=d[k];n=n+1;k=k+1;}d[n]='#';//system("pause");}static void Main(string[] args){ /*递归分析*/int f,p,j=0;char x;d[0]='E';d[1]='=';d[2]='>';d[3]='T';d[4]='G';d[5]='#';Console.Write("请输入字符串(长度<50,以#号结束)\n");do{ch=(char)Console.Read();a[j]=ch;j++;}while(ch!='#');n1=j;ch=b[0]=a[0];Console.Write("步骤\t文法\t分析串\t\t分析字符\t剩余串\n");f=E1();if (f==0) return;if (ch=='#'){Console.Write("accept\n");p=0;x=d[p];while(x!='#') {Console.Write(x);p=p+1;x=d[p]; /*输出推导式*/ }}else {Console.Write("error\n");Console.Write("回车返回\n");Console.ReadLine();Console.ReadLine();return;}Console.Write("\n");Console.Write("回车返回\n");Console.ReadLine();Console.ReadLine();}}}程序输入输出举例:1、输入“(i+i)*i”,分析如下图所示:2、输入“i#”,分析如下图所示:3、输入“i+i#”,分析如下图所示:四、实验结果与分析通过本次实验基本掌握了语法分析的原理和递归下降子程序分析方法,并且能将学到的知识学以致用,提高了对代码的分析能力,掌握了递归下降语法的构造,对自上再而下的语法分析模式有了更好的认识和理解。

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

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

编译原理实验报告题目: 递归下降语法分析器学 院 计算机科学与技术 专 业 xxxxxxxxxxxxxxxx 学 号 xxxxxxxxxxxx 姓 名 宁剑 指导教师 xxxx20xx 年xx 月xx 日递归下降语法分析器装 订 线一、实验目的了解语法分析器的内部工作原理,通过在本次实验中运用一定的编程技巧,掌握对表达式进行处理的一种方法。

二、实验原理算术表达式的文法可以是(可以根据需要适当改变):E→E+E|E-E|E*E|E/E|(E)|i根据递归下降分析法或预测分析法,对表达式进行语法分析,判断一个表达式是否正确。

三、实验步骤(1) 准备:1. 阅读课本有关章节,确定算术表达式的文法;(设计出预测分析表);2. 考虑好设计方案;3. 设计出模块结构、测试数据,初步编制好程序。

(2) 上机调试,发现错误,分析错误,再修改完善。

教师根据学生的设计方案与学生进行探讨,以修改方案和代码。

(3)改造后的文法:E→E+T|E-T|TT→T*F|T/F|FF→F^|PP→c |id| (E)四、实验环境计算机VC++软件五、实验程序#include<stdio.h>#include<stdlib.h>#include<string.h>#include<ctype.h>#include<conio.h>void error();void terror();void Scanner();char sym=' ';int i=0;char strToken[30]={""};FILE *in;void E();void E1();void F();void Retract(char str[30]){for(int j=0;j<30;j++){str[j]=0;}}void Scanner(){sym=fgetc(in);if (isspace(sym)){while(1){if(isspace(sym)){sym=fgetc(in);}else break;}}if(isdigit(sym)){while(1){if (isdigit(sym)){strToken[i]=sym;i++;sym=fgetc(in);}else{printf("%s",strToken);i=0;Retract(strToken);fseek(in,-2,1);sym=fgetc(in);break;}}}else{if(sym=='+'){printf("+");}else if(sym=='-'){printf("-");}else if(sym=='*'){printf("*");}else if(sym=='/'){printf("/");}else if(sym=='^'){printf("^");}else if(sym=='('){printf("(");}else if(sym==')'){printf(")");}}}void F(){if(isdigit(sym)){Scanner();}else if (sym=='('){Scanner();E();if(sym==')'){Scanner();}else error();}else terror();}void T1(){if(sym=='*'||sym=='/'||sym=='^'){Scanner();F();T1();}}void T(){F();T1();}void E1(){if (sym=='+'||sym=='-'){Scanner();T();E1();}}void E(){T();E1();}void error(){printf("\nThis is a wrong phrase!\n");exit(0);}void terror(){printf("\nthis is a wrong parase2!\n");exit(0);}int main(){if((in=fopen("input.txt","r"))==NULL){printf("File can't open.");exit(0);}Scanner();E();if (sym!='#'){printf("\nSuccess.");}else{printf("\nFail.");}fclose(in);return 0;}六、实验结果及分析程序输入/输出示例:如参考C 语言的运算符。

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

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

语法分析程序(递归下降法)班级学号姓名:指导老师:一. 实验目的: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;}}。

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

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

编译原理之递归下降语法分析程序(实验)⼀、实验⽬的利⽤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.如果递归子程序成功扩展,并继续匹配下一个输入,则语法分析器会一直进行下去,直到分析完整个语法串。

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

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

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

编译原理语法分析器

编译原理语法分析器

编译原理语法分析器编译原理语法分析器是编译器中的重要组成部分,它负责将源代码解析成抽象语法树,为后续的语义分析和代码生成做准备。

本文将介绍语法分析器的原理、分类和常用算法。

一、语法分析器的原理语法分析器的主要任务是根据给定的文法定义,将源代码解析成一个个语法单元,并构建出一棵抽象语法树。

它通过递归下降、预测分析和LR分析等算法来实现。

1. 递归下降法递归下降法是一种基于产生式的自顶向下分析方法。

它从文法的开始符号出发,通过不断地推导和回溯,逐步地构建抽象语法树。

递归下降法易于理解和实现,但对左递归和回溯有一定的局限性。

2. 预测分析法预测分析法也是自顶向下的分析方法,它通过预测下一个输入符号来选择适当的产生式进行推导。

为了提高效率,预测分析法使用预测分析表来存储各个非终结符和终结符的关系。

3. LR分析法LR分析法是一种自底向上的分析方法,它使用LR自动机和LR分析表来进行分析。

LR自动机是一个有限状态控制器,通过状态转移和规约动作来解析源代码。

LR分析表存储了状态转移和规约的规则。

二、语法分析器的分类根据语法分析器的特性和实现方式,可以将其分为LL分析器和LR 分析器。

1. LL分析器LL分析器是基于递归下降法和预测分析法的一类分析器。

它从左到右、从左到右地扫描源代码,并根据预测分析表进行推导。

常见的LL分析器有LL(1)分析器和LL(k)分析器。

2. LR分析器LR分析器是基于LR分析法的一类分析器。

它先通过移进-归约的方式建立一棵语法树,然后再进行规约操作。

LR分析器具有强大的语法处理能力,常见的LR分析器有LR(0)、SLR(1)、LR(1)和LALR(1)分析器。

三、常用的语法分析算法除了递归下降法、预测分析法和LR分析法,还有一些其他的语法分析算法。

1. LL算法LL算法是一种递归下降法的改进算法,它通过构造LL表和预测分析表实现分析过程。

LL算法具有很好的可读性和易于理解的特点。

2. LR算法LR算法是一种自底向上的分析方法,它通过建立LR自动机和构造LR分析表来进行分析。

c语言_递归下降分析程序实验_共13页

c语言_递归下降分析程序实验_共13页

实验二递归下降语法分析程序的设计与实现、实验目的:加深对语法分析器工作过程的理解;加强对递归下降法实现语法分析程序的掌握;能够采用一种编程语言实现简单的语法分析程序;能够使用自己编写的分析程序对简单的程序段进行语法翻译。

、实验内容:在实验1的基础上,用递归下降分析法编制语法分析程序,语法分析程序的实现可以采用任何一种编程工具。

三、实验要求:1.对语法规则有明确的定义;2.编写的分析程序能够进行正确的语法分析;3.*对于遇到的语法错误,能够做出简单的错误处理,给出简单的错误提示,保证顺利完成语法分析过程;4.实验报告要求用文法的形式对语法定义做出详细说明,说明语法分析程序的工作过程,说明错误处理的实现*。

四、实验学时:4学时五、实验步骤:1.定义目标语言的语法规则;2.根据语法规则输入语句段,用递归下降分析的方法进行语法分析,直到结束;3.*对遇到的语法错误做出错误处理。

六、实验内容:1.编程实现给定文法的递归下降分析程序。

E—T|E+TT—F|T*FF—(E)|i2.(参考课本P74)对文法先进行消除左递归。

3.分析程序由一组递归过程组成,文法中每个非终结符对应一个过程几个全局过程和变量:ADVANCE,把输入串指示器IP指向下一个输入符号,即读入一个单字符号SYM,IP当前所指的输入符号ERROR,出错处理子程序每个非终结符有对应的子程序的定义,首先在分析过程中,当需要从某个非终结符出发进行展开(推导)时,就调用这个非终结符对应的子程序。

4.具体实现时:当遇到终结符,编写:if (当前读到的输入符号=i)读入下一个输入符号当遇到非终结符E时,编写语句:调用E()当遇到E-->编写语句if (当前读到的输入符号不属于Follow (E))Error();(4)当某个非终结符的规则有多个候选式时,按LL(1)文法的条件能唯一的选择一个候选式进行推导。

#in elude <iostream> using n ames pace std;char〃字符串的存入a[80];char sym; 〃单个的判断字符int//字符串下标i=0;void//功能识别函数E();void//功能识别函数E2();void//功能识别函数T();void//功能识别函数T2();void input(); // 输入函数void advance(); // 字符串小标进一函数5. 代码实现:#include <stdio.h> #include<dos.h>#include<stdlib.h> #include<string.h>char a[50] ,b[50],d[200],e[10];char ch;int n1,i1=0,flag=1,n=5;int total=0;/* 步骤计数器 */ int E();int E1();int T();int F();void input();void input1();void F(); //功能识别函数 int G();/*E*/ int S();/*T ' */voidoutput();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");do{scanf("%c",&ch);a[j]=ch;j++;}while(ch!='#');n1=j;ch=b[0]=a[0];printf("步骤吐文法\t分析串\t\t分析字符\t剩余串\n");f=E1();if (f==0) return;if (ch=='#'){printf("accept\n");int E1(){p=0; x=d[p];while(x!='#') {printf("%c",x);p=p+1;x=d[p];printf("error\n");printf(" 回车返回 \n");getchar();getchar();return;printf("\n");printf("回车返回 \n");getchar();getchar();式*/}else{ /*输出推导int f,t;printf("%d\tE-->TG\t",total);total++;flag=1;input();input1();f=T();if (f==0) return(0);t=G();if (t==0) return(0);else return(1);int E()int f,t;printf("%d\tE-->TG\t",total);total++;e[0]='E';e[1]='=';e[2]='>';e[3]= 'T';e[4]='G';e[5]='#';output();flag=1;input();input1();f=T();if (f==0) return(0);{t=G();printf("accept\n");int E1(){int f;if (t==0) return(0); else return(1);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]='#'; output(); flag=1; input(); input1(); f=F(); if (f==0) return(0); t=S(); if (t==0) return(0); else return(1);intT()in t G()if(ch=='+') {b[i1]=ch;printf("%d\tG-->+TG\t",total);total++;e[0]='G';e[1]='=';e[2]='>';e[3]='+';e[4]='T';e[5]='G' ;e[6]='#';output();flag=0;input();input1();ch=a[++i1];f=T();if (f==0)return(0);G();return(1);prin tf("%d\tG-->A\t",total);total++;e[0]='G';e[1]='=';e[2]='>';e[3]='A';e[4]=#;output();flag=1;input();input1();return(1);intS()int f,t;if(ch=='*') {b[i1]=ch;printf("%d\tS-->*FS\t",total);total++;e[0]='S';e[1]='=';e[2]='>';e[3]='*';e[4]='F';e[5]='S ';e[6]='#';output();flag=0;input();input1();ch=a[++i1];f=F();if (f==0) return(0);t=S();if (t==0) return(0);else return(1);}prin tf("%d\tS-->A\t",total);total++;e[0]='S';e[1]='=';e[2]='>';e[3]='A';e[4]=#;output();flag=1;a[i1]=ch;input();input1();}return(1); }intF()intf;if(ch=='(') {b[i1]=ch;printf("%d\tF-->(E)\t",total);total++;e[0]='F';e[1]='=';e[2]='>';e[3]='(';e[4]='E';e[5]=' )';e[6]='#';output();flag=0;input();input1();ch=a[++i1];f=E();if (f==0)return(0);if(ch==')') {b[i1]=ch;printf("%d\tF-->(E)\t",total);total++;flag=0;input();input1();ch=a[++i1];else{printf("error\n");return(0);}elseif(ch=='i') {b[i1]=ch;printf("%d\tF-->i\t",total);total++;e[0]='F';e[1]='=';e[2]='>';e[3]='i';e[4]='#';output();flag=0;input();input1();ch=a[++i1];else{printf("error\n");return(0);return(1)};voidinput()intj=0;for (;j<=i1-flag;j++)printf("%c",b[j/*输出分析串*/ ]);printf("\t\t");/*输出分析字符*/ printf("%c\t\t",ch);voidinput1()intj;for (j=i1+1-flag;j<n1;j++)/*输出剩余字符*/ printf("%c",a[j]);}int m,k,j,q;int i=0;m=0;k=0;q=0;i=n;d[n]='=';d[n+1]='>';d[n+2]='#';n=n+2;i=n;i=i-2;while(d[i]!='>'&&i!=0) i=i-1; i=i+1;while(d[i]!=e[0]) i=i+1;q=i;m=q;k=q;while(d[m]!='>') m=m-1;m=m+1;while(m!=q) {d[n]=d[m];m=m+1;n=n+1;printf("\n ");void output(){ /*推导式计算 */d[n]='#';for(j=3;e[j]!='#';j++){d[n]=e[j];n=n+1;k=k+1;while(d[k]!='=') {d[n]=d[k];n=n+1;k=k+1;d[n]='#';system("pause");}。

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

魏陈强 204168实验3 递归下降法的语法分析器一、实验目的学习用递归下降法构造语法分析器的原理,掌握递归下降法的编程方法。

二、实验内容用递归下降法编写一个语法分析程序,使之与词法分析器结合,能够根据语言的上下文无关文法,识别输入的单词序列是否文法的句子。

这里只要求实现部分产生式,文法的开始符号为program。

(完整的源语言的文法定义见教材附录,p394)program→ blockblock→{stmts }stmts→stmt stmts |。

stmt→id=expr;| if(bool)stmt| if( bool)stmt else stmt| while(bool)stmt| do stmt while(bool ) ;| break ;| blockbool →expr < expr| expr <= expr| expr > expr| expr >= expr&| exprexpr→ expr + term| expr - term| termterm→ term * factor| term / factor| factorfactor→ ( e xpr ) | id| num三、实验要求1.个人完成,提交实验报告。

(2.实验报告中给出采用测试源代码片断,及其对应的最左推导过程(形式可以自行考虑)。

测试程序片断:{i = 2;while (i <=100){sum = sum + i;i = i + 2;}}对应的推导过程为:#program block{stmts }{stmt stmts}{id=expr;stmts }{id=num;stmts }{id=num;stmt stmts }{id=num;while(bool)stmt stmts }{id=num;while(e xpr<= expr)stmt stmts }{id=num;while(id<= expr)stmt stmts }{id=num;while(id<= num)stmt stmts }{id=num;while(id<= num)block stmts },{id=num;while(id<= num){stmts }stmts }.......四、实验思路之前编写的词法分析器,能够将语句中的每一个词素都识别出来,因此,在此基础上,定义一个二维字符串数组finaltable[100][20],用于存放由词法分析器提取出来的每个词素,比如,i=2,则finaltable[0]=”id”,finaltable[1]=”=”,finaltable[2]=”num”。

并且,为了以后能够方便使用switch() case 语句,另外再定义一个一维整型数组finaltableint[100],用于存放一个数字和finaltable[100][20]中的字符串对应。

这里,我们定义if=100,for=200,else=300,while=400,do=500,float=600,int=700,break=800,< = 17,<= = 16,> = 15,>= = 14,+ = 13,&&=12,||=11,}=10,{=9,;=8;)=7,(=6,= = 5,== = 4,!= =3,/=2,id =1,keyword=0,num=99,*=18,- = 19。

然后依据语法分析的正则表达式,参照实验一类似中缀改后缀的写法以及课本40页的伪代码编写。

相比词法分析器,词法分析的时候,是以单个字符为一个单位,而语法分析,我们以字符串为单位,这些字符串即finaltable[100][20]中的字符串。

编写的过程中涉及几个问题,1、如何把每一步的迭代都显示出来对于这个问题,可以在每个非终结符函数的开头输出对应的迭代即可。

2、在应用文法的时候,应该首先消除左递归,这是至关重要的,该实验我们只要消除expr()和term()的左递归即可。

3、if语句二义性处理。

对于这个问题,我们只要再往后看一个字符串,看其是否是else,如果是,则匹配if( bool)stmt else stmt,否则匹配if( bool ) stmt。

4、对于空选择,如何处理一开始的时候,我选择暂时忽略。

五、实验代码#include<>#include<>#include <>/*】if=100,for=200,else=300,while=400,do=500,float=600,int=700,break=800,< = 17,<= = 16,> = 15,>= = 14,+ = 13,&&=12,||=11,}=10,{=9,;=8;)=7,(=6,= = 5,== = 4,!= =3,/=2,id =1,keyword=0,num=99,*=18,- = 19 */char*keyword[8]={"if","for","else","while","do","float","int","break"}; char keywordtable[20][20],re_keywordtable[20][20];char digittable[20][20],re_digittable[20][20];char otherchartable[20][20],re_otherchartable[20][20];char idtable[20][20],re_idtable[20][20];char notetable[20][20];char finaltable[100][20];int finaltableint[100];char word[20];~void initialize();void alpha();void digit();void error();void otherchar();void note();void print();void prin();void check();void program();void block();—void stmts();void stmt();void Bool();void expr();void expr1();void term();void term1();void factor();void match(char *t);int digit_num=0,keyword_num=0,otherchar_num=0,id_num=0,note_num=0; :int redigit_num=1,rekeyword_num=1,reotherchar_num=1,reid_num=1;int final_num=0,finalnum=0;int flag_error=0;int flagerror=0;char lookahead;void main(){printf("请输入要分析的语句:\n");initialize();lookahead=getchar();]while(1){if(isalpha(lookahead)){alpha();initialize();}else if(isdigit(lookahead)){digit();initialize();}}else if(lookahead=='\t'||lookahead==' '){;}else if(lookahead=='\n')break;else if(lookahead=='/'){lookahead=getchar();if(lookahead=='*')-{note();initialize();}else{ungetc(lookahead,stdin);strcpy(finaltable[final_num],"/");strcpy(otherchartable[otherchar_num++],"/");finaltableint[final_num++]=2;initialize();`}}else{otherchar();initialize();}lookahead=getchar();}check();if(flag_error==0);{printf("词法分析结果如下:\n");print();prin();program();if(finalnum==final_num)printf("语法分析完成!\n");}}void alpha()、{int i=1,flag;char ch;ch=lookahead;word[0]=ch;ch=getchar();while(isalpha(ch)||isdigit(ch)){word[i++]=ch;ch=getchar();}~ungetc(ch,stdin);flag=0;for(i=0;i<8;i++){if(strcmp(word,keyword[i])==0)flag=1;}if(flag==1){strcpy(keywordtable[keyword_num++],word);strcpy(finaltable[final_num],word);)if(strcmp(word,"if")==0)finaltableint[final_num++]=100;if(strcmp(word,"for")==0)finaltableint[final_num++]=200;if(strcmp(word,"else")==0)finaltableint[final_num++]=300;if(strcmp(word,"while")==0)finaltableint[final_num++]=400;if(strcmp(word,"do")==0)finaltableint[final_num++]=500;if(strcmp(word,"float")==0)]finaltableint[final_num++]=600;if(strcmp(word,"int")==0)finaltableint[final_num++]=700;if(strcmp(word,"break")==0)finaltableint[final_num++]=800;}else{strcpy(idtable[id_num++],word);strcpy(finaltable[final_num],"id");finaltableint[final_num++]=1;!}}void digit(){int i=1,flag;char ch;ch=lookahead;word[0]=ch;ch=getchar();while(isalpha(ch)||isdigit(ch)){{word[i++]=ch;ch=getchar();}ungetc(ch,stdin);flag=0;for(i=0;word[i]!='\0';i++){if(word[i]<'0'||word[i]>'9')flag=1;}]if(flag==1){strcpy(idtable[id_num++],word);strcpy(finaltable[final_num],"id");finaltableint[final_num++]=1;}else{strcpy(digittable[digit_num++],word);strcpy(finaltable[final_num],"num");finaltableint[final_num++]=99;—}}void otherchar(){char ch;ch=lookahead;switch(ch){case '!':{ch=getchar();,if(ch=='='){strcpy(otherchartable[otherchar_num++],"!=");strcpy(finaltable[final_num],"!=");finaltableint[final_num++]=3;}else{ungetc(ch,stdin);error();}!}break;case '=':{ch=getchar();if(ch=='='){strcpy(otherchartable[otherchar_num++],"==");strcpy(finaltable[final_num],"==");finaltableint[final_num++]=4;}(else{strcpy(otherchartable[otherchar_num++],"=");strcpy(finaltable[final_num],"=");finaltableint[final_num++]=5;ungetc(ch,stdin);}}break;case '(':strcpy(otherchartable[otherchar_num++],"(");¥strcpy(finaltable[final_num],"(");finaltableint[final_num++]=6; // ( 6break;case ')':strcpy(otherchartable[otherchar_num++],")");strcpy(finaltable[final_num],")");finaltableint[final_num++]=7; // ) 7break;case ';':strcpy(otherchartable[otherchar_num++],";");strcpy(finaltable[final_num],";");]finaltableint[final_num++]=8; // ; 8break;case '{':strcpy(otherchartable[otherchar_num++],"{");strcpy(finaltable[final_num],"{");finaltableint[final_num++]=9; // { 9break;case '}':strcpy(otherchartable[otherchar_num++],"}");strcpy(finaltable[final_num],"}");finaltableint[final_num++]=10; // } 10、break;case '||':strcpy(otherchartable[otherchar_num++],"||");strcpy(finaltable[final_num],"||");finaltableint[final_num++]=11; // || 11break;case '&&':strcpy(otherchartable[otherchar_num++],"&&");strcpy(finaltable[final_num],"&&");finaltableint[final_num++]=12; //&& 12break;,case '+':strcpy(otherchartable[otherchar_num++],"+");strcpy(finaltable[final_num],"+");finaltableint[final_num++]=13; // + 13break;case '-':strcpy(otherchartable[otherchar_num++],"-");strcpy(finaltable[final_num],"-");finaltableint[final_num++]=19; // - 19break;case '>':({ch=getchar();if(ch=='='){strcpy(otherchartable[otherchar_num++],">=");strcpy(finaltable[final_num],">=");finaltableint[final_num++]=14;} // >= 14else{strcpy(otherchartable[otherchar_num++],">");]strcpy(finaltable[final_num],">");finaltableint[final_num++]=15; // > 15ungetc(ch,stdin);}}break;case '<':{ch=getchar();if(ch=='='){?strcpy(otherchartable[otherchar_num++],"<=");strcpy(finaltable[final_num],"<=");finaltableint[final_num++]=16;} // <= 16else{strcpy(otherchartable[otherchar_num++],"<");strcpy(finaltable[final_num++],"<");finaltableint[final_num++]=17; //< 17ungetc(ch,stdin);};}break;case '*':strcpy(finaltable[final_num],"*");finaltableint[final_num++]=18; // * 18break;default:error();break;}}】void error(){flag_error=1;printf("出现错误,中止分析!\n");}void initialize(){int i;for(i=0;i<20;i++)%{word[i]='\0';}}void check(){int i,j,flag;strcpy(re_keywordtable[0],keywordtable[0]);for(i=1;i<keyword_num;i++){|flag=0;for(j=0;j<rekeyword_num;j++){if(strcmp(keywordtable[i],re_keywordtable[j])==0){flag=1;break;}}if(flag==0)strcpy(re_keywordtable[rekeyword_num++],keywordtable[i]); ~}strcpy(re_digittable[0],digittable[0]);for(i=1;i<digit_num;i++){flag=0;for(j=0;j<redigit_num;j++){if(strcmp(digittable[i],re_digittable[j])==0){flag=1;{break;}}if(flag==0)strcpy(re_digittable[redigit_num++],digittable[i]);}strcpy(re_otherchartable[0],otherchartable[0]);for(i=1;i<otherchar_num;i++){flag=0;{for(j=0;j<reotherchar_num;j++){if(strcmp(otherchartable[i],re_otherchartable[j])==0){flag=1;break;}}if(flag==0)strcpy(re_otherchartable[reotherchar_num++],otherchartable[i]);}(strcpy(re_idtable[0],idtable[0]);for(i=1;i<id_num;i++){flag=0;for(j=0;j<reid_num;j++){if(strcmp(idtable[i],re_idtable[j])==0){flag=1;break;|}}if(flag==0)strcpy(re_idtable[reid_num++],idtable[i]);}}void note(){char ch;int i=0;$ch=getchar();while(1){if(ch=='*'){ch=getchar();if(ch=='/')break;else{ungetc(ch,stdin);】word[i++]=ch;}}else{word[i++]=ch;}ch=getchar();}strcpy(notetable[note_num++],word);}>void print(){int i;//printf("Keywords:\n");if(keyword_num!=0)for(i=0;i<rekeyword_num;i++)printf("< %s, >\n",re_keywordtable[i]);//printf("\nDigits:\n");if(digit_num!=0)for(i=0;i<redigit_num;i++)(printf("< number,%s >\n",re_digittable[i]);//printf("\nOtherchars:\n");if(otherchar_num!=0)for(i=0;i<reotherchar_num;i++)printf("< comparison,%s >\n",re_otherchartable[i]);//printf("\nId:\n");if(id_num!=0)for(i=0;i<reid_num;i++)printf("< id,%s >\n",re_idtable[i]);if(note_num!=0){?printf("注释:\n");for(i=0;i<note_num;i++)printf("%s\n",notetable[i]);}printf("词法分析完成!\n");}void prin(){int i;finaltableint[final_num]='\0';{printf("语法分析结果如下:\n");for(i=0;i<final_num;i++)printf("%s",finaltable[i]);printf("\n语法分析过程如下:\n");}void program(){printf("program-->block\n");block();if(flagerror==1)&{error();return;}}void block(){if(flagerror==1){return;)}printf("block-->{stmts}\n");match("{");stmts();match("}");}void stmts(){if(flagerror==1){》return;}if(finaltableint[finalnum]==10){printf("stmts-->null\n");return;}printf("stmts-->{stmt stmts}\n");stmt();stmts();}(void stmt(){if(flagerror==1){return;}switch(finaltableint[finalnum]){case 1:printf("stmt-->id=expr\n");match("id");^match("=");expr();match(";");break;case 100:match("if");match("(");Bool();match(")");stmt();if(strcmp(finaltable[finalnum],"else")==0)%{printf("stmt-->if(bool) stmt else stmt\n");match("else");stmt();break;}else{printf("stmt-->{if(bool) stmt\n");break;}—case 400:printf("stmt-->while(bool) stmt\n");match("while");match("(");Bool();match(")");stmt();break;case 500:printf("stmt-->do stmt while(bool)\n");match("do");%stmt();match("while");match("(");Bool();match(")");match(";");break;case 800:printf("stmt-->break;\n");match("break");match(";");;break;default:printf("stmt-->block\n");block();break;}}void Bool(){if(flagerror==1),{return;}expr();switch(finaltableint[finalnum]){case 17:printf("bool-->expr<expr\n");match("<");expr();break;case 16:\printf("bool-->expr<=expr\n");match("<=");expr();break;case 15:printf("bool-->expr>expr\n");match(">");expr();break;case 14:printf("bool-->expr>=expr\n"); )match(">=");expr();break;default:printf("bool-->expr\n");expr();break;}}void expr()@{if(flagerror==1){return;}printf("expr-->term expr1\n");term();expr1();}void expr1(){{if(flagerror==1){return;}switch(finaltableint[finalnum]){case 13:printf("expr1-->+term expr1\n");match("+");term();expr1();[break;case 19:printf("expr1-->-term expr1\n");match("-");term();expr1();break;default:printf("expr1-->null\n");return;}@}void term(){if(flagerror==1){return;}printf("term-->factor term1\n");factor();term1();,}void term1(){if(flagerror==1){return;}switch(finaltableint[finalnum]){case 18:printf("term1-->*factor term1\n");:match("*");factor();term1();break;case 2:printf("term1-->/factor term1\n");match("/");factor();term1();break;default:;printf("term1-->null\n");return;}}void factor(){if(flagerror==1){return;}<switch(finaltableint[finalnum]){case 6:printf("fatcor-->(expr)\n");match("(");expr();match(")");break;case 1:printf("factor-->id\n");match("id");break;(case 99:printf("factor-->num\n");match("num");break;default:flagerror=1;break;}}void match(char *t)%{if(strcmp(finaltable[finalnum],t)==0) ;else{flagerror=1;return;}finalnum++;}。

相关文档
最新文档