我正在使用bison将解析器编写成类C语法,但我在变量声明中遇到问题。
我的变量可以是简单的变量,数组或结构,所以我可以使用像 a.b [3] .c 这样的变量。
我有以下规则:
var : NAME /* NAME is a string */
| var '[' expr ']'
| var '.' var
;
这给了我一个转变/减少冲突,但我无法想出解决这个问题的方法。
如何重写语法或使用Bison优先级来解决问题?
答案 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 ']'
;