2017-4-27
实验概述
•实验内容:用bison工具生成一个PL/0语言的语法分析程序,对PL/0源程序进行语法分析,并按语法归约过程输出归约时所用的语法规则。
•实验环境:
•语法分析器生成工具:bison
•编程语言:C
YACC概述(1)
YACC = Yet Another Compiler Compiler
YACC是一个语法分析程序的自动产生系统
YACC的处理能力:可以用LALR(1)文法表示的上下文无关文法。
语法规则的写法
格式: 左部(非终结符):右部(文法符号串);
非终结符名称通常用小写字母,终结符名称通常用大写字母。
右部为空表示左部的非终结符可以匹配空串。
左部相同的语法规则应尽量合并。
需要递归时,尽量使用左递归。
例如 StmtList : /* empty */
| StmtList Stmt
;
语义动作的写法
语义动作用{ }括起来,其中的语句要符合C语言文法。
语义动作出现在规则的尾部时,bison在归约前执行它。
语义动作出现在规则的中间时,bison在识别出它前面的若干文法符号后执行它。
例如:expr : LPAREN expr RPAREN
{ $ = $2; }
| expr PLUS expr
{ $ = $1 + $3; }
| expr TIMES expr
{ $ = $1 * $3; }
文法符号的语义值
终结符的语义值由词法分析程序给出,并保存在yylval中。
非终结符的语义值在语义动作中获得。
可以通过$伪变量访问语义值
左部非终结符的语义值为$$
右部文法符号的语义值依次为$1,$2,…
例如 exp : NUM { $$ = $1; }
| exp '+' exp { $ = $1 + $3; }
;
用户子程序
子程序用C语言书写,将被原样照抄到C语言文件中。
如果子程序比较简单,可以全都写在YACC源文件中。
如果子程序比较复杂,可以分别写在几个文件中。
实现代码:
有两个文件,比较复杂我就不直接贴
分别有定义词法分析的lex.l和定义输出的语法结构的syntax.y文件
用bison进行编译之后得到头文件syntax.tab.h和syntax.tab.c
用flex编译后得到lex.yy.c
用code blocks或者VS 编译运行,生成exe文件后,随便用样例进行分析即可,语法分析输出到标准流(即DOS界面)