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.标识符(10)

    2.无符号数(11)

    3.保留字(一词一码)

    4.运算符(一词一码)

    5.界符(一词一码)

    代码:

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

    运行结果:

     

  • 相关阅读:
    poj2352树状数组解决偏序问题
    Python中的输入(input)和输出打印
    Python中的输入(input)和输出打印
    IP协议
    IP协议
    Python中的可迭代Iterable和迭代器Iterator
    Python中的可迭代Iterable和迭代器Iterator
    Python中的变量和数据类型
    Python中的变量和数据类型
    TCP的三次握手和四次挥手和UDP协议
  • 原文地址:https://www.cnblogs.com/linyanli/p/11933224.html
Copyright © 2011-2022 走看看