一、实验目的:
利用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 //引入头文件 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 //声明变量 6 char prog[800],dc[8]; //程序段 单词 7 char ch; //单词中的字符 8 int syn,p,m=0; //单词符号种别码 指针p 9 int n,sum=0; //整数sum 10 char *word[6]={"begin","if","then","while","do","end"}; //保留字 11 int kk=0; //判断是否有错误 12 //声明函数 13 void scaner(); 14 void lrparser(); 15 void yucu(); 16 void statement(); 17 void condition(); 18 void expression(); 19 void term(); 20 void factor(); 21 22 void scaner(){ //读取一个字符 23 m=0; 24 //初始化数组dc 25 for(n=0;n<8;n++){ 26 dc[n]=NULL; 27 } 28 ch=prog[p++]; 29 //遇到空格指针加1 30 while(ch==' '){ 31 ch=prog[p]; 32 p++; 33 } 34 //标识符 35 if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){ 36 m=0; 37 while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){ 38 dc[m++]=ch; 39 ch=prog[p++]; 40 } 41 p--; 42 syn=10; 43 //保留字 44 for(n=0;n<6;n++){ 45 if(strcmp(dc,word[n])==0){ 46 syn=n+1; 47 break; 48 } 49 } 50 } 51 //数字 52 else if((ch>='0'&&ch<='9')){ 53 sum=0; 54 while((ch>='0'&&ch<='9')){ 55 sum=sum*10+ch-'0'; 56 ch=prog[p++]; 57 } 58 p--; 59 syn=11; 60 } 61 else{ 62 switch(ch){ 63 case '<':m=0; 64 dc[m++]=ch; 65 ch=prog[p++]; 66 if(ch=='>'){ 67 syn=22; 68 dc[m++]=ch; 69 } 70 else if(ch=='='){ 71 syn=21; 72 dc[m++]=ch; 73 } 74 else{ 75 syn=20; 76 p--; 77 } 78 break; 79 case '>':m=0; 80 dc[m++]=ch; 81 ch=prog[p++]; 82 if(ch=='='){ 83 syn=24; 84 dc[m++]=ch; 85 } 86 else{ 87 syn=23; 88 p--; 89 } 90 break; 91 case ':':m=0; 92 dc[m++]=ch; 93 ch=prog[p++]; 94 if(ch=='='){ 95 syn=18; 96 dc[m++]=ch; 97 } 98 else{ 99 syn=17; 100 p--; 101 } 102 break; 103 case '*':syn=15;dc[0]=ch;break; 104 case '/':syn=16;dc[0]=ch;break; 105 case '+':syn=13;dc[0]=ch;break; 106 case '-':syn=14;dc[0]=ch;break; 107 case '=':syn=25;dc[0]=ch;break; 108 case ';':syn=26;dc[0]=ch;break; 109 case '(':syn=27;dc[0]=ch;break; 110 case ')':syn=28;dc[0]=ch;break; 111 case '#':syn=0;dc[0]=ch;break; 112 case ' ':syn=-2;dc[0]=ch;break; 113 } 114 } 115 } 116 117 //程序,判断是否以begin开始,end #结束 118 void lrparser(){ 119 if (syn==1) { //begin 120 scaner(); 121 yucu(); 122 if (syn==6) { //end 123 scaner(); 124 if (syn==0 && kk==0){ 125 printf("success "); 126 } 127 } 128 else { 129 printf("error,lose 'end' ! "); 130 kk=1; 131 exit(0); 132 } 133 } 134 else { 135 printf("error,lose 'begin' ! "); 136 kk=1; 137 exit(0); 138 } 139 return; 140 } 141 142 //语句串 143 void yucu() { 144 statement(); 145 while(syn==26) { 146 scaner(); 147 statement(); 148 } 149 return; 150 } 151 //语句 152 void statement(){ 153 if (syn==10) { //为标识符 154 scaner(); 155 if (syn==18) { //为 := 156 scaner(); 157 expression(); 158 } 159 else { 160 printf("error!"); 161 kk=1; 162 exit(0); 163 } 164 } 165 else if(syn==2){ //为if 166 condition(); 167 scaner(); 168 if(syn==3){ 169 statement(); 170 } 171 else{ 172 printf("error,lose 'then' ! "); 173 kk=1; 174 exit(0); 175 } 176 } 177 else { 178 printf("error!"); 179 kk=1; 180 exit(0); 181 } 182 183 return; 184 } 185 //条件 186 void condition(){ 187 expression(); 188 if(syn==25||syn==0||syn==20||syn==21||syn==23||syn==24){ 189 scaner(); 190 } 191 else{ 192 printf("error! "); 193 kk=1; 194 exit(0); 195 } 196 expression(); 197 return; 198 } 199 //表达式 200 void expression(){ 201 term(); 202 while(syn==13 || syn==14) { 203 scaner(); 204 term(); 205 } 206 return; 207 } 208 //项 209 void term(){ 210 factor(); 211 while(syn==15 || syn==16) { 212 scaner(); 213 factor(); 214 } 215 return; 216 } 217 //因子 218 void factor(){ 219 if(syn==10 || syn==11){ 220 scaner(); //为标识符或整常数时,读下一个单词符号 221 } 222 else if(syn==27) { 223 scaner(); 224 expression(); 225 if(syn==28){ 226 scaner(); 227 } 228 else { 229 printf(" ')' 错误 "); 230 kk=1; 231 exit(0); 232 } 233 } else { 234 printf("表达式错误 "); 235 kk=1; 236 exit(0); 237 } 238 return; 239 } 240 int main(void){ 241 //指针从0开始 242 p=0; 243 int i; 244 printf("请输入源程序: "); 245 do { 246 scanf("%c",&ch); 247 prog[p++]=ch; 248 } while(ch!='#'); 249 //指针从0开始 250 p=0; 251 do{ 252 scaner(); 253 lrparser(); 254 }while(syn!=0); 255 printf("语法分析结束! "); 256 257 }
运行结果如下: