2

我有我认为是我语法的一个简单部分,这是来自 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

4 回答 4

1

嗯不确定,FunctionCall、Value 和 Ref 也会是表达式吗?也许如果在删除 Expression 时它可以工作,那可能表明 Expression 也包含其中之一......

于 2010-02-13T07:26:39.737 回答
1

is的问题Assignment : Ref '=' RefRef = Ref = Ref模棱两可的(你可能已经知道了);尝试使用%right关键字定义“=”标记(假设您希望“=”是右关联的):

%right '='

至于Assignment: Ref '=' Value,我必须查看ID各种Value主体的定义,尽管将 '=' 定义为右结合可能就足够了。

于 2010-02-13T07:39:40.657 回答
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到特定分配的单个标记有一条清晰、明确的路径。这也有助于减少用户的混淆,因为所有表达式都具有相同的语法。

于 2010-02-14T06:37:07.970 回答
0

看起来解析器无法区分Assignment语法中的各种字符串,因为它的前瞻限制(相当严格)。

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

于 2010-02-13T07:40:41.133 回答