• 实验二 递归下降语法分析


    
    

    一、实验目的:

    
    

    利用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 "string.h"
      2 #include<stdio.h>
      3 #include<stdlib.h>
      4 char prog[80],token[8];
      5 int syn,p,m,n,sum=0;
      6 char ch;
      7 char *rwtab[6]= {"begin","if","then","while","do","end"};
      8 void lrparser();
      9 void yucu();
     10 void statement();
     11 void expression();
     12 void term();
     13 void factor();
     14 int kk=0;
     15 
     16 int scaner() {
     17     m=0;
     18     for(n=0; n<8; n++) token[n]=NULL;
     19     ch=prog[p++];
     20     while(ch==' ') ch=prog[p++];
     21     if((ch>='a' && ch<='z') ||(ch>='A' && ch<='Z')) {
     22         while((ch>='a' && ch<='z') ||(ch>='A' && ch<='Z')||(ch>='0' && ch<='9')) {
     23             token[m++]=ch;
     24             ch=prog[p++];
     25         }
     26         token[m++]='\0';
     27         syn=10;
     28         p=p-1;      //回退一个字符
     29         for(n=0; n<6; n++) {
     30             if(strcmp(token,rwtab[n])==0) {
     31                 syn=n+1;
     32                 break;
     33             }
     34         }
     35     } else if(ch>='0' && ch<='9') {
     36         sum=0;
     37         while(ch>='0' && ch<='9') {
     38             sum=sum*10+ch-'0';
     39             ch=prog[p++];
     40         }
     41         p=p-1;
     42         syn=11;
     43     } else {
     44         switch(ch) {
     45             case '<':
     46                 m=0;
     47                 token[m++]=ch;
     48                 ch=prog[p];
     49                 if(ch=='>') {
     50                     syn=21;
     51                     token[m++]=ch;
     52                 } else if(ch=='=') {
     53                     syn=22;
     54                     token[m++]=ch;
     55                 } else {
     56                     syn=20;
     57                     p=p-1;
     58                 }
     59                 p=p+1;
     60                 token[m]='\0';
     61                 break;
     62             case '>':
     63                 m=0;
     64                 token[m++]=ch;
     65                 ch=prog[p++];
     66                 if(ch=='=') {
     67                     syn=24;
     68                     token[m++]=ch;
     69                 } else {
     70                     syn=23;
     71                     p=p-1;
     72                 }
     73                 break;
     74             case ':':
     75                 m=0;
     76                 token[m++]=ch;
     77                 ch=prog[p++];
     78                 if(ch=='=') {
     79                     syn=18;
     80                     token[m++]=ch;
     81                 } else {
     82                     syn=17;
     83                     p=p-1;
     84                 }
     85                 break;
     86             case '+':
     87                 syn=13;
     88                 token[0]=ch;
     89                 break;
     90             case '-':
     91                 syn=14;
     92                 token[0]=ch;
     93                 break;
     94             case '*':
     95                 syn=15;
     96                 token[0]=ch;
     97                 break;
     98             case '/':
     99                 syn=16;
    100                 token[0]=ch;
    101                 break;
    102             case ';':
    103                 syn=26;
    104                 token[0]=ch;
    105                 break;
    106             case '(':
    107                 syn=27;
    108                 token[0]=ch;
    109                 break;
    110             case ')':
    111                 syn=28;
    112                 token[0]=ch;
    113                 break;
    114             case '=':
    115                 syn=25;
    116                 token[0]=ch;
    117                 break;
    118             case '#':
    119                 syn=0;
    120                 token[0]=ch;
    121                 break;
    122             default:
    123                 syn=-1;
    124         }
    125     }
    126 } 
    127 void lrparser() {
    128     if (syn==1) { //begin
    129         scaner();
    130         yucu();
    131         if (syn==6) { //end
    132             scaner();
    133             if (syn==0 && kk==0) printf("success \n");
    134         } else {
    135             if(kk!=1) printf("error,lose 'end' ! \n");
    136             kk=1;
    137         }
    138     } else {
    139         printf("error,lose 'begin' ! \n");
    140         kk=1;
    141     }
    142     return;
    143 }
    144  
    145 void yucu() {
    146     statement();
    147     while(syn==26) { 
    148         scaner();
    149         statement();
    150     }
    151     return;
    152 }
    153  
    154 void statement() {
    155     if (syn==10) { //为标识符
    156         scaner();
    157         if (syn==18) { //为 :=
    158             scaner();
    159             expression();
    160         } else {
    161             printf("error!");
    162             kk=1;
    163         }
    164     } else {
    165         printf("error!");
    166         kk=1;
    167     }
    168     return;
    169 }
    170  
    171  
    172 void expression() {
    173     term();
    174     while(syn==13 || syn==14) {
    175         scaner();
    176         term();
    177     }
    178     return;
    179 }
    180  
    181  
    182 void term() {
    183     factor();
    184     while(syn==15 || syn==16) {
    185         scaner();
    186         factor();
    187     }
    188     return;
    189 }
    190  
    191  
    192 void factor() {
    193     if(syn==10 || syn==11)scaner(); //为标识符或整常数时,读下一个单词符号
    194     else if(syn==27) {
    195         scaner();
    196         expression();
    197         if(syn==28)scaner();
    198         else {
    199             printf(" ')' 错误\n");
    200             kk=1;
    201         }
    202     } else {
    203         printf("表达式错误\n");
    204         kk=1;
    205     }
    206     return;
    207 }
    208  
    209  
    210 int main() {
    211     p=0;int i;
    212 
    213     printf("请输入源程序:\n");
    214     do {
    215         scanf("%c",&ch);
    216         prog[p++]=ch;
    217     } while(ch!='#');
    218     p=0;
    219     scaner();
    220     lrparser();
    221     printf("语法分析结束!\n");
    222 //    getch();
    223 }
    224  

     引用于https://blog.csdn.net/Leslie___Cheung/article/details/78938252

    课程作业
  • 相关阅读:
    C++怎么实现线程安全
    Linux内核之进程地址空间
    Linux内核之内存管理
    内存管理之内存寻址
    Linux内核初探
    进程间通信
    下拉列表控件实例 ComboBoxControl
    数据表格控件 DataGridControl
    8 种百度云高速下载,你值得拥有
    10 快好用的下载工具,终于和迅雷说拜拜了
  • 原文地址:https://www.cnblogs.com/lingcode/p/11934233.html
Copyright © 2020-2023  润新知