简体   繁体   English

一元运算符应该如何应用于表达式语法?

[英]How should a unary operator be applied in an expression grammar?

I have a grammar that I've implemented in C#.我有一个在 C# 中实现的语法。 My question relates to evaluating expressions.我的问题与评估表达式有关。 A cutdown version of the grammar just relating to expressions is.仅与表达式有关的语法的简化版本是。 Note that the grammar also supports logical operations (using AND and OR, rather than && and ||):请注意,语法还支持逻辑运算(使用 AND 和 OR,而不是 && 和 ||):

Expression => [ NegOp ] <Term> { <AddOp> <Term> }
Term =>       <Power> { <MulOp> <Power> }
Power =>      <Factor> [ ^ <Factor> ]
Factor =>     <Numeric> | ( OPENPAREN <Expression> CLOSEPAREN )
Numeric =>    <Float> | <Integer>
NegOp =>      + | - | NOT
AddOp =>      + | - | OR
MulOp =>      * | / | % | AND

I've implemented Left to Right evaluation of expressions, so that, for instance:我已经实现了表达式的从左到右评估,例如:

5 / 6 / 7

is interpreted as:被解释为:

(5 / 6) / 7

However, I'm unclear how to apply the NegOp to the Expression.但是,我不清楚如何将 NegOp 应用于表达式。 If I have the Expression:如果我有表达式:

5 - 4 * 3    => -7

and I prefix it with a minus sign, thus:我在它前面加上一个减号,因此:

-5 - 4 * 3

should this be interpreted as:这应该被解释为:

-(5 - 4 * 3)      => 7

or:或者:

(-5) - 4 * 3      => -17

ie Should the NegOp bind tightly to the first Term in the Expression, or apply to the Expression as a whole after evaluation?即 NegOp 是否应该与表达式中的第一个术语紧密绑定,还是在评估后应用于整个表达式?

Normally, unary prefix operators are located almost at the top of the operator precedence chain, just below postfix operators.通常,一元前缀运算符几乎位于运算符优先级链的顶部,就在后缀运算符的下方。 One way to do that would be to add them to what you call Factor :一种方法是将它们添加到您所谓的Factor中:

Factor =>     <Numeric> | OPENPAREN <Expression> CLOSEPAREN | NegOp Factor

That could be written as { NegOp } ( <Numeric> | OPENPAREN <Expression> CLOSEPAREN ) but I feel that using "a repetition of NegOp " inappropriately separates the operator(s) from the operand.这可以写成{ NegOp } ( <Numeric> | OPENPAREN <Expression> CLOSEPAREN )但我觉得使用“ NegOp的重复”不恰当地将运算符与操作数分开。 Also, some people might be inclined to use a single optional [ NegOp ] instead of arbitrary repetition, but that's seems hard to justify.此外,有些人可能倾向于使用单个可选的[ NegOp ]而不是任意重复,但这似乎很难证明。 Is there any good reason to disallow the use of two different unary operators on the same operand?是否有充分的理由禁止在同一个操作数上使用两个不同的一元运算符? But those are decisions you'll have to make.但这些都是你必须做出的决定。

However, in the specific case of unary minus in combination with exponentiation, it is moderately common but not universal to give exponentiation priority, since you would practically never want -2^20 to mean (-2)^20 , which is mathematically the same as 2^20 .但是,在一元减号与取幂组合的特定情况下,赋予取幂优先级是适度常见但并不普遍,因为您实际上永远不会希望-2^20表示(-2)^20 ,这在数学上是相同的作为2^20 I'd be inclined to go with the majority view on this, but both decisions are legitimate.我倾向于 go 对此有多数意见,但这两个决定都是合法的。

Exponentation itself is usually right-associative, unlike other mathematical operators, again because the other grouping doesn't add anything useful.与其他数学运算符不同,指数本身通常是右结合的,这也是因为其他分组不会添加任何有用的东西。 (a^b)^c is exactly the same as a^(b*c) , and would usually be better computed as the second; (a^b)^ca^(b*c)完全相同,通常最好计算为第二个; the expression you normally want is a^(b^c) .您通常想要的表达式是a^(b^c) I don't know of any commonly-used language with exponentiation in which exponentation groups to the left.我不知道任何常用的幂语言,其中幂在左侧分组。 Your decision to make exponentiation non-grouping also seems to me eccentric.在我看来,您使求幂不分组的决定也很古怪。 But it's your language.但这是你的语言。


It's maybe also worth adding that not all prefix operators have naturally high precedence.可能还值得补充的是,并非所有前缀运算符都具有天然的高优先级。 But it depends on what you mean by "operator".但这取决于您所说的“操作员”是什么意思。

For example, most languages have constructs like例如,大多数语言都有类似的结构

return x + y
assert i < n

These might look more like "statements" than "prefix operators", but syntactically the difference is minor.这些可能看起来更像“语句”而不是“前缀运算符”,但在语法上差异很小。 It's true that they don't return values, but there are variants which do, such as Python's yield operator.确实,它们不返回值,但有一些变体可以,例如 Python 的yield运算符。

Also, some languages have constructs like此外,某些语言具有类似的结构

lambda t: 42 * t         # There are many ways to spell lambda
let t = f(a) in t + 6

These are both bracketed prefix operators (in the same way that the subscript index operator v[i] is a bracketed postfix operator or that the C family's "ternary operator" is really a bracketed infix operator with low precedence. The bracketed part does contain an operand, but it's effectively fully parenthesized so you don't need to worry about it during the parse. So again they are syntactically the same as a prefix operator.它们都是带括号的前缀运算符(就像下标索引运算符v[i]是带括号的后缀运算符或 C 系列的“三元运算符”实际上是带括号的低优先级中缀运算符一样。括号部分确实包含操作数,但它实际上是完全括起来的,所以在解析过程中你不需要担心它。所以它们在语法上与前缀运算符相同。

All of these operators are at (or close to) the bottom of the precedence hierarchy;所有这些运算符都位于(或接近)优先级层次结构的底部 they basically take "the rest of the subexpression" to be their argument.他们基本上将“子表达式的 rest”作为他们的论据。 (In other words, the argument continues until terminated with a close parenthesis or whatever passes for a statement delimiter in the language. So if you have those things, your precedence hierarchy will have prefix operators close to both ends of the precedence list. But that's fine. The parse still works. (换句话说,参数一直持续到以右括号或语言中的语句分隔符传递的任何内容终止。因此,如果您有这些东西,您的优先级层次结构将在优先级列表的两端附近有前缀运算符。但那是很好解析仍然有效。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 一元运算符“&amp;”如何工作 - How does Unary Operator '&' work 如何添加具有应具有三元运算符的表达式的数据列 - How to add a datacolumn with a expression which should have a ternary operator 运算符“&”不能被应用于类型的操作数“labda表达”和“lambda表达式” - Operator '&&' cannot be applied to operands of type 'labda expression' and 'lambda expression' 运算符&#39;&amp;&amp;&#39;不能应用于&#39;lambda expression&#39;和&#39;lambda表达式&#39;类型的操作数 - Operator '&&' cannot be applied to operands of type 'lambda expression' and 'lambda expression 运营商&#39;||&#39; 不能应用于&#39;lambda expression&#39;和&#39;lambda expression&#39;类型的操作数 - Operator '||' cannot be applied to operands of type 'lambda expression' and 'lambda expression' 运算符“op”不能应用于“动态”和“lambda 表达式”类型的操作数 - Operator 'op ' cannot be applied to operands of type 'dynamic' and 'lambda expression' 运算符“ ??” 不能应用于IQueryContainer和lambda表达式类型的操作数 - Operator '??' cannot be applied to operands of type IQueryContainer and lambda expression 运算符&#39;||&#39; 不能应用于&#39;bool&#39;和&#39;lambda expression&#39;类型的操作数 - Operator '||' cannot be applied to operands of type 'bool' and 'lambda expression' 运算符优先级和一元运算符具有讽刺意味 - Operator precedence and unary operators in irony “错误:一元运算符预期”重载运算符&#39;*&#39; - “Error: Unary operator expected” when overloading operator '*'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM