Dodawanie nawiasów

Bloki oznaczają nawiasy. Gdy na przykład widzisz te bloki, zakładasz, że oznacza to -(5 + 2), a nie -5 + 2, ponieważ 52 należą do jednego bloku, a - do innego.

bloki reprezentujące -(5 + 2)

Jeśli jednak użyjesz nawiasów wokół każdego bloku, kod będzie znacznie mniej czytelny. Porównaj (((5) * (2)) + (3))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.

negate-and-addition

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:

Blok z operatorem negacji jednoargumentowej, operatorem dodawania i blokiem podrzędnym.

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.

Blok z operatorem negacji jednoargumentowej, operatorem dodawania i blokiem podrzędnym.

// 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.

Blok z operatorem negacji jednoargumentowej i operatorem dodawania bez bloku podrzędnego

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:

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.ATOMICOrder.NONE.

Order.ATOMIC ma najwyższy priorytet. Jest używana, gdy:

Order.NONE ma najsłabszą ważność. Jest używana, gdy: