第一句子网 - 唯美句子、句子迷、好句子大全
第一句子网 > 语法分析——简单判断条件语句 赋值语句 循环语句

语法分析——简单判断条件语句 赋值语句 循环语句

时间:2022-10-15 00:28:33

相关推荐

语法分析——简单判断条件语句 赋值语句 循环语句

语法分析小程序。简单判断赋值、条件、循环,代码块开始,结束

二、 实验要求

1.待分析的简单语言的语法

用扩充的EBNF表示如下:

<程序块>::= begin<语句>{;<语句>} end.

<语句>::= <赋值语句>|<条件语句>|<循环语句>

<赋值语句>::= IDENT:=<表达式>

<条件语句>::= if <条件>then <语句>

<循环语句>::= while <条件> do <语句>

<表达式>::= [+|-]<项>{(+|-)<项>}

<项>::= <因子>{(*|/)<因子>}

<因子>::= IDENT | NUMBER |‘(’<表达式>‘)’

<条件>::= <表达式><关系运算符><表达式>

<关系运算符>::= <>|=|<|<=|>|>=

2. 实验要求说明

输入单词串,以“.”结束,如果是文法正确的句子,则输出成功信息,否则输出失败信息,指出错误原因。需要系统地规划错误码。例如:

输入 begina:=2*3 end.

输出 syntaxparses success!

输入 beginx=4 end.

输出 Error 11: 没有检测到赋值语句的:=符号

输入beginx:=2;while x>0 do if x/2=0 then x:=(x/2) end.

输出 syntaxparses success!

3. 语法分析设计说明

采用递归下降分析程序。为每个非终结符编写一个子过程。

设计思路

1.变量说明

line 从终端读入的字符串;

p 当前所指位置在计数器,

ch 字符为

token 正在识别的单词字符串;

m 当前所指位置在计数器

num 整型常数

sym 每个单词符号种类

word 保留字表

Err 错误类型标记

flag 出错标记

2.函数说明

void getsym(); //判断输入字符类型

int block(); //程序快分析函数

void error(int i); //出错处理函数

void statement(); //语句处理函数

void expression(); //表达式处理函数

void term(); //项处理函数

void factor(); //因子处理函数

void condition(); //条件处理函数

void Relational_operator(); //表达式处理函数

void printSym(int i) //打印输入字符的类型

接下来举例说明几个重要函数

1).getsym()函数示意图

2).main()函数示意图

3)block()函数示意图

3).error()函数示意图

4). statement ()函数示意图

二、 实验截图

输入 begin a:=2*3 end.

输出 syntax parses success!

输入 begin x=4 end.

输出 Error 11: 没有检测到赋值语句的:=符号

输入begin x:=2;while x>0 do if x/2=0 then x:=(x/2) end.

输出 syntax parses success!

实验总结

1.这个结合上次作业增加了对注释部分的语句处理

2.为解决出错就直接函数返回增加了flag布尔型变量,处理出错的及时报错,函数返回

3.在出错处理上参考了现在主流的编译器gcc,g++,发现他们是遇到出错的点直接报错,递归不返回。

例如:begin x=4end.

这句话,缺少:=符号,但是编译器只报赋值符号缺少,不会返回报错赋值语句出错,语句出错,程序块出错这种错误。

但是如果有这个需求,只需要把flag一个一个递归返回传值就好

代码:

#include <bits/stdc++.h>using namespace std;/*变量说明:line从终端读入的字符串;当前所指位置在计数器 ptoken为存放的单词自身字符串;当前所指位置在计数器 mnumber整型常数sym每个单词符号种类*/enum symbol{period=0,ident=1,number=2,Plus=3,Minus=4,times=5,slash=6,eql=7,neq=8,lss=9,leq=10,gtr=11,geq=12,lparen=13,rparen=14,semicolon=15,becomes=16,beginsym=17,endsym=18,ifsym=19,thensym=20,whilesym=21,dosym=22,note=23,nil=24,};char line[100],token[10],ch;char s2[10];enum symbol sym;int p,m, num;char *word[6]= {"begin","end", "if","then","while","do"};int Err;bool flag=true;bool flag2=false;bool flag3=false;void getsym();int block();void error(int i);void statement();void expression();void term();void factor();void condition();void Relational_operator();int main(){freopen("t1.txt","r",stdin);//读了字符串, 直到遇.结束p=0;printf("\n please input a string(end with '.'): ");do{scanf("%c",&ch);line[p++]=ch;}while(ch!='.');line[p++]='\0';//逐个单词扫描;Err = 0;p=0;getsym();//当前扫描的单词存放在sym中block();if ((sym==0)&&(Err==0))printf("syntax parses success!\n");return 0;}void printSym(enum symbol sym){/************************************************************ TODO: 输出单词 *************************************************************/switch(sym){case period:return;case number:printf("%d ",num);break;case nil:printf("you have input a wrong string\n");break;case note://printf("this is notes\n");break;case Plus:printf("+");break;case Minus:printf("-");break;case times:printf("*");break;case slash:printf("/");break;case eql:printf("=");break;case neq:printf("><");break;case lss:printf("<");break;case leq:printf("<=");break;case gtr:printf(">");break;case geq:printf(">=");break;case lparen:printf("( ");break;case rparen:printf(") ");break;case semicolon:printf("; ");break;case becomes:printf(":= ");break;case beginsym:printf("\nbegin ");break;case endsym:flag3=true;printf("print( %s ) ",s2);printf("end\n");break;case ifsym:printf("if ");break;case thensym:printf("then ");break;case whilesym:printf("while ");break;case dosym:printf("do ");break;case ident:printf("%s ",token);break;default:break;}}void getsym(){for(m=0; m<8;m++) token[m++]=NULL;ch=line[p++];m=0;/**************************************************** ******** TODO: 单词识别 *************************************************************/while((ch==' '||ch=='\n')) ch=line[p++];//字母打头的字符串;标识符if((ch<='z'&&ch>='a')||(ch<='Z'&&ch>='A')){do{token[m++]=ch;ch=line[p++];}while((ch<='z'&&ch>='a')||(ch<='Z'&&ch>='A')||(ch<='9'&&ch>='0'));sym=ident;token[m++]='\0';ch=line[p--];for(int n=0;n<6;n++){if(strcmp(token,word[n])==0){if(n==0) sym=beginsym;else if(n==1) sym=endsym;else if(n==2) sym=ifsym;else if(n==3) sym=thensym;else if(n==4) sym=whilesym;else if(n==5) sym=dosym;break;}}/*TODO识别标识符IDENT和保留字*/}else if((ch<='9'&&ch>='0')){num=0;do{num=num*10+ch-'0';ch=line[p++];}while((ch<='9'&&ch>='0'));ch=line[p--];sym=number;/*TODO识别数字NUMBER*/}else {switch(ch){case ':'://赋值符号token[m++]=ch;ch=line[p++];if(ch=='='){sym=becomes;token[m++]=ch;}else{sym=nil;}break;case '<'://<=和<符号token[m++]=ch;ch=line[p++];if(ch=='='){token[m++]=ch;sym=leq;}else if(ch=='>'){token[m++]=ch;sym=neq;}else{sym=lss;p--;}break;case '>'://>=和>符号token[m++]=ch;ch=line[p++];if(ch=='='){sym=geq;token[m++]=ch;}else{sym=gtr;p--;}break;case '+':sym=Plus;token[m++]=ch;break;case '-':sym=Minus;token[m++]=ch;break;case '*':sym=times;token[m++]=ch;break;case '/':ch=line[p++];if(ch=='*'){//cout<<"in\n";char fr;//前面的一个符号fr='*';ch=line[p++];while(1){fr=ch;ch=line[p++];if(fr=='*'&&ch=='/') break;}sym=note;token[m++]=ch;}else{sym=slash;token[m++]=ch;p--;}break;case '=':sym=eql;token[m++]==ch;break;case '(':sym=lparen;token[m++]=ch;break;case ')':sym=rparen;token[m++]=ch;break;case ';':sym=semicolon;token[m++]=ch;break;case '.':sym=period;token[m++]=ch;break;case ' ':token[m++]=ch;break;default:sym=nil;break;}}token[m++]='\0';//如果想看分析的每一个sym,请打开这个注释printSym(sym);//处理语句分析中的注释if(sym==note) getsym();}void error(int i){switch (i){case 1:printf("Error %d: 没有检测到语句期望begin符号\n", i);break;case 2:printf("Error %d: 没有检测到赋值语句的 := 符号\n",i);break;case 3:printf("Error %d: 没有检测到条件语句的 then 符号\n",i);break;case 4:printf("Error %d: 没有检测到循环语句的 do 符号\n",i);break;case 5:printf("Error %d: 错误的句子!\n",i);break;case 6:printf("Error %d: 你写了数字!\n",i);break;case 7:printf("Error %d: 没有检测到 '(' 的 ')' 符号\n",i);break;case 8:printf("Error %d: 没有检测到因子\n",i);break;case 9:printf("Error %d: 没有检测到关系运算符\n",i);break;case 11:printf("Error %d: 没有检测到语句期望 end 符号\n", i);break;default:break;}flag=false;Err++;}int block(){//cout<<"程序块分析\n";if (sym != beginsym){error(1);}else{getsym();statement();//语句处理while (sym == semicolon){getsym();statement();//语句处理}if (sym != endsym&&flag){error(11);}getsym();}return 0;}void statement(){/************************************************ TODO: 语句处理(赋值/条件/循环) ************************************************/flag2=false;//cout<<"语句处理\n";if(sym==ident){flag2=true;flag3=false;for(int i=0;i<strlen(token)+1;i++)s2[i]=token[i];//赋值语句//cout<<"赋值语句分析\n";getsym();if(sym==becomes){getsym();expression();if(!flag3) printf(" print( %s ); ",s2);}else{error(2);//printf("Error!赋值语句左部标识符后面应是赋值号 ':='\n");return;}}else if(sym==ifsym){//条件语句//cout<<"条件语句分析\n";getsym();condition();if(sym==thensym){getsym();statement();}else{error(3);//printf("Error!条件语句条件后面应是 'then'\n");return;}}else if(sym==whilesym){//循环语句//cout<<"循环语句分析\n";getsym();condition();if(sym==dosym){getsym();statement();}else{error(4);//printf("Error!循环语句条件后面应是 'do'\n");return;}}else{error(5);//printf("错误的句子!\n");return;}if(sym==number){error(6);//printf("你写了数字!\n");return;}}void expression(){//cout<<"表达式处理\n";/*********************************************************** TODO: 表达式处理 ********************************************************/if(sym==Plus||sym==Minus){getsym();term();}else{term();while(sym==Plus||sym==Minus){getsym();term();}}}void term(){//cout<<"项处理\n";/*********************************************************** TODO: 项处理 ********************************************************/if(sym==times||sym==slash){getsym();factor();}else{factor();while(sym==times||sym==slash){getsym();factor();}}}void factor(){//cout<<"因子处理\n";/*********************************************************** TODO: 因子处理 ********************************************************/if(sym==ident||sym==number){getsym();}else if(sym==lparen){getsym();expression();if(sym==rparen) getsym();else{error(7);//printf("语法分析出错!请检查是否缺少 ')'\n");return;}}else{error(8);//printf("Error!缺少因子\n");return;}}void condition(){//cout<<"条件处理\n";/*********************************************************** TODO: 条件处理 ********************************************************/expression();//getsym();Relational_operator();getsym();expression();}void Relational_operator(){//cout<<"关系运算符处理\n";/*********************************************************** TODO: 关系运算符 ********************************************************/if(sym==neq||sym==eql||sym==lss||sym==leq||sym==gtr||sym==geq||sym==8||sym==9||sym==10||sym==11||sym==12||sym==13){//getsym();}else{error(9);//printf("Error!缺少关系运算符\n");return;}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。