Wstawianie nawiasu

Bloki wymagają nawiasów. Na przykład gdy widzisz poniższe bloki, zakładasz, że oznaczają one -(5 + 2), a nie -5 + 2, ponieważ 5 i 2 są częścią 1 bloku, a - jest częścią innego.

bloki reprezentujące -(5 + 2)

Jeśli jednak wszystkie bloki są ujęte w nawiasy, utrudnia to czytelność kodu. Porównaj (((5) * (2)) + (3)) i 5 * 2 + 3. Oba te wyrażenia odnoszą się do tego samego wyrażenia (13), ale drugie jest znacznie łatwiejsze do odczytania.

Reguły pierwszeństwa operatorów Blockly pomagają generować kod z minimalną liczbą nawiasów, aby zapewnić maksymalną czytelność.

Generowanie „prawidłowych” danych wyjściowych

Jeśli nie chcesz, aby wygenerowany kod był czytelny dla człowieka, nie musisz się martwić o zminimalizowanie nawiasów. Dodawanie bloków jest dobrym sposobem, a gwarantuje, że wygenerowany kod będzie zawsze prawidłowo oceniany.

Aby zapewnić poprawność, zawsze przekazuj wywołania Order.ATOMIC do valueToCode i zawsze zwracaj Order.NONE z generatora kodów blokowych.

Wygeneruj optymalne nawiasy

Nawiasy należy wstawić tylko wtedy, gdy wygenerowany kod jest nieprawidłowy. Dzieje się tak, gdy pierwszeństwo operatora w bloku zewnętrznym jest większe niż pierwszeństwo operatora w bloku wewnętrznym.

Na przykład w poniższych blokach występuje jednoargumentowy operator negacji i operator dodawania. Jednoargumentowa negacja ma większy priorytet niż operator addition.

usuń i dodaj

Jeśli więc nie dodasz nawiasów, otrzymasz -5 + 2, a element - będzie sprawdzany przed wartością +, która nie odpowiada blokom.

Możesz poinformować generatora, kiedy wstawić nawiasy, podając mu siłę poszczególnych operatorów. Jeśli operator zewnętrzny jest silniejszy niż operator wewnętrzny, wstawia nawiasy, aby chronić operator wewnętrzny.

valueToCode ma pierwszeństwo przed operatorem zewnętrznym, a kropka zwrotna określa pierwszeństwo operatora wewnętrznego.

Oto przykład bloku zawierającego 2 operatory:

Blok z jednoargumentowym operatorem negacji, 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];
}

Pierwszeństwo valueToCode

Gdy wywołujesz valueToCode w celu wygenerowania kodu bloku wewnętrznego, przekazujesz go jako priorytet najsilniejszego operatora działającego na kodzie bloku wewnętrznego. Jest to operator, przed którym musisz chronić kod bloku wewnętrznego.

Na przykład w poniższych blokach zarówno jednoargumentowy operator negacji, jak i operator dodawania działają na kod bloku wewnętrznego. Jednoargumentowa negacja jest silniejsza, dlatego jest w tym przypadku pierwszeństwo przed parametrem valueToCode.

Blok z jednoargumentowym operatorem negacji, 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`;

Pierwszeństwo zwrotów

Gdy zwracasz pierwszeństwo z generatora kodów blokowych, zwracaj pierwszeństwo najsłabszego operatora w kodzie bloku. To operator potrzebuje ochrony.

Na przykład poniższy blok zawiera zarówno jednoargumentowy operator negacji, jak i operator dodawania. Dodanie jest słabsze, więc to jest pierwszeństwo z generatora kodów blokowych.

Blok z jednoargumentowym operatorem negacji i operatorem dodawania, bez blokady podrzędnej

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

Wyliczenie zamówienia

Każdy moduł generatora języków definiuje wyliczenie Order, które zawiera wszystkie pierwszeństwo dla danego języka.

Silniejsze pierwszeństwo mają niższe wartości wsteczne, a słabsze – wyższe. Słabe pierwszeństwo to np. wyższe miejsce w rankingu, a słabsze – niższe w rankingu, tak jakby rywalizowali ze sobą.

Oto gdzie znajdziesz wyliczenia Order dla wszystkich wbudowanych języków:

Specjalne pierwszeństwo

Większość pierwszeństwa w wyliczeniach Order w generatorach pasuje do pierwszeństwa zdefiniowanych przez odpowiednie języki tekstowe. Są jednak 2 szczególne pierwszeństwo: Order.ATOMIC i Order.NONE.

Order.ATOMIC ma najsilniejszy pierwszeństwo. Jest on używany, gdy:

Order.NONE to najsłabszy pierwszeństwo. Jest on używany, gdy:

  • Chcesz, aby kod był zawsze umieszczony w nawiasach, tak aby zwracany był z generatora kodów blokowych.
  • Żaden operator nie działa na wewnętrznym bloku, więc przekazujesz go do funkcji valueToCode.