实验二 递归下降语法分析

一、实验目的:

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

#include<stdio.h>
#include <iostream>
#include<string.h>
using namespace std;

char *reserved[6] = {"begin","if","then","while","do","end"};
char input[80],output[8]; 
char ch;
int syn,p,i;//syn
int m = 0,n,row,sum = 0,count=0; 
int flag = 0;//
void ParseS();//解析语句 
void ParseS1();
void ParseS2();
void ParseS3();
void ParseS4();
void ParseC();//解析条件 
void ParseE();//解析表达式 
void ParseE1();
void ParseT();//解析项 
void ParseT1();
void ParseF();//解析因子 
void scanner(){
    for( i = 0 ; i < 8 ; i++ ){
        output[i] = NULL;
    }//
    ch = input[p++];
    
    while( ch == ' ' ){
        ch = input[p] ;
        p ++ ;
    }
    //持续读入 
    if( ( ch >= 'a' && ch <= 'z' ) || ( ch >= 'A' && ch <= 'Z' ) ){
        m = 0 ;
        while( ( ch >= 'a' && ch <= 'z' ) || ( ch >= 'A' && ch <= 'Z' ) || ( ch >= '0' && ch <= '9' ) ){
            output[m++]  = ch ;
            ch = input[p++];
        }
        output[m++] = '\0';
        p -- ;
        syn = 10 ;
        for( n = 0 ; n < 6 ; n ++ ){
            if( strcmp(output,reserved[n]) == 0 ){
                syn = n + 1;
                break;
            }
        }
    
    }else if( ( ch >= '0' && ch <= '9' ) ){
        sum = 0 ;
        while( ch >= '0' && ch <= '9' ){
            sum=sum*10+ch-'0' ;
            ch = input[p++] ;
        }
        p -- ;
        syn = 11;
    }
    else if(ch == '/'){
        ch = input[p++] ;
        if(ch == '/'){
            while(ch != '\n'){
                ch = input[p++] ;
            }
            scanner();    
            
        }
        else if(ch == '*'){
            ch = input[p++];
            int flag=0;
        //    printf("%c %c",ch,input[p]);
            while((ch == '*' && input[p] != '/')||(ch != '*' && input[p] == '/') || (ch != '*' && input[p] != '/')){
                ch = input[p++] ;
                if(p==count-2 && (ch != '*' && input[p] != '/')){
                    flag =1;
                    syn = 100;
                    break;
                }
            }
            p++;
            if(flag==0){
                scanner();    
            }
            
        }else{
            p = p - 2 ;
            ch = input[p++] ; 
            output[0] = ch ;
            syn = 16 ;
        } 
        
    }else switch(ch){
        case '+':
            output[0] = ch ; 
            syn = 13;
            break;
        case '-':
            output[0] = ch ; 
            syn = 14;
            break;
        case '*':
            output[0] = ch ;
            syn = 15 ;
            break;
        case '/':
            output[0] = ch ;
            syn = 16 ;
            break;
        case ':':
            i = 0;
            output[i++] = ch ;
            ch = input[p++];
            if( ch == '=' ){
                output[i++] = ch;
                syn = 18 ;
            }else{
                syn = 17;
                p-- ;
            }
            break;
        case '<':
            i = 0 ;
            output[i++] = ch ;
            ch = input[p++] ;
            if( ch == '=' ){
                output[i++] = ch ;
                syn = 21 ;
            }else if( ch == '>' ){
                output[i++] = ch ;
                syn = 22 ;
            }else{
                syn = 20 ;
                p-- ;
            }
            break;
        case '>':
            i = 0;
            output[i++] = ch ;
            ch = input[p++] ;
            if( ch == '=' ){
                output[i++] = ch;
                syn=24;
            }else{
                syn=23;
                p--;
            }
            break;
        case '=':
            output[0] = ch ;
            syn = 25 ;
        break;
        case ';':
            output[0] = ch ;
            syn = 26 ;
            break;
        case '(':
            output[0] = ch ;
            syn = 27 ;
            break;
        case ')':
            output[0] = ch ;
            syn = 28 ;
            break;
        case '#':
            output[0] = ch ;
            syn = 0;
            break;
        case '\n':
            syn = 99 ;
            break;
        default:
            syn = -1 ;
            break;    
    }
    
}

void ParseS(){
    if(flag != 0){
        if(syn == 10){ //<id>:=<表达式> 
            scanner();
            ParseS1();
        }
        else if(syn == 2){ //if
            scanner();
            ParseS2();
        }
        else if(syn == 4){//while
            scanner();
            ParseS3();
        }
        else if(syn == 0){
        } 
        else{
            printf("statement syntx error S\n");
            exit(0);
        }
    }
    else{
        if(syn == 1){//begin
        scanner();
        flag = 1;
        ParseS4();
        }else{
            printf("error,缺少begin!\n");
            exit(0);
        }
    }
}

void ParseS1(){
    if(syn==18){
        scanner();
        ParseE();
    }
    else{
        printf("statement syntx error S1\n");
        exit(0);
    }
}
void ParseS2(){//if
    ParseC(); 
    if(syn== 3 ){
        scanner();
        ParseS();
    }
    else{
        printf("statement syntx error S2\n");
        exit(0);
    }
}
void ParseS3(){//while
    ParseC(); 
    if(syn== 5 ){
        scanner();
        ParseS();
    }
    else{
        printf("statement syntx error S3 \n");
        exit(0);
    }
}

void ParseS4(){//begin
    ParseS();
    while(syn == 26){
        scanner();
        ParseS();
    }
    if(syn == 6){
        scanner();
        if(syn == 0){
            printf("success!");
        }
        else{
            printf("statement syntx error S4\n");
        }
    }
    else{
        printf("error,缺少end\n");
        exit(0);
    }
}
void ParseC(){
    ParseE();
    if(syn==25||syn==0||syn==20||syn==21||syn==23||syn==24){
        scanner();
        scanner();
    }
    else{
        printf("condition syntx error C\n");
        exit(0);
        }
    ParseE();
 
} 
void ParseE(){
    ParseT();
    ParseE1();

}
 
 

void ParseE1(){
    if(syn == 13 || syn == 14){
        scanner();
        ParseT();
        ParseE1();
    }
    else if(syn == 28 || syn == 0){
    }    
}

 

void ParseT(){
    ParseF();
    ParseT1();
}

 

void ParseT1(){
    if(syn == 15 || syn == 16){
        scanner();
        ParseF();
        ParseT1();
    } 
    else if(syn == 13 ||syn == 14 || syn == 28 || syn == 0){    
    }

}

void ParseF(){
    if(syn == 27){
        scanner();
        ParseE();
        if(syn == 28){
            scanner();
        }
        else{
            printf("factor syntx error F\n");
            exit(0);
        }
    }
    else if(syn == 10 || syn == 11){
            scanner();    
                
    }
    else{
        printf("factor syntx error F\n");
        exit(0);
    }
}
int main() {
    p = 0;
    printf("请输入源程序:");
    do{
        ch = getchar();
        input[p++] = ch;
    }while(ch != '#');
    count = p;
    p = 0;
    scanner();
    ParseS();
    return 0;
}

 

 

posted on 2019-11-29 20:21  辛苦最怜天上月  阅读(211)  评论(0编辑  收藏  举报

导航