问题标签 [associativity]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
parsing - 左结合运算符的 BNF 文法
对于带有左关联运算符的简单算术表达式,我有以下EBNF语法:
如何在不更改运算符关联性的情况下将其转换为BNF语法?以下 BNF 语法对我不起作用,因为现在运算符已变为右关联:
维基百科说:
几种解决方案是:
- 将语法重写为左递归,或
- 用更多的非终结符重写语法以强制正确的优先级/关联性,或
- 如果使用 YACC 或 Bison,则有运算符声明,%left、%right 和 %nonassoc,它们告诉解析器生成器强制执行哪种关联。
但它并没有说如何重写语法,我也没有使用任何解析工具,如 YACC 或 Bison,只是简单的递归下降。我所要求的甚至可能吗?
programming-languages - 为什么关联性是运算符的基本属性,而不是优先级的基本属性
在任何编程语言教科书中,我们总是被告知该语言中的每个运算符如何具有左关联性或右关联性。似乎关联性是任何运算符的基本属性,无论它采用多少操作数。在我看来,无论我们如何将关联性分配给其他运算符,我们都可以将任何关联性分配给任何运算符。
但为什么会这样呢?也许举个例子更好。假设我想设计一种假设的编程语言。以这种任意方式为这些运算符分配关联性是否有效(都具有相同的优先级):
!+ - * / 是我的 5 个运算符都具有相同的优先级。
如果是的话,我假设的解析器如何将像 2+2!3+5*6/3-5!3!3-3*2 这样的表达式括起来?以及为什么。
编辑:
第一个示例 (2+2!3+5*6/3-5!3!3-3*2) 不正确。也许忘记一元操作,让我这样说吧,我们可以像我上面那样分配具有相同优先级不同关联性的运算符吗?如果是,将如何评估示例,例如 2+3-4*5/3+2?因为大多数编程语言似乎为具有相同优先级的运算符分配了相同的关联性。但是我们总是谈论操作员关联性,就好像它是单个操作员的属性——而不是优先级的属性。
c++ - C/C++ 中的运算符优先级和关联性
请注意,这与运算符优先级无关。 () 和 ++ ,未定义的行为和序列点,为什么这些构造(使用 ++)未定义的行为?和数百个类似的问题在这里
很快:标准是否保证了关联性?
详细示例:来自维基百科的文章运算符优先级,operator*
并且operator/
具有相同的优先级并且它们是Left-to-right
运算符。这是否意味着,该标准保证,这:
将被评估为
或者它的实现定义?
如果有保障,可以报价吗?
只是出于好奇,我总是在这些情况下写括号。
准备删除问题,如果有这样的问题。
parsing - LR(0) 解析器中的后缀和右关联运算符
是否可以构造一个 LR(0) 解析器来解析具有前缀和后缀运算符的语言?例如,如果我有一个带有 +(加法)和 ! (阶乘)运算符通常优先于 1+3!应该是 1 + 3!= 1 + 6 = 7,但如果解析器是 LR(0),那么当它在堆栈上有 1+3 时,它肯定会减少而不是移位?
另外,右结合运算符会带来问题吗?例如,2^3^4 应该是 2^(3^4) 但同样,当解析器在堆栈上有 2^3 时,它如何知道减少或移位?
如果这不可能,是否还有办法使用 LR(0) 解析器,可能通过更改语法在适当的位置添加括号?
c - 请解释此代码中运算符的关联性
输出:11 99
请解释输出。为什么地址有增量?
c++ - 一元运算符具有关联性是否有意义?
来自http://en.cppreference.com/w/cpp/language/operator_precedence的 C++ 运算符优先级表(我知道这不是规范的,但标准没有讨论优先级或关联性)将一元运算符标记为右/左关联.
从对不同问题的讨论中,我留下了疑问。一元运算符具有关联性是否有意义?
c++ - 功能应用程序关联到左侧
根据该表,功能应用程序关联到左侧。这意味着什么?当二元运算符出现多次时,关联性很重要,例如在a - b - c
. 这与功能应用程序有什么关系?如果函数应用程序与右侧关联,它会有什么不同?
c++ - 是否违反过 C/C++ 运算符优先级和关联性规则?
是否在任何 C/C++ 表达式中违反了运算符优先级和关联性规则?
如果是这样,你能举个例子吗?
假设优先级和关联性规则的声明是:
每个运算符都有一个给定的优先级,每个优先级都有一个给定的关联性。如果两个运算符在它们期望操作数的地方看到一个子表达式,则它属于具有更高优先级的那个。联系被关联性打破。
编辑:背景
该标准将 C/C++ 表达式定义为 CFG,它比基于优先级的解析器灵活得多。例如,可以给二元运算符提供不对称的“优先级”,这会导致任何优先级表不正确。然而,在我看来,语法的设计被限制为支持简单的优先规则。以下是我遇到的一些所谓的“反例”:
1) a?b,c:d
不被解释为(a?b),(c:d)
一些人声称,?:
运算符对其中间操作数的优先级与对其其他操作数的优先级不同a?b,c:d
,例如,因为 不被解释为(a?b),(c:d)
。但是,既不b
也不c
占据它似乎?:
作为其内部操作数的位置。按此推理a[b+c]
应解释为(a[b)+(c])
,这是可笑的。
2) sizeof(int)*a
被解释为(sizeof(int))*a
而不是sizeof((int)(*a))
...因为 C 不允许将带括号的强制转换作为 sizeof 的运算符。但是,这两种解释都符合优先规则。混淆来自*
运算符的歧义(是二元运算符还是一元运算符?)。优先表并不意味着解决运算符的歧义。毕竟,它们不是运算符符号优先表。所以运算符优先级规则本身是完整的。
3) a+b=c
导致语法错误,而不是语义错误
a+b=c
,根据标准,是无效的 C语法。如果 C 有一个基于优先级的解析器,它只会在语义级别被捕获。在 C 中,碰巧任何不是一元表达式的表达式都不能是左值的。因此,这些语义上注定要失败的 LHS 表达式不需要在语法上进行调整。它对整个语言没有影响,优先表不必用于预测表达式将导致的错误的句法/语义。
list - Haskell 初学者:柯里化/列表关联性
来自Learn You a Haskell:
想想这个列表:
[5]
。这只是5:[]
. 在 的左侧:
,有一个值;在右侧,有一个列表。在这种情况下,它是一个空列表。现在名单怎么样[4,5]
?好吧,这对4:(5:[])
. 查看第一个 :,我们看到它的左侧还有一个元素,右侧还有一个列表 ,(5:[])
。 类似的列表也是如此3:(4:(5:6:[]))
,它可以写成这样或类似3:4:5:6:[]
(因为:
是右关联的)或[3,4,5,6]
.
对于粗体部分,我期待不断增长的列表最终以3:(4:(5:(6:[])))
. 这与我对柯里化、关联性或两者缺乏理解有关。有人能告诉我我的想法的缺陷吗?