140 likes | 414 Views
Introduction of Bison/Yacc. Yet another compiler-compiler. LALR(1) 分析生成器 安装 Bison 编写 .y 文件,描述文法 Bison *.y 生成 .c 文件 VC 编译 .c 文件生成 exe 文件 运行 exe 分析输入串. Yacc 说明文件 (.h) { 定义 } %% { 规则 } %% 辅助程序. Example. exp -> exp addop term | term addop -> + | - term -> term mulop factor | factor
E N D
Yet another compiler-compiler • LALR(1)分析生成器 • 安装Bison • 编写.y文件,描述文法 • Bison *.y生成.c文件 • VC编译.c文件生成exe文件 • 运行exe分析输入串
Yacc说明文件(.h) • {定义} • %% • {规则} • %% • 辅助程序
Example • exp -> exp addop term | term • addop -> + | - • term -> term mulop factor | factor • mulop -> * • factor -> (exp) | number • 对应的.y文件
解释 • exp : exp ‘+’ term { $$ = $1 + $3; } • yylval • yylex • yyerror • yyparse
分析表以及分析过程 • Bison -v *.y 生成对应 .output 文件 • .output文件即生成的LALR(1)分析表 • 设置yydebug可直接输出分析过程
处理二义性 • E -> E+E | E-E | E*E | E/E | (E) | -E | E^E | number • 归约-归约冲突:选择说明中最先出现的产生式 • 移进-归约冲突:移进优先 • 算符优先与结合性
算符的优先级与结合性 • 优先级(越后出现优先级越高) • %left ‘+’ ‘-’ • %left ‘*’ • 结合性 • %left ‘+’ ‘-’ • 12+34-12 • %right (右结合) • %nonassoc (重复的算符不允许出现在相同的层级)
E -> E+E | E-E | E*E | E/E | (E) | -E | E^E | number • 对应的.y文件
Bison与Flex的结合 • Bison –d *.y 生成.h文件 • .h文件中存放需要的token • .l文件定义所有的token • Flex *.l • 替换yylex函数
YYSTYPE • $$, $1, $2的实际值,存放在yylval中 • 默认yylval为int类型 • 可通过#define YYSTYPE double设置为其他类型 • %union设置复杂的类型 • YYSTYPE也可定义为特定的类型(其他头文件中定义), #define YYSTYPE treeNode *
Example • %union{double val; char op} • %token NUM • %type <val> exp term factor NUM • %type <op> addop mulop • exp : exp op term {switch($2) • { • case ‘+’: $$ = S1 + S3; break; • case ‘-’: $$ = S1 – S2; break; • } • } • Tiny程序(编译原理与实践 附录)