英文:
Bison %nonassoc vs %token?
问题
%nonassoc
和 %token
之间的区别是什么?我理解 %left
和 %right
的区别,但对我来说前两者听起来一样。我希望有人能给我一些示例,以便了解何时需要使用 %nonassoc
和何时需要使用 %token
?使用 %token
?使用 %token
?使用 %token
?
英文:
I've read a lot of sources, but yet can't understand what's the difference between: %nonassoc
and %token
?
I understand the difference between %left
and %right
but for me the first two sound the same.
I hope if someone can give me few examples to understand when I need to use %nonassoc
and when to use %token
?
to use %token
?
to use %token
?
to use %token
?
答案1
得分: 1
%token 是声明终结符的基本方式。
使用 %nonassoc 会在存在优先级歧义时引发语法错误。
根据我的经验,你不需要除了 %token 之外的任何东西来定义终结符。
以下是来自 $ info bison
的相关部分:
3.7.3 操作符优先级
-------------------------
使用‘%left’、‘%right’、‘%nonassoc’或‘%precedence’声明来声明一个令牌并同时指定其优先级和结合性。这些被称为“优先级声明”。*参见 Precedence::,获取有关操作符优先级的一般信息。
优先级声明的语法与‘%token’的语法几乎相同:要么
%left SYMBOLS...
要么
%left <TYPE> SYMBOLS...
事实上,这些声明中的任何一个都能够完成‘%token’的任务。但另外,它们还指定了所有这些 SYMBOLS 的结合性和相对优先级:
• 运算符 OP 的结合性决定了如何处理运算符的重复使用:‘X OP Y OP Z’是否通过首先将 X 与 Y 组合或首先将 Y 与 Z 组合来解析。‘%left’ 指定左结合性(首先将 X 与 Y 组合),‘%right’ 指定右结合性(首先将 Y 与 Z 组合)。‘%nonassoc’ 指定无结合性,这意味着‘X OP Y OP Z’被视为语法错误。
‘%precedence’ 仅为 SYMBOLS 指定优先级,不定义任何结合性。使用它来仅定义优先级,而将由于结合性引起的任何潜在冲突启用。
• 运算符的优先级确定了它与其他运算符的嵌套方式。在单个优先级声明中声明的所有令牌具有相等的优先级,并根据它们的结合性进行嵌套。当在不同优先级声明中声明的两个令牌关联时,后声明的令牌具有更高的优先级,并首先分组。
英文:
%token is the basic way to declare a terminal.
Using %nonassoc will throw a syntax error if there is any precedence ambiguity.
From my experience, you shouldn't need anything other than %token for the terminals.
Here is the relevant section from $ 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.
答案2
得分: 1
%token
声明令牌(s)
%nonassoc
声明令牌(s) 并设置它们的优先级
%left
/%right
声明令牌并设置它们的优先级以及关联性
因此,您的选择取决于您是不想设置优先级,还是只想设置优先级,或者同时设置优先级和关联性。
那么优先级和关联性有什么区别呢?它们都用于解决移位/归约冲突,当移位一个令牌和归约一个包含一个令牌的规则之间存在冲突时,其中优先级(以及可能的关联性)会起作用。优先级用于当涉及的令牌不同(或至少具有不同的优先级)时,而关联性用于当令牌相同(或至少具有相同的优先级)时。
Yacc实际上是在比较将要归约的规则的优先级和关联性与将要移位的令牌的优先级和关联性。只是规则总是从一个令牌(要么是规则中的一个,要么是使用 %prec
指定的一个)那里获得优先级和关联性。
英文:
%token
declares token(s)
%nonassoc
declares token(s) AND sets their precedence
%left
/%right
declares tokens AND sets their precedence AND sets their associativity
So which you use depends on whether you want to not set the precedence at all, or set just the precedence, or set both precedence and associativity.
So what is the difference between precedence and associativity? They're both for resolving shift/reduce conflicts when there's a conflict between shifting a token and reducing a rule containing a token<sup>1</sup> with predence (and possibly associativity). The precedence is for when the tokens in question are different (or at least have different precedence), while the associativity is for when the tokens are the same (or at least have the same precedence)
<sup>1</sup><sub>Yacc is actually comparing the precedence and associativity of the rule to be reduced with that of the token to be shifted. It's just that rules always get precedence/associativity from a token (either one in the rule, or one specified with %prec
)</sub>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论