您的位置:首页 > 其它

编写语法分析程序

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;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: