Bloki oznaczają nawiasy. Gdy na przykład widzisz te bloki, zakładasz, że oznacza to -(5 + 2)
, a nie -5 + 2
, ponieważ 5
i 2
należą do jednego bloku, a -
do innego.
Jeśli jednak użyjesz nawiasów wokół każdego bloku, kod będzie znacznie mniej czytelny. Porównaj (((5) * (2)) + (3))
z 5 * 2 + 3
. Oba te wyrażenia dają ten sam wynik (13
), ale drugie jest znacznie łatwiejsze do odczytania.
Reguły priorytetów operatorów w Blockly pomagają generować kod z minimalną liczbą nawiasów, co zwiększa czytelność.
generowanie „prawidłowego” wyjścia.
Jeśli nie zależy Ci na tym, aby wygenerowany kod był czytelny dla człowieka, nie musisz się martwić minimalizowaniem nawiasów. Owijanie każdego bloku jest dobrym podejściem, ponieważ zapewnia, że wygenerowany kod jest zawsze prawidłowo oceniany.
Aby mieć pewność, że wszystko jest prawidłowe, zawsze przekazuj parametr Order.ATOMIC
do wywołań valueToCode
i zawsze zwracaj parametr Order.NONE
z generatora kodu blokowego.
generowanie optymalnych nawiasów,
Wstaw nawiasy tylko wtedy, gdy wygenerowany kod jest nieprawidłowy. Dzieje się tak, gdy pierwszeństwo operatora w bloku zewnętrznym jest silniejsze niż pierwszeństwo operatora w bloku wewnętrznym.
Na przykład w tych blokach występuje operator negacji jednoargumentowej i operator dodawania. Negacja jednoelementowa ma silniejsze pierwszeństwo niż operator dodawania.
Jeśli nie dodasz nawiasów, otrzymasz -5 + 2
, a wynik -
zostanie obliczony przed +
, co nie pasuje do bloków.
Możesz określić, kiedy generator ma wstawiać nawiasy, podając mu siłę działania różnych operatorów. Jeśli widzi, że operator zewnętrzny jest silniejszy niż operator wewnętrzny, wstawia nawiasy, aby chronić operator wewnętrzny.
valueToCode
przyjmuje pierwszeństwo operatora zewnętrznego, a zwracana tablica określa pierwszeństwo operatora wewnętrznego.
Oto przykład bloku zawierającego 2 operatory:
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];
}
wartość do kodu pierwszeństwa
Gdy wywołujesz funkcję valueToCode
, aby wygenerować kod bloku wewnętrznego, przekazujesz jej priorytet najsilniejszego operatora działającego na kod bloku wewnętrznego. To operator, przed którym należy chronić kod bloku wewnętrznego.
Na przykład w tych blokach zarówno operator negacji jednoargumentowej, jak i operator dodawania działają na kod bloku wewnętrznego. Negacja jednoargumentowa jest silniejsza, więc to ona powinna mieć pierwszeństwo przed valueToCode
.
// The - is the strongest operator acting on the inner code.
const innerCode = generator.valueToCode(block, 'INNER', Order.UNARY_NEGATION);
const code = `-${innerCode} + 2`;
Zwrot priorytetu
Gdy zwracasz priorytet z generatora kodu bloku, zwracaj priorytet najsłabszego operatora w kodzie bloku. To operator, który wymaga ochrony.
Na przykład ten blok zawiera operator negacji jednoargumentowej i operator dodawania. Dodatek jest słabszy, więc powinien mieć niższą ważność w porównaniu z blokiem z generatora kodu.
const code = `-${innerCode} + 2`;
// The + is the weakest operator in the block.
return [code, Order.ADDITION];
Typ wyliczenia kolejności
Każdy moduł generatora języka definiuje typ enumeracji Order
, który zawiera wszystkie hierarchie dla danego języka.
Większe wartości mają mniejsze wartości podrzędne, a mniejsze wartości mają większe wartości podrzędne. Silne reguły mają wyższą rangę, a słabsze – niższą. Można je porównać do wojowników walczących o przetrwanie.
Oto lista typów Order
dla wszystkich wbudowanych języków:
- Kolejność rzutek
- Kolejność wykonywania kodu JavaScript
- Zamówienie Lua
- Zamów PHP
- Kolejność w Pythonie
Specjalne priorytety
Większość priorytetów w generowanych wartościach wyliczonych Order
odpowiada priorytetom zdefiniowanym przez odpowiednie języki tekstowe. Istnieją jednak 2 szczególne poziomy pierwszeństwa: Order.ATOMIC
i Order.NONE
.
Order.ATOMIC
ma najwyższy priorytet. Jest używana, gdy:
- Chcesz zadbać o to, aby kod był zawsze w nawiasach, więc przekazujesz go do
valueToCode
. - Twój blok nie zawiera żadnych operatorów, więc zwracasz go z generatora kodu bloku.
Order.NONE
ma najsłabszą ważność. Jest używana, gdy:
- Chcesz zadbać o to, aby kod był zawsze ujęty w nawiasy, więc zwracasz go z generatora kodu blokowego.
- Nie ma operatorów działających na bloku wewnętrznym, więc przekazujesz go do
valueToCode
.