编写语法分析程序
2016-01-21 18:46
134 查看
编写语法分析程序
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>C|ε First(< term >C)={ID,NUM,(} First(+<term>C)={+} First(-<term>C)={-} Follow(C)={;, ), (>|<|>=|<=|==|!=)} 16)< term > →< factor >D , D →*<factor>D|/<factor>D|ε First(< 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("\n Open %s error !\n", Scanout); es = 1; } printf("=========Result!=========\n\n"); if (es == 0) { fscanf(fp, "%s%s%d\n", &token, &token1, &line); es = program(); } fclose(fp); return (es); } int program() { int es = 0; if (strcmp(token, "{")) { printf("ERROR: Line %d Lack { \n", line); return 1; } fscanf(fp, "%s%s%d\n", &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 } \n", line); return 1; } ch = getc(fp); while (ch != EOF) { if (ch != ' '&&ch != '\n'&&ch != '\t') { printf("ERROR: Line %d Programma error!! \n", 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 \n", 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||} \n", line); return 1; } } int declaration_stat() { if (strcmp(token, "int")) { printf("ERROR: Line %d Lack int \n", line); return 1; } fscanf(fp, "%s%s%d\n", &token, &token1, &line); if (strcmp(token, "ID")) { printf("ERROR: Line %d Lack ID \n", line); return 1; } fscanf(fp, "%s%s%d\n", &token, &token1, &line); if (strcmp(token, ";")) { printf("ERROR: Line %d Lack ; \n", line); return 1; } fscanf(fp, "%s%s%d\n", &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||( \n", 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||( ||} \n", line); return 1; } } int statement() { int es = 0; if (es == 0 && strcmp(token, "if") == 0) { fscanf(fp, "%s%s%d\n", &token, &token1, &line); es = if_stat(); } else if (es == 0 && strcmp(token, "while") == 0) { fscanf(fp, "%s%s%d\n", &token, &token1, &line); es = while_stat(); } else if (es == 0 && strcmp(token, "for") == 0) { fscanf(fp, "%s%s%d\n", &token, &token1, &line); es = for_stat(); } else if (es == 0 && strcmp(token, "read") == 0) { fscanf(fp, "%s%s%d\n", &token, &token1, &line); es = read_stat(); } else if (es == 0 && strcmp(token, "write") == 0) { fscanf(fp, "%s%s%d\n", &token, &token1, &line); es = write_stat(); } else if (es == 0 && strcmp(token, "{") == 0) { fscanf(fp, "%s%s%d\n", &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||( \n", line); return 1; } return (es); } int if_stat() { int es = 0; if (strcmp(token, "(")) { printf("ERROR: Line %d Lack ( \n", line); return 1; } fscanf(fp, "%s%s%d\n", &token, &token1, &line); es = expression(); if (es > 0) { return 1; } if (strcmp(token, ")")) { printf("ERROR: Line %d Lack ) \n", line); return 1; } fscanf(fp, "%s%s%d\n", &token, &token1, &line); es = statement(); if (es > 0) { return 1; } if (strcmp(token, "else") == 0) { fscanf(fp, "%s%s%d\n", &token, &token1, &line); es = statement(); } return (es); } int while_stat() { int es = 0; if (strcmp(token, "(")) { printf("ERROR: Line %d Lack ( \n", line); return 1; } fscanf(fp, "%s%s%d\n", &token, &token1, &line); es = expression(); if (es > 0) { return 1; } if (strcmp(token, ")")) { printf("ERROR: Line %d Lack ) \n", line); return 1; } fscanf(fp, "%s%s%d\n", &token, &token1, &line); es = statement(); return (es); } int for_stat() { int es = 0; if (strcmp(token, "(")) { printf("ERROR: Line %d Lack ( \n", line); return 1; } fscanf(fp, "%s%s%d\n", &token, &token1, &line); es = expression(); if (es > 0) { return 1; } if (strcmp(token, ";")) { printf("ERROR: Line %d Lack ; \n", line); return 1; } fscanf(fp, "%s%s%d\n", &token, &token1, &line); es = expression(); if (es > 0) { return 1; } if (strcmp(token, ";")) { printf("ERROR: Line %d Lack ; \n", line); return 1; } fscanf(fp, "%s%s%d\n", &token, &token1, &line); es = expression(); if (es > 0) { return 1; } if (strcmp(token, ")")) { printf("ERROR: Line %d Lack ) \n", line); return 1; } fscanf(fp, "%s%s%d\n", &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 ; \n", line); return 1; } fscanf(fp, "%s%s%d\n", &token, &token1, &line); return 0; } int read_stat() { int es = 0; if (strcmp(token, "ID")) { printf("ERROR: Line %d Lack ID \n", line); return 1; } fscanf(fp, "%s%s%d\n", &token, &token1, &line); if (strcmp(token, ";")) { printf("ERROR: Line %d Lack ; \n", line); return 1; } fscanf(fp, "%s%s%d\n", &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\n", &token, &token1, &line); return 0; } int expression_stat() { int es = 0; if (strcmp(token, ";") == 0) { fscanf(fp, "%s%s%d\n", &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\n", &token, &token1, &line); return 0; } else { printf("ERROR: Line %d Lack ; \n", line); return 1; } } else { printf("ERROR: Line %d Lack ;||ID||NUM||( \n", 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\n", &token2, &token3, &line); if (strcmp(token2, "=") == 0) { fscanf(fp, "%s%s%d\n", &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||( \n", 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\n", &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 )||>||<||>=||<==||==||!=||; \n", 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||( \n", line); return 1; } } int D() { int es = 0; if (strcmp(token, "+") == 0 || strcmp(token, "-") == 0) { fscanf(fp, "%s%s%d\n", &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 +||-||;||)||<||>||<=||>=||==||!= \n", 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||( \n", line); return 1; } } int E() { int es = 0; if (strcmp(token, "*") == 0 || strcmp(token, "/") == 0) { fscanf(fp, "%s%s%d\n", &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 *||/||;||)||>||<||==||!=||>=||<= \n", line); return 1; } } int factor() { int es = 0; if (strcmp(token, "(") == 0) { fscanf(fp, "%s%s%d\n", &token, &token1, &line); es = expression(); if (es > 0) { return 1; } if (strcmp(token, ")")) { printf("ERROR: Line %d ) \n", line); return 1; } fscanf(fp, "%s%s%d\n", &token, &token1, &line); return 0; } else if (strcmp(token, "ID") == 0 || strcmp(token, "NUM") == 0) { fscanf(fp, "%s%s%d\n", &token, &token1, &line); return 0; } else { printf("ERROR: Line %d ( || ID || NUM \n", line); return 1; } }
相关文章推荐