一、实验目的:
利用C语言编制递归下降分析程序,并对简单语言进行语法分析。
编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。
二、实验原理
每个非终结符都对应一个子程序。
该子程序根据下一个输入符号(SELECT集)来确定按照哪一个产生式进行处理,再根据该产生式的右端:
- 每遇到一个终结符,则判断当前读入的单词是否与该终结符相匹配,若匹配,再读取下一个单词继续分析;不匹配,则进行出错处理
- 每遇到一个非终结符,则调用相应的子程序
三、实验要求说明
输入单词串,以“#”结束,如果是文法正确的句子,则输出成功信息,打印“success”,否则输出“error”,并指出语法错误的类型及位置。
例如:
输入begin a:=9;x:=2*3;b:=a+x end #
输出success
输入x:=a+b*c end #
输出‘end' error
四、实验步骤
1.待分析的语言的语法(参考P90)
2.将其改为文法表示,至少包含
–语句
–条件
–表达式
3. 消除其左递归
4. 提取公共左因子
5. SELECT集计算
6. LL(1)文法判断
7. 递归下降分析程序
实现源代码如下:
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 5 char prog[]="a+b*c#",token[20]; //输入程序段,单词符号 6 char ch; 7 int syn,p,m,n,sum;//单词符号类型syn,整数sum 8 char *rwtab[6] = {"begin","if","then","while","do","end"}; 9 10 void E(); 11 void T(); 12 void E1(); 13 void T1(); 14 void F(); 15 void error(); 16 17 void scaner(){ 18 for (n=0;n<20;n++) 19 token[n]=NULL; 20 m=0; 21 sum=0; 22 ch=prog[p++]; 23 while(ch==' '){ //跳过空格 24 ch=prog[p++]; 25 } 26 if(ch>='a'&&ch<='z'){ //判断单词 27 while(ch>='a'&&ch<='z'){ 28 token[m++]=ch; 29 ch=prog[p++]; 30 } 31 syn=10; 32 p--; 33 for(n=0;n<6;n++){ 34 if(strcmp(token,rwtab[n])==0){ 35 syn=n+1; 36 break; 37 } 38 } 39 } 40 else{ 41 if(ch>='0'&&ch<='9'){ //判断数字 42 while(ch>='0'&&ch<='9'){ 43 sum=sum*10+(ch-'0'); 44 ch=prog[p++]; 45 } 46 syn=11; 47 p--; 48 } 49 else{ 50 switch(ch){ 51 case '<': 52 token[m++]=ch; 53 ch=prog[p++]; 54 if(ch=='>'){ //<> 55 syn=22; 56 token[m++]=ch; 57 } 58 else if(ch=='='){ //<= 59 syn=21; 60 token[m++]=ch; 61 } 62 else{ //< 63 syn=20; 64 p--; 65 } 66 break; 67 68 case '>': 69 m=0; 70 token[m++]=ch; 71 ch=prog[p++]; 72 if(ch=='='){ //>= 73 syn=24; 74 token[m++]=ch; 75 } 76 else{ //> 77 syn=23; 78 p--; 79 } 80 break; 81 82 case ':': 83 m=0; 84 token[m++]=ch; 85 ch=prog[p++]; 86 if(ch=='='){ //:= 87 syn=18; 88 token[m++]=ch; 89 } 90 else{ //: 91 syn=17; 92 p--; 93 } 94 break; 95 96 case '+':syn=13;token[0]=ch;break; 97 case '-':syn=14;token[0]=ch;break; 98 case '*':syn=15;token[0]=ch;break; 99 case '/':syn=16;token[0]=ch;break; 100 case '=':syn=25;token[0]=ch;break; 101 case ';':syn=26;token[0]=ch;break; 102 case '(':syn=27;token[0]=ch;break; 103 case ')':syn=28;token[0]=ch;break; 104 case '#':syn=0;token[0]=ch;break; 105 default:syn=-1;token[0]=ch;break; 106 } 107 } 108 } 109 } 110 111 void E(){ 112 T(); 113 E1(); 114 } 115 116 117 118 void E1(){ 119 if (syn == 13){ 120 scaner(); 121 T(); 122 E1(); 123 } 124 else if(syn ==0 || syn == 28){ 125 126 } 127 else 128 error(); 129 } 130 131 void T(){ 132 F(); 133 T1(); 134 } 135 136 void T1(){ 137 if(syn == 15){ 138 scaner(); 139 F(); 140 T1(); 141 } 142 else if (syn == 0 || syn == 28 || syn ==13){ 143 144 } 145 else 146 error(); 147 } 148 149 void F(){ 150 if(syn == 27){ 151 scaner(); 152 E(); 153 if(syn == 28){ 154 scaner(); 155 printf("success\n"); 156 } 157 else 158 error(); 159 } 160 else if(syn == 11 || syn == 10){ 161 scaner(); 162 printf("success\n"); 163 } 164 else 165 error(); 166 } 167 168 void error(){ 169 printf("error\n"); 170 printf("\n(%s,出错!)",token); 171 } 172 173 main(){ 174 scaner(); 175 E(); 176 }