编写语法分析程序

编写语法分析程序


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;
    }
}


原文地址:https://www.cnblogs.com/mengfanrong/p/5149285.html