• 编写语法分析程序


    编写语法分析程序


    Note: Mr.JY的编译原理!


    文法改造

    1.文法

    
    1) <program>→{<declaration_list><statement_list>}
    
    2) <declaration_list><declaration_list><declaration_stat> | ε
    
    3) <declaration_stat>→int ID;
    
    4) <statement_list><statement_list><statement>| ε
    
    5) <statement><if_stat>|<while_stat>|<for_stat>|<read_stat>
                   |<write_stat>|< compound_stat > |<expression_stat>
    
    6) <if_stat>→ if (<expr>) <statement >| if (<expr>) <statement >else < statement >
    
    7) <while_stat>→ while (<expr >) < statement >
    
    8) <for_stat>→ for (<expr>;<expr>;<expr>)<statement>
    
    9) <write_stat>→write <expression>;
    
    10) <read_stat>→read ID;
    
    11)<compound_stat>→{<statement_list>}
    
    12)<expression_stat>< expression >;|;
    
    13)< expression >→ ID=<bool_expr>|<bool_expr>
    
    14)<bool_expr><additive_expr> |< additive_expr >(>|<|>=|<=|==|!=)< additive_expr > 
    
    15)< additive_expr>< additive_expr>+<term>|< additive_expr>-<term>|< term > 
    
    16)< term >< term >*<factor>|< term >/<factor>|< factor >
    
    17)< factor >→(< expression >)|ID|NUM
    

    2.消除左递归:

    a.
    原型:<declaration_list><declaration_list><declaration_stat> | ε
    改造:<declaration_list> → A  ,A →<declaration_stat>A|ε
    
    b.
    原形:<statement_list><statement_list><statement>| ε
    改造:<statement_list> → B  。 B →<statement>B| ε
    
    c.
    原形:< additive_expr>< additive_expr>+<term>|< additive_expr>-<term>|< term >
    改造:< additive_expr>< term >C  。 C →+<term>C|-<term>C|ε

    3.提取公因式:

    a.
    原形:<bool_expr><additive_expr>|< additive_expr >(>|<|>=|<=|==|!=)< additive_expr > 
    
    改造:<bool_expr><additive_expr>E 
    E→ε|(>|<|>=|<=|==|!=)< additive_expr > 
    b. 
    原形:< term >< term >*<factor>|< term >/<factor>|< factor >
    改造:< term >< factor >D
    D →*<factor>D|/<factor>D|ε
    
    3. <if_stat>→ if (<expr>) <statement >( ε|else < statement>)
    不可提取公因式
    
    < expression >→ ID=<bool_expr>|<bool_expr>
    该文法解决方案:  程序设计时通过超前读一个符号来解决,假设识别出标识符的符号ID后,再读一个符号。假设这个符号是“=”,说明选择的是赋值表达式。 假设不是“=”,则说明选择的是布尔表达式

    求First&Follow集

    1) <program> →{<declaration_list><statement_list>}
    
    First({<declaration_list><statement_list>})= {  {  }
    
    2) <declaration_list> → A , A →<declaration_stat>A|ε
    
    First(A)=First(<declaration_stat>A)=   { int ,ε }
    First(<declaration_stat>A)=First( int ID;)= { int }
    Follow(A) ={ if,while,for,read,write,{,},;,ID,(,NUM}
    
    3) <declaration_stat> →int ID;
    
    First(int ID;)={int}
    
    4)<statement_list> → B , B →<statement>B| ε
    
    First(<statement>B)={ if,while,for,read,write,{,;,ID,NUM,( }
    First(B) ={ if,while,for,read,write,{,;,ID, ε}
    Follow(B) ={ } }
    
    5)<statement><if_stat>|<while_stat>|<for_stat>|<read_stat>|
    <write_stat>|< compound_stat > |<expression_stat>
    
    First(<if_stat>)={if}
    First(<while_stat>)={while}
    First(<for_stat>)={for}
    First(<read_stat>)={read}
    First(<write_stat>)={write}
    First(< compound_stat >)={{} 
    First(<expression_stat>)={ ;,ID,NUM,( }
    
    6) <if_stat> → if (<expr>) <statement >| if (<expr>) <statement >else < statement >
    
    First(if (<expr>) <statement >)={ if }
    First(if (<expr>) <statement >else < statement >)={ if }
    
    7) <while_stat> → while (<expr >) < statement >
    
    First(while (<expr >) < statement >)={ while }
    
    8) <for_stat> → for (<expr>;<expr>;<expr>)<statement>
    
    First(for (<expr>;<expr>;<expr>)<statement>)={ for }
    
    9) <write_stat> →write <expression>;
    
    First(write <expression>;)={ write }
    
    10) <read_stat> →read ID; 
    
    First(read ID;)={ read }
    
    11)<compound_stat> →{<statement_list>} 
    
    First({<statement_list>})={{}
    
    12)<expression_stat> →< expression >;|; 
    
    First(< expression >;)= {ID,NUM,(}
    First(;)={;}
    
    13)< expression > → ID=<bool_expr>|<bool_expr> 
    
    First(ID=<bool_expr>)={ID}
    First(<bool_expr>)={ID,NUM,(}
    
    14) <bool_expr> →<additive_expr>E , E→ε|(>|<|>=|<=|==|!=)< additive_expr > 
    
    First(<additive_expr>E)={ID,NUM,(}
    First((>|<|>=|<=|==|!=)< additive_expr >)={>,<,>=,<=,==,!=}
    First(ε)={ ε} 
    Follow(E)={;}
    
    15)< additive_expr> →< term >C , C →+<term>C|-<term>CFirst(< term >C)={ID,NUM,(}
    First(+<term>C)={+}
    First(-<term>C)={-}
    Follow(C)={;, ), (>|<|>=|<=|==|!=)}
    
    16)< term > →< factor >D , D →*<factor>D|/<factor>DFirst(< factor >D)={ID,NUM,(}
    First(*<factor>D)={*}
    First(/<factor>D)={/}
    First(ε)={ε}
    Follow(D)={+,-, <,>,>=,<=,==,!=, ; , )}
    
    17)< factor > →(< expression >)|ID|NUM
    
    First((< expression >))={ ( }
    First(ID)=ID
    First(NUM)=NUM
    

    代码实现

    1.測试代码

    {
    int a;
    int i;
    int bc;
    for (i=1; i <= 10; i=i+1)
    {
    ;
    a=a+i
    b=b*i;
    {
    c=a+b;
    }
    }
    if (a>b) 
    {
    write a;
    }
    else 
    {
    write b;
    }
    }
    write c
    }

    2.实现代码

    #include<stdio.h>
    #include<ctype.h>
    #include<conio.h>
    #include<stdlib.h>
    #include<string.h>
    int A();
    int B();
    int C();
    int D();
    int E();
    int TESTparse();
    int program();
    int statement();
    int statement_list();
    int expression();
    int expression_stat();
    int declaration_stat();
    int declaration_list();
    int if_stat();
    int for_stat();
    int read_stat();
    int write_stat();
    int while_stat();
    int compound_stat();
    int term();
    int factor();
    int bool_expr();
    int additive_expr();
    int line;
    char ch;
    FILE *fp;//用于指向输入文件的指针
    extern char Scanout[300];//保存词法分析输出文件名称
    char token[20], token1[40];//token保存单词符号,token1保存单词值
    int TESTparse()
    {
        int es = 0;
        if ((fp = fopen(Scanout, "r")) == NULL)
        {
            printf("
     Open %s error !
    ", Scanout);
            es = 1;
        }
        printf("=========Result!=========
    
    ");
    
        if (es == 0)
        {
            fscanf(fp, "%s%s%d
    ", &token, &token1, &line);
            es = program();
        }
        fclose(fp);
        return (es);
    }
    int program()
    {
        int es = 0;
        if (strcmp(token, "{"))
        {
            printf("ERROR: Line %d   Lack  {    
    ", line);
            return 1;
        }
        fscanf(fp, "%s%s%d
    ", &token, &token1, &line);
        es = declaration_list();
        if (es > 0)
        {
            return 1;
        }
        es = statement_list();
        if (es > 0)
        {
            return 1;
        }
        if (strcmp(token, "}"))
        {
            printf("ERROR: Line %d   Lack  }    
    ", line);
            return 1;
        }
        ch = getc(fp);
        while (ch != EOF)
        {
            if (ch != ' '&&ch != '
    '&&ch != '	')
            {
                printf("ERROR: Line %d   Programma error!!   
    ", line);
                return (es = 1);
            }
            ch = getc(fp);
        }
        return (es);
    }
    int declaration_list()
    {
        int es = 0;
        if (strcmp(token1, "int") == 0)
        {
            es = A();
            return es;
        }
        else
        {
            printf("ERROR: Line %d   Lack int 
    ", line);
            return 1;
        }
    }
    int A()
    {
        int es = 0;
        if (strcmp(token1, "int") == 0)
        {
            es = declaration_stat();
            if (es > 0)
            {
                return 1;
            }
            es = A();
            return (es);
        }
        else if
            (
            strcmp(token1, "if") == 0 ||
            strcmp(token1, "while") == 0 ||
            strcmp(token1, "for") == 0 ||
            strcmp(token1, "read") == 0 ||
            strcmp(token1, "write") == 0 ||
            strcmp(token1, "{") == 0 ||
            strcmp(token1, ";") == 0 ||
            strcmp(token1, "ID") == 0 ||
            strcmp(token1, "(") == 0||
            strcmp(token1, "NUM") == 0 ||
            strcmp(token1, "}") == 0
            )
        {
            return 0;
        }
        else
        {
            printf("ERROR: Line %d   Lack int||if||while||for||read||write||{||;||ID||(||NUM||} 
    ", line);
            return 1;
        }
    }
    int  declaration_stat()
    {
        if (strcmp(token, "int"))
        {
            printf("ERROR: Line %d   Lack   int    
    ", line);
            return 1;
        }
        fscanf(fp, "%s%s%d
    ", &token, &token1, &line);
        if (strcmp(token, "ID"))
        {
            printf("ERROR: Line %d   Lack   ID    
    ", line);
            return 1;
        }
        fscanf(fp, "%s%s%d
    ", &token, &token1, &line);
        if (strcmp(token, ";"))
        {
            printf("ERROR: Line %d   Lack   ;   
    ", line);
            return  1;
        }
        fscanf(fp, "%s%s%d
    ", &token, &token1, &line);
        return 0;
    }
    int statement_list()
    {
        int es = 0;
        if (
            strcmp(token, "if") == 0 || strcmp(token, "while") == 0 ||
            strcmp(token, "for") == 0 || strcmp(token, "read") == 0 ||
            strcmp(token, "write") == 0 || strcmp(token, "ID") == 0 ||
            strcmp(token, "{") == 0 || strcmp(token, ";") == 0 ||
            strcmp(token, "NUM") == 0 || strcmp(token, "(") == 0 
            )
        {
            es = B();
            return es;
        }
        else
        {
            printf("ERROR: Line %d   Lack  if||while||for||read||write||{||;||ID||NUM||(   
    ", line);
            return 1;
        }
    }
    int B()
    {
        int es = 0;
        if (strcmp(token, "if") == 0 || strcmp(token, "while") == 0 ||
            strcmp(token, "for") == 0 || strcmp(token, "read") == 0 ||
            strcmp(token, "write") == 0 || strcmp(token, "ID") == 0 ||
            strcmp(token, "{") == 0 || strcmp(token, ";") == 0 ||
            strcmp(token, "NUM") == 0 || strcmp(token, "(") == 0)
        {
            es = statement();
            if (es > 0)
            {
                return 1;
            }
            es = B();
            return (es);
        }
        else if (strcmp(token, "}") == 0)
        {
            return 0;
        }
        else
        {
            printf("ERROR: Line %d   Lack  if||while||for||read||write||{||;||ID||NUM||( ||}  
    ", line);
            return 1;
        }
    }
    int statement()
    {
        int es = 0;
        if (es == 0 && strcmp(token, "if") == 0)
        {
            fscanf(fp, "%s%s%d
    ", &token, &token1, &line);
            es = if_stat();
        }
        else if (es == 0 && strcmp(token, "while") == 0)
        {
            fscanf(fp, "%s%s%d
    ", &token, &token1, &line);
            es = while_stat();
        }
        else if (es == 0 && strcmp(token, "for") == 0)
        {
            fscanf(fp, "%s%s%d
    ", &token, &token1, &line);
            es = for_stat();
        }
        else if (es == 0 && strcmp(token, "read") == 0)
        {
            fscanf(fp, "%s%s%d
    ", &token, &token1, &line);
            es = read_stat();
        }
        else if (es == 0 && strcmp(token, "write") == 0)
        {
            fscanf(fp, "%s%s%d
    ", &token, &token1, &line);
            es = write_stat();
        }
        else if (es == 0 && strcmp(token, "{") == 0)
        {
            fscanf(fp, "%s%s%d
    ", &token, &token1, &line);
            es = compound_stat();                       
        }
        else if (es == 0 && strcmp(token, "ID") == 0 || strcmp(token, "NUM") == 0 || strcmp(token, "(") == 0 || strcmp(token, ";") == 0)
        {
            es = expression_stat();
        }
        else
        {
            printf("ERROR: Line %d   Lack  if||while||for||read||write||{||;||ID||NUM||(   
    ", line);
            return 1;
        }
        return (es);
    }
    int if_stat()
    {
        int es = 0;
        if (strcmp(token, "("))
        {
            printf("ERROR: Line %d   Lack  ( 
    ", line);
            return 1;
        }
        fscanf(fp, "%s%s%d
    ", &token, &token1, &line);
        es = expression();
        if (es > 0)
        {
            return 1;
        }
        if (strcmp(token, ")"))
        {
            printf("ERROR: Line %d   Lack  ) 
    ", line);
            return 1;
        }
        fscanf(fp, "%s%s%d
    ", &token, &token1, &line);
        es = statement();
        if (es > 0)
        {
            return 1;
        }
        if (strcmp(token, "else") == 0)
        {
            fscanf(fp, "%s%s%d
    ", &token, &token1, &line);
            es = statement();
        }
        return (es);
    }
    int while_stat()
    {
        int es = 0;
        if (strcmp(token, "("))
        {
            printf("ERROR: Line %d   Lack   (   
    ", line);
            return 1;
        }
        fscanf(fp, "%s%s%d
    ", &token, &token1, &line);
        es = expression();
        if (es > 0)
        {
            return 1;
        }
        if (strcmp(token, ")"))
        {
            printf("ERROR: Line %d   Lack   )   
    ", line);
            return 1;
        }
        fscanf(fp, "%s%s%d
    ", &token, &token1, &line);
        es = statement();
        return (es);
    }
    int for_stat()
    {
        int es = 0;
        if (strcmp(token, "("))
        {
            printf("ERROR: Line %d   Lack   (   
    ", line);
            return 1;
        }
        fscanf(fp, "%s%s%d
    ", &token, &token1, &line);
        es = expression();
        if (es > 0)
        {
            return 1;
        }
        if (strcmp(token, ";"))
        {
            printf("ERROR: Line %d   Lack   ;   
    ", line);
            return 1;
        }
        fscanf(fp, "%s%s%d
    ", &token, &token1, &line);
        es = expression();
        if (es > 0)
        {
            return 1;
        }
        if (strcmp(token, ";"))
        {
            printf("ERROR: Line %d   Lack   ;  
    ", line);
            return 1;
        }
        fscanf(fp, "%s%s%d
    ", &token, &token1, &line);
        es = expression();
        if (es > 0)
        {
            return 1;
        }
        if (strcmp(token, ")"))
        {
            printf("ERROR: Line %d   Lack   )  
    ", line);
            return 1;
        }
        fscanf(fp, "%s%s%d
    ", &token, &token1, &line);
        es = statement();
        return (es);
    }
    int write_stat()
    {
        int es = 0;
        es = expression();
        if (es > 0)
        {
            return 1;
        }
        if (strcmp(token, ";"))
        {
            printf("ERROR: Line %d   Lack   ;  
    ", line);
            return 1;
        }
        fscanf(fp, "%s%s%d
    ", &token, &token1, &line);
        return 0;
    }
    
    
    int read_stat()
    {
        int es = 0;
        if (strcmp(token, "ID"))
        {
            printf("ERROR: Line %d   Lack   ID  
    ", line);
            return 1;
        }
        fscanf(fp, "%s%s%d
    ", &token, &token1, &line);
        if (strcmp(token, ";"))
        {
            printf("ERROR: Line %d   Lack   ;   
    ", line);
            return 1;
        }
        fscanf(fp, "%s%s%d
    ", &token, &token1, &line);
        return 0;
    }
    
    int compound_stat()
    {
        int es = 0;
        es = statement_list();
        if (es > 0)
        {
            return 1;
        }
        if (strcmp(token, "}"))
        {
            return 1;
        }
        fscanf(fp, "%s%s%d
    ", &token, &token1, &line);
        return 0;
    }
    
    int expression_stat()
    {
        int es = 0;
        if (strcmp(token, ";") == 0)
        {
            fscanf(fp, "%s%s%d
    ", &token, &token1, &line);
            return 0;
        }
        else if (strcmp(token, "ID") == 0 || strcmp(token, "NUM") == 0 || strcmp(token, "(") == 0)
        {
            es = expression();
            if (es > 0)
            {
                return 1;
            }
            if (strcmp(token, ";") == 0)
            {
                fscanf(fp, "%s%s%d
    ", &token, &token1, &line);
                return 0;
            }
            else
            {
                printf("ERROR: Line %d   Lack   ;   
    ", line);
                return 1;
            }
        }
        else
        {
            printf("ERROR: Line %d   Lack   ;||ID||NUM||(   
    ", line);
        }
        return 0;
    }
    
    int expression()
    {
        int es = 0, fileadd;
        char token2[20], token3[40];
        if (strcmp(token, "ID") == 0)
        {
            fileadd = ftell(fp);//记住当前文件位置
            fscanf(fp, "%s%s%d
    ", &token2, &token3, &line);
    
            if (strcmp(token2, "=") == 0)
            {
                fscanf(fp, "%s%s%d
    ", &token, &token1, &line);
                es = bool_expr();
                if (es > 0)
                {
                    return 1;
                }
            }
            else
            {
                fseek(fp, fileadd, 0);//若非‘=’,则文件指针回到'='前的标识符
                es = bool_expr();
                if (es > 0)
                {
                    return 1;
                }
            }
        }
        else
        {
            es = bool_expr();
            if (es > 0)
            {
                return 1;
            }
        }
        return 0;
    }
    
    int bool_expr()
    {
        int es = 0;
        if (strcmp(token, "ID") == 0 || strcmp(token, "NUM") == 0 || strcmp(token, "("))
        {
            es = additive_expr();
            if (es > 0)
            {
                return 1;
            }
            es = C();
            return (es);
        }
        else
        {
            printf("ERROR: Line %d   Lack  ID||NUM||(    
    ", line);
            return 1;
        }
    }
    
    int C()
    {
        int es = 0;
        if (
            strcmp(token, ">") == 0 ||
            strcmp(token, ">=") == 0 ||
            strcmp(token, "<") == 0 ||
            strcmp(token, "<=") == 0 ||
            strcmp(token, "==") == 0 ||
            strcmp(token, "!=") == 0
            )
        {
            fscanf(fp, "%s%s%d
    ", &token, &token1, &line);
            es = additive_expr();
            if (es > 0)
            {
                return 1;
            }
            return 0;
        }
        else if (strcmp(token, ";") == 0 || strcmp(token, ")") == 0)
        {
            return 0;
        }
        else
        {
            printf("ERROR: Line %d   Lack )||>||<||>=||<==||==||!=||;    
    ", line);
            return 1;
        }
    }
    
    int additive_expr()
    {
        int es = 0;
        if (strcmp(token, "ID") == 0 || strcmp(token, "NUM") == 0 || strcmp(token, "(") == 0)
        {
            es = term();
            if (es > 0)
            {
                return 1;
            }
            es = D();
            return (es);
        }
        else
        {
            printf("ERROR: Line %d   Lack  ID||NUM||(   
    ", line);
            return 1;
        }
    }
    
    int D()
    {
        int es = 0;
        if (strcmp(token, "+") == 0 || strcmp(token, "-") == 0)
        {
            fscanf(fp, "%s%s%d
    ", &token, &token1, &line);
            es = term();
            if (es > 0)
            {
                return 1;
            }
            es = D();
            return (es);
        }
        else if
            (
            strcmp(token, ";") == 0 || strcmp(token, ")") == 0 ||
            strcmp(token, ">") == 0 || strcmp(token, ">=") == 0 ||
            strcmp(token, "<") == 0 || strcmp(token, "<=") == 0 ||
            strcmp(token, "==") == 0 || strcmp(token, "!=") == 0
            )
        {
            return 0;
        }
        else
        {
            printf("ERROR: Line %d   Lack   +||-||;||)||<||>||<=||>=||==||!=    
    ", line);
            return 1;
        }
    }
    
    int term()
    {
        int es = 0;
        if (strcmp(token, "ID") == 0 || strcmp(token, "NUM") == 0 || strcmp(token, "(") == 0)
        {
            es = factor();
            if (es > 0)
            {
                return 1;
            }
            es = E();
            return (es);
        }
        else
        {
            printf("ERROR: Line %d   Lack  ID||NUM||(   
    ", line);
            return 1;
        }
    }
    int E()
    {
        int es = 0;
        if (strcmp(token, "*") == 0 || strcmp(token, "/") == 0)
        {
            fscanf(fp, "%s%s%d
    ", &token, &token1, &line);
            es = factor();
            if (es > 0)
            {
                return 1;
            }
            es = E();
            return (es);
        }
        else if
            (
            strcmp(token, ";") == 0 || strcmp(token, ")") == 0 ||
            strcmp(token, "+") == 0 || strcmp(token, "-") == 0 ||
            strcmp(token, ">") == 0 || strcmp(token, ">=") == 0 ||
            strcmp(token, "<") == 0 || strcmp(token, "<=") == 0 ||
            strcmp(token, "==") == 0 || strcmp(token, "!=") == 0
            )
        {
            return 0;
        }
        else
        {
            printf("ERROR: Line %d   Lack   *||/||;||)||>||<||==||!=||>=||<=  
    ", line);
            return 1;
        }
    }
    int factor()
    {
        int es = 0;
        if (strcmp(token, "(") == 0)
        {
            fscanf(fp, "%s%s%d
    ", &token, &token1, &line);
            es = expression();
            if (es > 0)
            {
                return 1;
            }
            if (strcmp(token, ")"))
            {
                printf("ERROR: Line %d   )   
    ", line);
                return 1;
            }
            fscanf(fp, "%s%s%d
    ", &token, &token1, &line);
            return 0;
        }
        else if (strcmp(token, "ID") == 0 || strcmp(token, "NUM") == 0)
        {
            fscanf(fp, "%s%s%d
    ", &token, &token1, &line);
            return 0;
        }
        else
        {
            printf("ERROR: Line %d   ( || ID || NUM    
    ", line);
            return 1;
        }
    }
    
    
    
  • 相关阅读:
    Scrapy框架
    爬虫高性能相关
    存储库之MongoDB
    存储库之redis
    beautifulsoup
    pyecharts
    wxpy模块
    Gin框架
    Python的rabbitMQ
    Vue基础
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/5149285.html
Copyright © 2020-2023  润新知