我读了很多资料,但还是不明白:
%nonassoc
和 %token
? 之间有什么区别
我明白
%left
和%right
之间的区别,但对我来说前两个听起来是一样的。
我希望如果有人能给我几个例子来理解我什么时候需要使用
%nonassoc
以及什么时候使用%token
?
使用
%token
?
使用%token
?
使用%token
?
%token 是声明终端的基本方式。
如果有任何优先级歧义,使用 %nonassoc 将抛出语法错误。
根据我的经验,终端除了 %token 之外不需要任何其他东西。
这里是
$ info bison
的相关部分
3.7.3 Operator Precedence
-------------------------
Use the ‘%left’, ‘%right’, ‘%nonassoc’, or ‘%precedence’ declaration to
declare a token and specify its precedence and associativity, all at
once. These are called “precedence declarations”. *Note Precedence::,
for general information on operator precedence.
The syntax of a precedence declaration is nearly the same as that of
‘%token’: either
%left SYMBOLS...
or
%left <TYPE> SYMBOLS...
And indeed any of these declarations serves the purposes of ‘%token’.
But in addition, they specify the associativity and relative precedence
for all the SYMBOLS:
• The associativity of an operator OP determines how repeated uses of
the operator nest: whether ‘X OP Y OP Z’ is parsed by grouping X
with Y first or by grouping Y with Z first. ‘%left’ specifies
left-associativity (grouping X with Y first) and ‘%right’ specifies
right-associativity (grouping Y with Z first). ‘%nonassoc’
specifies no associativity, which means that ‘X OP Y OP Z’ is
considered a syntax error.
‘%precedence’ gives only precedence to the SYMBOLS, and defines no
associativity at all. Use this to define precedence only, and
leave any potential conflict due to associativity enabled.
• The precedence of an operator determines how it nests with other
operators. All the tokens declared in a single precedence
declaration have equal precedence and nest together according to
their associativity. When two tokens declared in different
precedence declarations associate, the one declared later has the
higher precedence and is grouped first.
%token
声明令牌
%nonassoc
decalres 令牌并设置它们的优先级
%left
/%right
声明标记并设置它们的优先级并设置它们的结合性
所以你使用哪个取决于你是不想设置优先级,还是只设置优先级,或者同时设置优先级和结合性。
那么优先级和结合性有什么区别呢?当移动令牌和减少包含具有优先级(以及可能的关联性)的令牌1 的规则之间存在冲突时,它们都用于解决转移/减少冲突。优先级用于所讨论的标记不同(或至少具有不同的优先级),而结合性用于标记相同(或至少具有相同的优先级)
1Yacc实际上是比较要归约的规则和要移位的token的优先级和结合性。只是规则总是从标记中获得优先级/关联性(规则中的一个,或者用
%prec
指定的)