Twelfth - recursive descent parser

First, the purpose of the experiment:

The use of C language compiled recursive descent parsing procedures, and simple language parsing.

The preparation of a recursive descent parser, syntax checking and realize the structure of the word lexical analysis program provided by sequence analysis.

 

Second, the experimental principle

Each nonterminal symbol corresponds to a subroutine.

This subroutine is determined according to a next input symbol (SELECT sets) which are processed in a production, then the right end of the production according to:

  • Each encounter a terminator, it is determined whether the current read word matches the terminator, if matched, then the next word is read to continue the analysis; do not match, an error process is performed
  • Each encounter a nonterminal, the appropriate subroutine is called

 

Third, the experiment asked for clarification

Enter the word string to "#" end if the grammar is correct sentences, the output success information, print "success", otherwise output "error", and pointed out grammatical errors of the type and location.

E.g:

Input begin a: = 9; x: = 2 * 3; b: = a + x end #

Output success

Input x: = a + b * c end #

Output 'end' error

 

Fourth, the experimental procedures

1. Grammar of the language to be analyzed (refer to P90)

2. Grammar to be expressed, at least comprising

- Statement

-condition

-expression

3. eliminate left recursion

4. Extract the left common factor

5. SELECT set computing

6. LL (1) grammar is determined

7. recursive descent parser

solution:

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

char * Reserved [. 6] = { "the begin", "IF", "the then", "the while", "do" , "End"}; 
char INPUT [80], Output [. 8]; 
char CH; 
int SYN, p, I; // SYN code is a species other, p is the scanning adding 
int m = 0, n, row , sum 0 =, COUNT = 0; 
int flag = 0; // flag 
void parseS (); // parse the statement 
void ParseS1 (); 
void ParseS2 (); 
void ParseS3 (); 
void ParseS4 (); 
void PARSEC (); analysis conditions // 
void ParseE (); // analytic expression 
void ParseE1 (); 
void PARSET (); // resolvables 
void ParseT1 (); 
void ParseF (); // parse factor 
void Scanner () { 
    for (I = 0; i <8;i++ ){
        output[i] = NULL;++ I) { 
    } // initialize output
    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;
}

  

 

 

Guess you like

Origin www.cnblogs.com/kushoulder/p/11960161.html