免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5838 | 回复: 2
打印 上一主题 下一主题

yacc不使用优先规则解决移进/规约冲突的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-11-12 17:42 |只看该作者 |倒序浏览
本帖最后由 一刀。 于 2012-11-12 17:46 编辑

初学lex和yacc,书上有两个例子,一个是使用优先规则的运行没有问题,另一个不使用优先规则的死活跑不过去,甚至连乘法除法都有问题,请大牛指教一下

下面这个是词法分析程序
  1. %{
  2. #include "y.tab.h"
  3. extern int yylval;
  4. %}

  5. %%
  6. [0-9]+  { yylval = atoi(yytext); return NUMBER; }
  7. [ \t]+  ;
  8. \n return 0;
  9. [_a-zA-Z][_a-zA-Z0-9]*  { return NAME; }
  10. [=\*\/\(\)\+\-]         { return yytext[0]; }
  11. %%
复制代码
下面这个是使用有限规则的语法分析程序,运行没有问题
  1. %{
  2. #include <stdio.h>
  3. %}

  4. %token NAME NUMBER
  5. %left '-' '+'
  6. %left '*' '/'
  7. %nonassoc UMINUS

  8. %%
  9. statement: NAME '=' expression
  10.   | expression { printf("= %d\n", $1); }
  11.   ;

  12. expression: expression '+' expression { $$ = $1 + $3; }
  13.   | expression '-' expression         { $$ = $1 - $3; }
  14.   | expression '*' expression         { $$ = $1 * $3; }
  15.   | expression '/' expression
  16.     {
  17.       if($3 == 0)
  18.         yyerror("divide by zero");
  19.       else
  20.         $ = $1 / $3;
  21.     }
  22.   | '-' expression %prec UMINUS       { $$ = -$2; }
  23.   | '(' expression ')'                { $$ = $2; }
  24.   | NUMBER                            { $$ = $1; }
  25.   ;
  26. %%

  27. extern FILE *yyin;

  28. int main()
  29. {
  30.         do
  31.         {
  32.                 yyparse();
  33.         }
  34.         while(!feof(yyin));
  35. }
复制代码
下面这个是不使用优先规则的程序,乘法、除法和小括号都有问题
  1. %{
  2. #include <stdio.h>
  3. %}

  4. %token NAME NUMBER

  5. %%
  6. statement: NAME '=' expression
  7.   | expression { printf("= %d\n", $1); }
  8.   ;

  9. expression: expression '+' mulexp { $$ = $1 + $3; }
  10.   | expression '-' mulexp  { $$ = $1 - $3; }
  11.   | primary                { $$ = $1; }
  12.   ;

  13. mulexp: mulexp '*' primary { $$ = $1 * $3; }
  14.   | mulexp '/' primary
  15.     {
  16.       if($3 == 0)
  17.         yyerror("divide by zero");
  18.       else
  19.         $$ = $1 / $3;
  20.     }
  21.   | primary
  22.   ;

  23. primary: '(' expression ')' { $$ = $2; }
  24.   | '-' primary             { $$ = -$2; }
  25.   | NUMBER                  { $$ = $1; }
  26.   ;

  27. %%

  28. extern FILE *yyin;

  29. int main()
  30. {
  31.         do
  32.         {
  33.                 yyparse();
  34.         }
  35.         while(!feof(yyin));
  36. }
复制代码

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
2 [报告]
发表于 2012-11-12 20:03 |只看该作者
一刀。 发表于 2012-11-12 17:42
初学lex和yacc,书上有两个例子,一个是使用优先规则的运行没有问题,另一个不使用优先规则的死活跑不过去, ...

你的乘法和除法都无法被规约成statement,当然是语法错误
在你的程序中,乘法和除法唯一可以被规约成statement的机会是
expression: expression '+' mulexp
expression: expression '-' mulexp
也就是前面必须要有加减法
所以以下都是不符合你的语法的
linux-s3hu:/tmp/compile # ./a.out
2*3
= 2
syntax error
= 3

linux-s3hu:/tmp/compile # ./a.out
2*3+1
= 2
syntax error
= 4

以下才符合你的语法
linux-s3hu:/tmp/compile # ./a.out
1+2*3
= 7

论坛徽章:
0
3 [报告]
发表于 2012-11-12 20:31 |只看该作者
本帖最后由 一刀。 于 2012-11-12 20:40 编辑

回复 2# cjaizss


    谢谢!我把primary改成mulexp通过了。我看书不仔细
  1. %{
  2. #include <stdio.h>
  3. %}

  4. %token NAME NUMBER

  5. %%
  6. statement: NAME '=' expression
  7.   | expression { printf("= %d\n", $1); }
  8.   ;

  9. expression: expression '+' mulexp { $$ = $1 + $3; }
  10.   | expression '-' mulexp  { $$ = $1 - $3; }
  11.   | mulexp                { $$ = $1; }
  12.   ;

  13. mulexp: mulexp '*' primary { $$ = $1 * $3; }
  14.   | mulexp '/' primary
  15.     {
  16.       if($3 == 0)
  17.         yyerror("divide by zero");
  18.       else
  19.         $ = $1 / $3;
  20.     }
  21.   | primary
  22.   ;

  23. primary: '(' expression ')' { $$ = $2; }
  24.   | '-' primary             { $$ = -$2; }
  25.   | NUMBER                  { $$ = $1; }
  26.   ;

  27. %%

  28. extern FILE *yyin;

  29. int main()
  30. {
  31.         do
  32.         {
  33.                 yyparse();
  34.         }
  35.         while(!feof(yyin));
  36. }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP