Os blocos implicam parênteses. Por exemplo, ao ver os blocos a seguir,
suponha que isso significa -(5 + 2)
, e não -5 + 2
, porque 5
e 2
fazem parte de
um bloco e o -
é parte de outro bloco.
Mas se você colocar parênteses em torno de cada bloco, o código ficará muito menos
legível. Compare (((5) * (2)) + (3))
com 5 * 2 + 3
. Ambas as opções
as expressões são avaliadas como a mesma coisa (13
), mas a segunda é muito mais fácil
para ler.
As regras de precedência de operador do Blockly ajudam você a gerar um código número de parênteses, para facilitar a leitura.
Gerar "correto" saída
Se você não precisa que o código gerado seja legível por humanos, não é necessário se preocupar com a minimização dos parênteses. Envolver todos os blocos é uma boa abordagem, e garante que o código gerado seja sempre avaliado corretamente.
Para garantir a correção, sempre transmita Order.ATOMIC
para chamadas valueToCode
.
sempre retornar Order.NONE
do seu gerador de código de bloco.
Gerar parênteses ideais
Parênteses só precisam ser inseridos se o código gerado estiver incorreto sem para resolvê-los com rapidez. Isso acontece quando a precedência de um operador no bloco externo é mais forte do que a precedência de um operador no bloco interno.
Por exemplo, nos blocos a seguir há um operador de negação unário e um adicionar. A negação unária tem uma precedência mais forte do que a adicionar.
Portanto, se você não adicionar parênteses, -5 + 2
, e -
será avaliado.
antes do +
, que não corresponde aos blocos.
Você pode dizer ao gerador quando inserir parênteses, informando o quão forte de diferentes operadores. Se perceber que o operador externo é mais forte, que o operador interno, ele insere parênteses para proteger o operador interno.
valueToCode
tem na precedência do operador externo, e o retorno
tupla especifica a precedência do operador interno.
Aqui está um exemplo de um bloco que inclui dois operadores:
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];
}
Precedência de valueToCode
Quando você chama valueToCode
para gerar o código de um bloco interno, ele é transmitido
a precedência do operador mais forte agindo no código do
bloco de recursos dependente. Esse é o operador do qual o código do bloco interno precisa ser protegido.
Por exemplo, no bloco a seguir, o operador de negação unário e o
operador de adição atuam no código do bloco interno. Negação unária
é mais forte, então essa é a precedência que você precisa transmitir para valueToCode
.
// The - is the strongest operator acting on the inner code.
const innerCode = generator.valueToCode(block, 'INNER', Order.UNARY_NEGATION);
const code = `-${innerCode} + 2`;
Precedência de retorno
Ao retornar uma precedência do seu gerador de código de bloco, retorne o precedência do operador mais fraco dentro do código do bloco. Esta é a ou operador que precisa de proteção.
Por exemplo, o bloco a seguir contém um operador de negação unário e um adicionar. A adição é mais fraca, então essa é a precedência que você deve do gerador de código de bloco.
const code = `-${innerCode} + 2`;
// The + is the weakest operator in the block.
return [code, Order.ADDITION];
Enumeração do pedido
Cada módulo gerador de linguagem define um tipo enumerado Order
que inclui todos os
as precedências dela.
As precedências mais fortes têm valores de apoio menores, e as precedências mais fracas têm valores de apoio mais altos. Você pode pensar nas precedências fortes como sendo "classificadas mais alto" em força, e as mais fracas como “classificação inferior” como se eles eram lutadores competitivos.
Confira onde você pode encontrar os tipos enumerados Order
para todos os idiomas integrados:
Precedências especiais
A maioria das precedências Os tipos enumerados Order
correspondem às precedências
definidos pelos respectivos idiomas baseados em texto. Mas há duas características
precedências, Order.ATOMIC
e Order.NONE
.
Order.ATOMIC
é a precedência mais forte. Ele é usado quando:
- É importante garantir que o código esteja sempre entre parênteses,
então você o transmite para
valueToCode
. - Seu bloco não inclui nenhum operador, então você o retorna do seu de código de bloco.
Order.NONE
é a precedência mais fraca. Ele é usado quando:
- É importante garantir que o código esteja sempre entre parênteses, então você a retorna do seu gerador de código de bloco.
- Não há operadores agindo em um bloco interno, então você o passa para
valueToCode
: