zoukankan      html  css  js  c++  java
  • 作业12 实验二 递归下降语法分析

    一、实验目的:

    利用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 } 

    运行结果如下:

     

  • 相关阅读:
    题解 DTOJ #1438. 矮人排队(lineup)
    题解 DTOJ #4423. 「THUSC2019」塔
    题解 DTOJ #4123.「2019冬令营提高组」全连
    题解 DTOJ #4016.辉夜的夜空明珠(moon)
    题解 DTOJ #2498.大步小步(babystep)
    题解 DTOJ #3326.组队(group)
    题解 DTOJ #1515.三塔合一
    题解 DTOJ #2305.Bazarek
    【code】Splay 模板
    寻找乱序数组中第K大的数
  • 原文地址:https://www.cnblogs.com/hs01/p/11940839.html
Copyright © 2011-2022 走看看