免费注册 查看新帖 |

Chinaunix

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

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. }
复制代码

论坛徽章:
0
2 [报告]
发表于 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