getianao 2012-07-23
08年9月入学,12年7月毕业,结束了我在软件学院愉快丰富的大学生活。此系列是对四年专业课程学习的回顾,索引参见:http://blog.csdn.net/xiaowei_cqu/article/details/7747205
语法分析
Yacc是一个用来生成编译器的编译器(编译器代码生成器)。yacc生成的编译器主要是用C语言写成的语法解析器(Parser),需要与词法解析器Lex一起使用,再把两部份产生出来的C程序一并编译。
作为Yacc对说明文件中的%tokenNUMBER声明的对应。Yacc坚持定义所有的符号记号本身,而不是从别的地方引入一个定义。但是却有可能通过在记号声明中的记号名之后书写一个值来指定将赋给记号的数字值。
Yacc的输入是巴科斯范式(BNF)表达的语法规则以及语法规约的处理代码,Yacc输出的是基于表驱动的编译器,包含输入的语法规约的处理代码部分。
Yacc是开发编译器的一个有用的工具,采用LALR(1)语法分析方法。
安装ParserGenerator,并编译lex和yacc函数库
编写Yacc程序如下:
line : bexpr '\n' {if($1==1){printf("true");}else{printf("false");}} | '\n' {printf("\n");} ; bexpr : bexpr '&' bterm { if(($1==1)&&($3==1)){$$=1;}else{$$=0;} } | bterm ; bterm : bterm '|' bfactor {if(($1==0)&&($3==0)){$$=0;}else{$$=1;}} | bfactor ; bfactor :'~' bfactor {if($2==1){$$=0;}else{$$=1;}} | '('bexpr')' {$$=$2;} | TRUE | FALSE在读到1或0(通过Lex定义的语法返回的响应值)以及‘|’或‘&’‘~’布尔运算符号时,进行布尔预算,并返回值
根据布尔运算的结果打印“true”或“false”的消息
在Yacc中只需定义相应的语法规则
line: L '\n' | '\n' ; L : S | L ',' S ; S :'(' L ')' {$$=$2;} | LETTER {printf("%c",$1);}并在遇到字符时,打印字符即可得到效果
之后通过C语言判断是否是回文:将第i个字符与第len-i-1个字符比较,如果有不相同的,则将标记tag标记为0(否则为1)
程序最后(读入换行符‘\n’时)通过tag标记输出是否为回文。