实验四 用YACC实现的语法分析器
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
void yyerror(char *s) {
printf("%s\n",s); } %} %token NUM %token BASIC IF ELSE DO BREAK REAL TRUE FALSE ID LE INDEX %token WHILE AND OR EQ NE GE %left '+''-' %left '*''/' %right UMINUS %%
| expr {printf("rel->expr\n");}
;
expr : expr '+' term {printf("expr->expt+term\n");}
| expr '-' term {printf("expr->expr-term\n");}
| term {printf("expr->term\n");}
实验 4 用 Yacc 工具构造语法分析器
一、实Βιβλιοθήκη Baidu目的
掌握移进-归约技术语法分析技术,利用语法分析器生成工具 Yacc/Bison 实 现语法分析器的构造。
二、实验内容
利用语法分析器生成工具 Yacc/Bison 编写一个语法分析程序,与词法分析器 结合,能够根据语言的上下文无关文法,识别输入的单词序列是否文法的句子。
| {printf("\decls->E\n");}
;
decl : type ID ';' {printf("decl->type id\n");}
;
type : type '[' NUM ']' {printf("type->type [num]\n");}
| BASIC {printf("type->basic\n");}
|IF '(' bool ')' stmt ELSE stmt {printf("stmt->if(bool) stmt else stmt\n");}
|WHILE '(' bool')' stmt {printf("stmt->while(bool) stmt\n");}
|DO stmt WHILE '(' bool ')' ';' {printf("stmt->->do stmt while(bool)\n");}
;
equality : equality EQ rel {printf("equality->equality==rel\n");}
| equality NE rel {printf("equality->equality!=rel\n");}
| rel {printf("equality->rel\n");}
;
stmts : stmts stmt {printf("stmts->stmts stmt\n");}
| {printf("stmts->E\n");}
;
stmt : loc '=' bool ';' {printf("stmt->loc=bool\n");}
|IF '(' bool ')' stmt {printf("stmt->if(bool) stmt\n");}
|BREAK ';' {printf("stmt->break\n");}
| block {printf("stmt->block\n");}
;
loc
: loc '[' bool ']' {printf("loc->loc[bool]\n");}
|ID {printf("loc->id\n");}
;
2、在.y文件中添加main()函数,以及一些外部函数的声明:
#include "lex.yy.c" int yyparse(); extern void BeginCompileOneFile( const char * filename ); extern void EndCompileOneFile(void); void main() {
三、实验要求
1.个人完成,提交实验报告。 2.实验报告中给出采用测试源代码片断,及其对应的最右推导过程(形式可以 自行考虑,如依次给出推导使用的产生式)。
例如,程序片断
四、实验步骤
1、根据文法编写.y文件:
%{ #include<ctype.h> #include<stdio.h> #define YYSIYPE double
} }
五、实验结果
六、心得体会
其实这个实验并不难,不过很容易出错。在按照文法产生式编写.y文件时,
只要不注意写错,那或者在编译的无法生成.c文件,或者生成.c文件后在项目编 译时生成一大堆的错误。在理论课上学习了yacc进行语法分析的原理,这次通过 实验观察yacc的移入规约情况可以说是对课本知识的复习,收获很多。
;
rel
: expr '<' expr {printf("rel->expr<expr\n");}
| expr LE expr {printf("rel->expr<=expr\n");}
| expr '>' expr {printf("rel->expr>expr\n");}
| expr GE expr {printf("rel->expr>=expr\n");}
char filename[200]; printf("请输入源程序文件名:"); scanf("%s:",filename); BeginCompileOneFile( filename ); yyparse(); EndCompileOneFile();
}
3、修改实验三的.l文件,删除main()函数:
program : block {printf("program->block\n");} ;
block : '{'decls stmts'}' {printf("block->decls stmts\n");}
;
decls : decls decl {printf("decls->decls decl\n");}
4、用flex.exe编译.l文件,生成lex.yy.c
5、用bison.exe编译.y文件,生成my.tab.c
6、在VC下建立工程,添加lex.yy.c和my.tab.c文件
7、以文件读入方式进行测试,测试例子为: {
i = 2; while (i <=100) {
sum = sum + i; i = i + 2;
;
term : term '*' unary {printf("term->term*unary\n");}
| term '/' unary {printf("term->term/unary\n");} | unary {printf("term->unary\n");} ; unary: '!' unary {printf("unary->!unary\n");} | '-' unary {printf("unary->-unary\n");} | factor {printf("unary->factor\n");} ; factor: '(' bool ')' {printf("factor->(bool)\n");} | loc {printf("factor->loc\n");} | NUM {printf("factor->num\n");} | REAL {printf("factor->real\n");} | TRUE {printf("factor->true\n");} | FALSE {printf("factor->false\n");} ; %%
bool : bool OR join {printf("bool->bool||join\n");}
| join {printf("bool->join\n");}
;
join : join AND equality {printf("join->join && equality\n");}
| equality {printf("join->equality\n");}
printf("%s\n",s); } %} %token NUM %token BASIC IF ELSE DO BREAK REAL TRUE FALSE ID LE INDEX %token WHILE AND OR EQ NE GE %left '+''-' %left '*''/' %right UMINUS %%
| expr {printf("rel->expr\n");}
;
expr : expr '+' term {printf("expr->expt+term\n");}
| expr '-' term {printf("expr->expr-term\n");}
| term {printf("expr->term\n");}
实验 4 用 Yacc 工具构造语法分析器
一、实Βιβλιοθήκη Baidu目的
掌握移进-归约技术语法分析技术,利用语法分析器生成工具 Yacc/Bison 实 现语法分析器的构造。
二、实验内容
利用语法分析器生成工具 Yacc/Bison 编写一个语法分析程序,与词法分析器 结合,能够根据语言的上下文无关文法,识别输入的单词序列是否文法的句子。
| {printf("\decls->E\n");}
;
decl : type ID ';' {printf("decl->type id\n");}
;
type : type '[' NUM ']' {printf("type->type [num]\n");}
| BASIC {printf("type->basic\n");}
|IF '(' bool ')' stmt ELSE stmt {printf("stmt->if(bool) stmt else stmt\n");}
|WHILE '(' bool')' stmt {printf("stmt->while(bool) stmt\n");}
|DO stmt WHILE '(' bool ')' ';' {printf("stmt->->do stmt while(bool)\n");}
;
equality : equality EQ rel {printf("equality->equality==rel\n");}
| equality NE rel {printf("equality->equality!=rel\n");}
| rel {printf("equality->rel\n");}
;
stmts : stmts stmt {printf("stmts->stmts stmt\n");}
| {printf("stmts->E\n");}
;
stmt : loc '=' bool ';' {printf("stmt->loc=bool\n");}
|IF '(' bool ')' stmt {printf("stmt->if(bool) stmt\n");}
|BREAK ';' {printf("stmt->break\n");}
| block {printf("stmt->block\n");}
;
loc
: loc '[' bool ']' {printf("loc->loc[bool]\n");}
|ID {printf("loc->id\n");}
;
2、在.y文件中添加main()函数,以及一些外部函数的声明:
#include "lex.yy.c" int yyparse(); extern void BeginCompileOneFile( const char * filename ); extern void EndCompileOneFile(void); void main() {
三、实验要求
1.个人完成,提交实验报告。 2.实验报告中给出采用测试源代码片断,及其对应的最右推导过程(形式可以 自行考虑,如依次给出推导使用的产生式)。
例如,程序片断
四、实验步骤
1、根据文法编写.y文件:
%{ #include<ctype.h> #include<stdio.h> #define YYSIYPE double
} }
五、实验结果
六、心得体会
其实这个实验并不难,不过很容易出错。在按照文法产生式编写.y文件时,
只要不注意写错,那或者在编译的无法生成.c文件,或者生成.c文件后在项目编 译时生成一大堆的错误。在理论课上学习了yacc进行语法分析的原理,这次通过 实验观察yacc的移入规约情况可以说是对课本知识的复习,收获很多。
;
rel
: expr '<' expr {printf("rel->expr<expr\n");}
| expr LE expr {printf("rel->expr<=expr\n");}
| expr '>' expr {printf("rel->expr>expr\n");}
| expr GE expr {printf("rel->expr>=expr\n");}
char filename[200]; printf("请输入源程序文件名:"); scanf("%s:",filename); BeginCompileOneFile( filename ); yyparse(); EndCompileOneFile();
}
3、修改实验三的.l文件,删除main()函数:
program : block {printf("program->block\n");} ;
block : '{'decls stmts'}' {printf("block->decls stmts\n");}
;
decls : decls decl {printf("decls->decls decl\n");}
4、用flex.exe编译.l文件,生成lex.yy.c
5、用bison.exe编译.y文件,生成my.tab.c
6、在VC下建立工程,添加lex.yy.c和my.tab.c文件
7、以文件读入方式进行测试,测试例子为: {
i = 2; while (i <=100) {
sum = sum + i; i = i + 2;
;
term : term '*' unary {printf("term->term*unary\n");}
| term '/' unary {printf("term->term/unary\n");} | unary {printf("term->unary\n");} ; unary: '!' unary {printf("unary->!unary\n");} | '-' unary {printf("unary->-unary\n");} | factor {printf("unary->factor\n");} ; factor: '(' bool ')' {printf("factor->(bool)\n");} | loc {printf("factor->loc\n");} | NUM {printf("factor->num\n");} | REAL {printf("factor->real\n");} | TRUE {printf("factor->true\n");} | FALSE {printf("factor->false\n");} ; %%
bool : bool OR join {printf("bool->bool||join\n");}
| join {printf("bool->join\n");}
;
join : join AND equality {printf("join->join && equality\n");}
| equality {printf("join->equality\n");}