yacc转移减少问题

时间:2010-02-13 07:17:38

标签: grammar yacc shift-reduce-conflict

我认为我的语法是一个简单的部分,这是从yacc得到错误。我知道我需要在某处添加%prec,但不确定在哪里。

Assignment : Ref '=' Ref
           | Ref '=' Expression
           | Ref '=' Value
           | Ref '=' FunctionCall
           ;

Ref : ID
    | ID '[' Expression ']'
    ;

Value : INT
      | BOOLEAN
      | CHAR
      | STRING
      ;

我得到的错误是:

 warning: rule never reduced because of conflicts: Assignment: Ref '=' Ref
 warning: rule never reduced because of conflicts: Assignment: Ref '=' Value

因此ID只是一个变量名,而Ref是对变量的引用。

4 个答案:

答案 0 :(得分:1)

嗯,不确定,FunctionCall,Value和Ref也是Expressions吗?也许如果删除Expression时它可以工作,那么可能会建议Expression包含其中一个......

答案 1 :(得分:1)

Assignment : Ref '=' Ref Ref = Ref = Ref的问题不明确(您可能已经知道);尝试使用%right关键字定义'='标记(假设您希望“=”为右关联):

%right '='

对于Assignment: Ref '=' Value,我必须看到ID和各种Value主体的定义,但将'='定义为右关联可能就足够了。

答案 2 :(得分:1)

我们确实需要看到FunctionCall和(特别是)Expression的定义来给出明确的答案,但我的猜测是Expression可以是单个Ref或Value。在这种情况下,它表示它不知道(肯定)是否直接将赋值右侧的Ref / Value解析为自身,或者作为简单表达式。

令人惊讶的是,FunctionCall没有产生类似的歧义 - 这往往表明你对Expression的定义可能是奇怪的,至少接近有缺陷。

如果我这样做,我可能会将Assignment的定义更改为:

%left '-' '+'
%left '*' '/'   

%%

Assignment: Ref '=' Expression;

Expression: Value
          | FunctionCall
          | Ref
          | Expression '+' Expression
          | Expression '-' Expression
          | Expression '/' Expression
          | Expression '*' Expression
          | '(' Expression ')'
          ; 

当然,您可能希望支持更多的运营商而不是基本的运营商,但很难猜测 - 我只是试图投入足够的话来提供至少一个合理的想法。

在任何情况下,使用这种结构毫无疑问,赋值的右侧有是一个表达式,而表达式可以包含你列出的三个基本项,结合任意算术运算符,如:

x[i] = a[2] + 1 + f(3)

必须(逐步):

Ref = Expression
Ref = Expression '+' Expression
Ref = Expression '+' Expression '+' Expression
Ref = Ref '+' Value '+' FunctionCall
ID '[' ID ']' '=' ID '[' Value ']' '+' Value '+' FunctionCall

(并且FunctionCall可能会进一步减少到:ID '(' Value ')'

结论:至少这部分语法基本上不受S / R冲突的影响 - 从顶级Assignment到特定任务的单个令牌,有一条明确,明确的路径。这也有助于减少用户的混淆,因为所有表达式都具有相同的语法。

答案 3 :(得分:0)

似乎解析器无法区分语法中的各种Assignment字符串(相当严格)的预测限制。

如果IDValue制作很容易解析,我认为你不会遇到这个问题。你很可能将所有Assignment个产品组合成一个,这至少可以更容易地减少这一个规则并使问题更加明显。