ブロックにはかっこが必要です。たとえば、次のブロックがある場合、5
と 2
が 1 つのブロックの一部で、-
が別のブロックの一部であるため、-5 + 2
ではなく -(5 + 2)
であると考えられます。
しかし、すべてのブロックをかっこで囲むと、コードが読みにくくなります。(((5) * (2)) + (3))
と 5 * 2 + 3
を比較します。どちらの式も同じ結果(13
)として評価されますが、2 つ目の式の方が読みやすくなります。
Blockly の演算子優先順位ルールを使用すると、最小限の括弧でコードを生成できるため、読みやすさが向上します。
「正しい」出力を生成する
生成されたコードを人が読める形式にする必要がない場合は、かっこを最小化する必要はありません。すべてのブロックをラップすることは適切なアプローチであり、これにより、生成されたコードが常に正しく評価されるようになります。
正確性を確保するために、常に Order.ATOMIC
を valueToCode
呼び出しに渡して、ブロックコード生成ツールから常に Order.NONE
を返します。
最適な括弧の生成
括弧は、生成されたコードが正しくない場合にのみ挿入する必要があります。これは、外側のブロックの演算子の優先順位が内側のブロックの演算子の優先順位よりも高い場合に発生します。
たとえば、次のブロックには、単項否定演算子と加算演算子があります。単項否定は、加算演算子よりも優先順位が高くなります。
したがって、かっこを追加しないと、-5 + 2
になり、-
は +
の前に評価され、これはブロックと一致しません。
ジェネレータにかっこを挿入するタイミングを指示するには、さまざまな演算子の強さを指定します。外側演算子が内側演算子よりも強力であると判断すると、括弧を挿入して内側演算子を保護します。
valueToCode
は外部演算子より優先され、戻りタプルは内部演算子の優先順位を指定します。
2 つの演算子を含むブロックの例を次に示します。
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.ATOMIC
と Order.NONE
という 2 つの特別な優先順位があります。
Order.ATOMIC
が最も強い優先度です。次の場合に使用されます。
- コードが常にかっこで囲まれるようにするため、
valueToCode
に渡します。 - ブロックに演算子が含まれていないため、ブロックコード生成ツールから返します。
Order.NONE
が最も低い優先度です。次の場合に使用されます。
- コードが常にかっこで囲まれるようにするため、ブロックコード ジェネレータから返すようにします。
- 内側のブロックを操作する演算子はないため、
valueToCode
に渡します。