转换/减少变量声明中的冲突

时间:2015-03-01 22:25:06

标签: parsing bison yacc

我正在使用bison将解析器编写成类C语法,但我在变量声明中遇到问题。

我的变量可以是简单的变量,数组或结构,所以我可以使用像 a.b [3] .c 这样的变量。

我有以下规则:

var : NAME             /* NAME is a string */
    | var '[' expr ']'
    | var '.' var
    ;

这给了我一个转变/减少冲突,但我无法想出解决这个问题的方法。

如何重写语法或使用Bison优先级来解决问题?

2 个答案:

答案 0 :(得分:1)

我不知道为什么你希望.[]运算符是关联的,但是这样的事情可能会激发你的灵感。

y
%union{}

%token NAME

%start var

%left   '.'
%left   '['

%%

var:
    NAME
|   var '[' expr ']'
|   var '.' var

此外,由于var可能出现在expr中,因此语法可能还有其他问题。

答案 1 :(得分:1)

使用优先声明解决这种转移 - 减少冲突当然是可能的,但在我看来,这只会使语法难以阅读。最好使语法反映语言的语义。

var(有些人可能称之为左值或引用)是简单标量变量的名称,或者是从命名复杂值和选择器的var迭代构建的表达式,成员名称或数组索引。换句话说:

var     : NAME
        | var selector
        ;
selector: '.' NAME
        | '[' expression ']'
        ;

这清楚地说明了a.b[3].c的含义是什么,例如;语义由解析树描述:

       a.b[3].c
     +----+----+
     |         |
   a.b[3]     .c
  +---+--+
  |      |
 a.b    [3]
+-+-+
|   |
a  .b

没有必要创建selector规则;将两条规则包装在一起是微不足道的。如果您觉得上面写的更清楚,以下内容也会起作用:

var: NAME
   | var '.' NAME
   | var '[' expression ']'
   ;