收藏 分销(赏)

实验四编译用Yacc工具构造语法分析器.doc

上传人:丰**** 文档编号:10710327 上传时间:2025-06-11 格式:DOC 页数:10 大小:374.01KB 下载积分:8 金币
下载 相关 举报
实验四编译用Yacc工具构造语法分析器.doc_第1页
第1页 / 共10页
实验四编译用Yacc工具构造语法分析器.doc_第2页
第2页 / 共10页


点击查看更多>>
资源描述
实验4 用Yacc工具构造语法分析器 一、实验目的 掌握移进-归约技术语法分析技术,利用语法分析器生成工具Yacc/Bison实现语法分析器的构造。 二、实验内容 利用语法分析器生成工具Yacc/Bison编写一个语法分析程序,与词法分析器结合,能够根据语言的上下文无关文法,识别输入的单词序列是否文法的句子。 源语言的文法定义见教材附录 A.1,p394,要求实现完整的语言。 三、实验要求 1.个人完成,提交实验报告。 2.实验报告中给出采用测试源代码片断,及其对应的最右推导过程(形式可以自行考虑,如依次给出推导使用的产生式)。 例如,程序片断 四、实验思路 本次实验是一次实现词法分析和语法分析的过程,词法分析的内容与第二次实验类似,对关键词,数字,标识符以及其他类型的字符进行识别,分别返回对应的数据类型,这个过程相对来说是比较简单的,由于有特定的词法分析过程的格式,很容易将代码编写出来。语法分析的过程则给出了文法以及相应的语义动作,代码的编写相对比较复杂。 首先,在D:\FlexBison的目录下建立一个文件夹,我命名为expmt3,将bison.exe和flex.exe放到expmt3目录下。然后编写mylex.l文件和myyacc.y文件,在dos下切换到expmt3目录下,先用命令flex mylex.l生成lex.yy.c文件,再用命令bison –d myyacc.y生成myyacc.tab.c文件和myyacc.tab.h文件,在这个目录中再新建一个example.c文件,用vc++打开这个文件,然后编译这个文件,再将前两步生成的lex.yy.c、myyacc.tab.c和myyacc.tab.h文件加入到工程中,再编译并连接生成可执行文件。最后测试程序的正确性要在expmt3的debug目录下创建一个测试文件test.txt,将测试片段放入其中,然后在dos界面运行程序,知道产生正确的结果,实验就完成了。 五、具体代码 Mylex.l %option noyywrap %{ #include<ctype.h> #include<string.h> #include<stdio.h> #include<stdlib.h> #include "myYacc.tab.h" %} delim [ \t\n] ws {delim}+ letter [A-Za-z] digit [0-9] %% {ws} { } "if" {printf("IF ");return(IF);} "else" {printf("ELSE ");return(ELSE);} "int" {printf("INT "); return(BASIC);} "float" {printf("FLOAT "); return(BASIC);} "break" {printf("BREAK");return(BREAK);} "do" {printf("DO ");return(DO);} "while" {printf("WHILE ");return(WHILE);} "true" {printf("TRUE ");return(TRUE);} "index" {printf("INDEX "); return(INDEX);} "bool" {printf("BOOL "); return(BASIC);} "char" {printf("CHAR "); return(BASIC);} "real" {printf("real");return(REAL);} "false" {printf("FLASE "); return(FALSE);} [a-zA-Z_][a-zA-Z0-9_]* {printf("ID");return(ID);} [+-]?[0-9]+ {printf("NUM");return(NUM);} [+-]?[0-9]*[.][0-9]+ {printf("NUM");return(NUM);} "<" {printf("LT ");return('<');} "<=" {printf("LE ");return(LE);} "=" {printf("= ");return('=');} "==" {printf("EQ ");return(EQ);} "!=" {printf("NE ");return(NE);} ">" {printf("GT ");return('>');} ">=" {printf("GE ");return(GE);} "+" {printf("+ ");return('+');} "-" {printf("- ");return('-');} "[" {printf("[ ");return('[');} "]" {printf("] ");return(']');} "{" {printf("{");return('{');} "}" {printf("}");return('}');} "(" {printf("(");return('(');} ")" {printf(")");return(')');} ";" {printf(";");return(';');} "," {printf(",");return(',');} "&&" {printf("&&");return(AND);} "||" {printf("||");return(OR);} %% Myyacc.y %{ #include<ctype.h> #include<stdio.h> extern int yylex(); extern int yyerror(); %} %token NUM %token ID %token IF WHILE DO BREAK REAL TRUE FALSE BASIC ELSE INDEX GE LE NE EQ AND OR %% program : block { printf("program-->block\n"); } ; block : '{' decls stmts '}' { printf("block-->{decls stmts}\n"); } ; decls : | decls decl { printf("decls-->decls decl\n"); } ; decl : type ID ';' { printf("decl-->type id;\n"); } ; type : type '[' NUM ']' { printf("type-->type[num]\n"); } | BASIC { printf("type-->basic\n"); } ; stmts : | stmts stmt { printf("stmts-->stmts stmt\n"); } ; stmt : matched_stmt { printf("stmt-->matched_stmt\n");} | open_stmt { printf("stmt-->open_stmt\n");} ; open_stmt: IF '(' booL ')' stmt { printf("open_stmt-->if(bool)stmt\n");} | IF '(' booL ')' matched_stmt ELSE open_stmt { printf("open_stmt-->if(bool) matched_stmt else open_stmt\n");} ; matched_stmt: IF '(' booL ')' matched_stmt ELSE matched_stmt { printf("matched_stmt-->if(bool) matched_stmt else matched_stmt\n");} | other { printf("matched_stmt-->other\n");} ; other: loc '=' booL ';' { printf("stmt-->loc=bool;\n"); } | WHILE '(' booL ')' stmt { printf("stmt-->while(bool)stmt\n"); } | DO stmt WHILE '(' booL ')' ';' { printf("stmt-->do stmt while(bool);\n"); } | BREAK ';' { printf("stmt-->break;\n"); } | block { printf("stmt-->block\n"); } ; loc : loc '[' booL ']' { printf("loc-->loc[bool]\n"); } | ID { printf("loc-->id\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"); } ; equality : equality EQ rel { printf("equality-->equality==rel\n"); } | equality NE rel { printf("equality-->equality!=rel\n"); } | rel { printf("equality-->rel\n"); } ; rel : expr '<' expr { printf("rel-->expr<expr\n"); } | expr LE expr { printf("rel-->expr<=expr\n"); } | expr GE expr { printf("rel-->expr>=expr\n"); } | expr '>' expr { printf("rel-->expr>expr\n"); } | expr { printf("rel-->expr\n"); } ; expr : expr '+' term { printf("expr-->expr+term\n"); } | expr '-' term { printf("expr-->expr-term\n"); } | term { printf("expr-->term\n"); } ; 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"); } ; %% int yyerror(s) char *s; { fprintf(stderr,"syntactic error:%s\n",s); return 0; } 六、 实验结果 七、 实验总结 实验中的注意事项: (1)一个由 Yacc 生成的解析器调用 yylex() 函数来获得标记。对于由 Lex 生成的 lexer 来说,要和 Yacc 结合使用,每当 Lex 中匹配一个模式时都必须返回一个标记。 因此 Lex 中匹配模式时的动作一般格式为: {pattern} { /* do smthg*/ return TOKEN_NAME; } 于是 Yacc 就会获得返回的标记。当 Yacc 编译一个带有 _d 标记的myyacc .y文件时,会生成一个头文件myyacc.tab.h,它对每个标记都有 #define 的定义。 如果 Lex 和 Yacc 一起使用的话,头文件必须在相应的 Lex 文件mylex.l中的 C 声明段中包括。 (2)在myyacc.y中要加入对函数int yylex()和函数int yyerror()的外部声明。 (3)对文件放置的位置也要很小心,不然很容易就造成错误 (4)这次的实验使我对语法分析的过程更加了解,更多的掌握了移进——规约技术语法分析,对理论知识起到了巩固的作用,加强了编译整个理论体系的认识,也对flex &bison的操作有了更深一步的了解。
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服