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. 递归下降分析程序

    种别码:

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

    实验结果:

     

  • 相关阅读:
    SDOI2008]仪仗队
    洛谷P1414 又是毕业季II
    P3865 【模板】ST表
    [HAOI2007]理想的正方形
    noip 2011 选择客栈
    [AHOI2009]中国象棋
    洛谷P3387 【模板】缩点
    [SCOI2005]最大子矩阵
    [CQOI2009]叶子的染色
    LibreOJ #116. 有源汇有上下界最大流
  • 原文地址:https://www.cnblogs.com/m2362563619/p/11960088.html
Copyright © 2011-2022 走看看