括号插入

方块隐含括号。例如,当您看到以下代码块时,会假定它表示 -(5 + 2) 而非 -5 + 2,因为 52 属于一个块,- 属于另一个块。

代表 -(5 + 2) 的块

但是,如果为每个块添加圆括号,则代码的可读性会大大降低。将 (((5) * (2)) + (3))5 * 2 + 3 进行比较。这两个表达式的计算结果相同 (13),但第二个表达式更易于阅读。

Blockly 的运算符优先级规则可帮助您生成括号最少的代码,以提高可读性。

生成“正确”的输出

如果您不需要生成的代码直观易懂,则无需担心将括号最小化。封装每个代码块是一种不错的方法,并且可确保始终对生成的代码进行正确评估。

为确保正确性,请始终将 Order.ATOMIC 传递给 valueToCode 调用,并始终从块代码生成器返回 Order.NONE

生成最佳括号

只有当生成的代码不正确时,才需要插入圆括号。当外部块中运算符的优先级高于内部块中的运算符优先级时,就会发生这种情况。

例如,以下代码块中有一个一元否定运算符和一个加法运算符。一元非运算的优先级高于加法运算符。

否定和加法

因此,如果您不添加圆括号,将得到 -5 + 2,并且 - 会在 + 之前求值,而这与块不匹配。

您可以告知生成器何时插入圆括号,只需告诉生成器不同运算符的强弱程度即可。如果它发现外部运算符比内部运算符强,则会插入圆括号以保护内部运算符。

valueToCode 采用外部运算符的优先级,返回元组指定内部运算符的优先级。

以下是包含两个运算符的块示例:

包含一元否定运算符、加法运算符和子块的块。

import {javascriptGenerator, Order} from 'blockly/javascript';

javascriptGenerator.forBlock['negate_plus_two'] = function(block, generator) {
  // valueToCode takes in the precedence of the outer operator.
  const innerCode = generator.valueToCode(block, 'INNER', Order.UNARY_NEGATION);
  const code = `-${innerCode} + 2`;
  // The return tuple specifies the precedence of the inner operator.
  return [code, Order.ADDITION];
}

valueToCode 优先级

当您调用 valueToCode 以生成内部块的代码时,您向其传递对内部块代码执行操作的最强运算符的优先级。这是需要保护内部代码块的代码的运算符。

例如,在下面的块中,一元否定运算符和加法运算符都对内部块的代码执行操作。一元否定更强,因此您应该传递给 valueToCode 的优先级。

包含一元否定运算符、加法运算符和子块的块。

// The - is the strongest operator acting on the inner code.
const innerCode = generator.valueToCode(block, 'INNER', Order.UNARY_NEGATION);
const code = `-${innerCode} + 2`;

返回优先级

从块代码生成器返回优先级时,返回块代码中最弱运算符的优先级。这是需要保护的运算符。

例如,以下代码块同时包含一元否定运算符和加法运算符。加法较弱,因此您应该从块代码生成器返回优先级。

包含一元否定运算符和加法运算符且没有子块的块

const code = `-${innerCode} + 2`;
// The + is the weakest operator in the block.
return [code, Order.ADDITION];

订单枚举

每个语言生成器模块都会定义一个 Order 枚举,其中包含相应语言的所有优先级。

优先级较高的优先级具有较低的后备值,优先级较低的优先级具有较高的后备值。您可以将高优先级视为力量“较高”,将较低优先级视为“较低”优先级,就像它们是竞技斗士一样。

您可以在以下位置找到所有内置语言的 Order 枚举:

特殊优先级

生成器的 Order 枚举中的大多数优先级都与各自基于文本的语言所定义的优先级相匹配。但有两个特殊优先级:Order.ATOMICOrder.NONE

Order.ATOMIC 是最高优先级。用于以下情况:

  • 您需要确保代码始终带有英文括号,因此将其传递给 valueToCode
  • 您的代码块不包含任何运算符,因此请从代码块代码生成器中返回该代码块。

Order.NONE 是最低优先级。用于以下情况: