【问题标题】:Shift/reduce conflicts in yaccyacc 中的移位/减少冲突
【发布时间】:2014-04-25 12:49:58
【问题描述】:

我正在学习 lex 和 yacc 编程以及这个 yacc 程序来验证和评估算术表达式,从而给我 10 个移位/减少冲突。你能指出这个程序有什么问题吗

这是 611.y

%{
#include<stdio.h>
int flag=1;
%}

%token id num 
%left '(' ')'
%left '+' '-'
%left '/' '*'
%nonassoc UMINUS

%%

stmt:
    expression { printf("\n valid exprn");}
    ;

expression:
    '(' expression ')' 
    | '(' expression {printf("\n Syntax error: Missing right paranthesis");}
    | expression '+' expression {printf("\nplus recog!");$$=$1+$3;printf("\n %d",$$);}
    | expression '+' { printf ("\n Syntax error: Right operand is missing ");}
    | expression '-' expression {printf("\nminus recog!");$$=$1-$3;printf("\n %d",$$);}
    | expression '-' { printf ("\n Syntax error: Right operand is missing ");}
    | expression '*' expression {printf("\nMul recog!");$$=$1*$3;printf("\n %d",$$);}
    | expression '*' { printf ("\n Syntax error: Right operand is missing ");}
    | expression '/' expression {printf("\ndivision recog!");if($3==0) printf("\ndivision cant be done, as divisor is zero.");else {$$=$1+$3;printf("\n %d",$$);}}
    | expression '/' { printf ("\n Syntax error: Right operand is missing ");}
    | expression '%' expression
    | expression '%' { printf ("\n Syntax error: Right operand is missing ");}
    | id
    | num 
;

%%

main()
{
    printf(" Enter an arithmetic expression\n");
    yyparse();
}

yyerror()
{
    printf(" Invalid arithmetic Expression\n");
    exit(1);
}

这是 611.l

%{
#include "y.tab.h"
#include<stdio.h>
#include<ctype.h>
extern int yylval;
int val;
%}

%%

[a-zA-Z][a-zA-Z0-9]* {printf("\n enter the value of variable %s:",yytext);scanf("%d",&val);yylval=val;return id;}
[0-9]+[.]?[0-9]* {yylval=atoi(yytext);return num;}
[ \t] ;
\n {return 0;}
. {return yytext[0];}
%%

int yywrap()
{
    return 1;
}

当我像这样编译代码时

lex 611.l

yacc -d 611.y

它给了我

yacc:10 shift/reduce conflicts.

请帮帮我。

【问题讨论】:

    标签: c compiler-construction yacc lex


    【解决方案1】:

    有两点是错的:

    1. '%' 的优先级缺失,将其添加到'/' '*'
    2. '(' expression 错误处理程序不明确(在表达式(4*(2+3)+5*7 中有很多方法可以插入缺少的括号)并且实际上与正常的'(' expression ')' 规则相冲突。使这样的处理程序工作并非易事。我建议删除它并依赖内置的 yacc 错误处理程序。

    简单的错误处理可以这样实现:

    stmt:
        expression { printf("\n valid exprn");}
        | error { printf(" Invalid arithmetic Expression\n"); }
        ;
    
     expression:
        '(' expression ')' 
        | '(' error ')' { printf(" Invalid arithmetic Expression\n"); }
        | ... /* all the rest */
    

    您也不需要所有其他错误处理程序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多