In the C99 standard, the expressions allow for precedence and associativity.
在C99标准中,表达式允许优先级和关联性。
Precedence is documented quite well since the order in which the operators appear in the document are of reducing precedence, so function calls come before multiplicative operators which, in turn, come before additive operators.
由于运算符在文档中出现的顺序优先级较低,所以优先级记录得非常好,因此函数调用在乘法运算符之前出现,而乘法运算符又在加法运算符之前出现。
However, I can't find a definitive description of the associativity, whether it's left or right. This is important since 35/5*2
would be 14
for one variant (35/5)*2
and 3
for the other variant 35/(5*2)
.
但是,我无法找到关联性的明确描述,无论是左还是右。这很重要,因为35/5 * 2对于一个变体(35/5)* 2将是14而对于另一个变体35 /(5 * 2)将是3。
Section 6.5 Expressions /3, footnote 74
state:
第6.5节表达式/ 3,脚注74状态:
The syntax specifies the precedence of operators in the evaluation of an expression, which is the same as the order of the major subclauses of this subclause, highest precedence first.
语法指定运算符在表达式求值中的优先级,该子表达式与本子条款的主要子条款的顺序相同,优先级最高。
Within each major subclause, the operators have the same precedence. Left- or right-associativity is indicated in each subclause by the syntax for the expressions discussed therein.
在每个主要子条款中,运算符具有相同的优先级。左或右相关性在每个子条款中通过其中讨论的表达式的语法指示。
However, taking the multiplicative case, for example:
但是,以乘法情况为例,例如:
6.5.5 Multiplicative operators
Syntax
multiplicative-expression:
cast-expression
multiplicative-expression * cast-expression
multiplicative-expression / cast-expression
multiplicative-expression % cast-expression
Constraints
Each of the operands shall have arithmetic type. The operands of the%
operator shall have integer type.
Semantics
The usual arithmetic conversions are performed on the operands.
The result of the binary*
operator is the product of the operands.
The result of the/
operator is the quotient from the division of the first operand by the second; the result of the%
operator is the remainder. In both operations, if the value of the second operand is zero, the behavior is undefined.
When integers are divided, the result of the/
operator is the algebraic quotient with any fractional part discarded. If the quotienta/b
is representable, the expression(a/b)*b + a%b
shall equala
.6.5.5乘法运算符语法multiplicative-expression:cast-expression multiplicative-expression * cast-expression multiplicative-expression / cast-expression multiplicative-expression%cast-expression约束每个操作数都应具有算术类型。 %运算符的操作数应具有整数类型。语义通常的算术转换是在操作数上执行的。 binary *运算符的结果是操作数的乘积。 /运算符的结果是第一个操作数除以第二个操作数的商; %运算符的结果是余数。在这两个操作中,如果第二个操作数的值为零,则行为未定义。当整数被划分时,/运算符的结果是代数商,丢弃任何小数部分。如果商a / b是可表示的,则表达式(a / b)* b + a%b应等于a。
I can see nothing in there that mentions the associativity, nor does there seem to be any default setting elsewhere in the standard.
我在那里什么都看不到提到关联性,标准中的其他地方似乎也没有任何默认设置。
Am I missing something here?
我在这里错过了什么吗?
2 个解决方案
#1
9
Operator associativity isn't specified explicitly as “right-associative” or “left-associative”. You deduce it from the grammar. In your example, the multiplicative-expression
term refers to itself recursively, and the recursion is on the left-hand side of the operator. That means that a parser encountering a * b * c
must parse a * b * c
like (a * b) * c
, which is left-associative.
运算符关联性未明确指定为“右关联”或“左关联”。你从语法中推断出它。在您的示例中,multiplicative-expression术语以递归方式引用自身,递归位于运算符的左侧。这意味着遇到* b * c的解析器必须解析a * b * c,如(a * b)* c,这是左关联的。
The assignment-expression
term (6.5.16) has this grammar:
赋值表达式术语(6.5.16)具有以下语法:
assignment-expression:
conditional-expression
unary-expression assignment-operator assignment-expression
So a parser encountering a = b = c
has to parse it like a = (b = c)
, which is right-associative.
因此,遇到a = b = c的解析器必须像a =(b = c)那样解析它,这是右关联的。
#2
3
The grammar itself specifies associativity, by the productions used:
语法本身通过使用的产品指定关联性:
multiplicative-expression:
cast-expression
multiplicative-expression * cast-expression
This means that in a * b * c
, c
must be parsed as a cast-expression
, and a * b
as one multiplicative-expression
, before further parsing of a * b
itself. Thus the left-associativity of multiplication is forced into the syntax-tree by the parsing rules.
这意味着在a * b * c中,在进一步解析a * b本身之前,c必须被解析为强制转换表达式,并且* b作为一个乘法表达式。因此,通过解析规则将乘法的左关联性强制进入语法树。
#1
9
Operator associativity isn't specified explicitly as “right-associative” or “left-associative”. You deduce it from the grammar. In your example, the multiplicative-expression
term refers to itself recursively, and the recursion is on the left-hand side of the operator. That means that a parser encountering a * b * c
must parse a * b * c
like (a * b) * c
, which is left-associative.
运算符关联性未明确指定为“右关联”或“左关联”。你从语法中推断出它。在您的示例中,multiplicative-expression术语以递归方式引用自身,递归位于运算符的左侧。这意味着遇到* b * c的解析器必须解析a * b * c,如(a * b)* c,这是左关联的。
The assignment-expression
term (6.5.16) has this grammar:
赋值表达式术语(6.5.16)具有以下语法:
assignment-expression:
conditional-expression
unary-expression assignment-operator assignment-expression
So a parser encountering a = b = c
has to parse it like a = (b = c)
, which is right-associative.
因此,遇到a = b = c的解析器必须像a =(b = c)那样解析它,这是右关联的。
#2
3
The grammar itself specifies associativity, by the productions used:
语法本身通过使用的产品指定关联性:
multiplicative-expression:
cast-expression
multiplicative-expression * cast-expression
This means that in a * b * c
, c
must be parsed as a cast-expression
, and a * b
as one multiplicative-expression
, before further parsing of a * b
itself. Thus the left-associativity of multiplication is forced into the syntax-tree by the parsing rules.
这意味着在a * b * c中,在进一步解析a * b本身之前,c必须被解析为强制转换表达式,并且* b作为一个乘法表达式。因此,通过解析规则将乘法的左关联性强制进入语法树。