Вставка скобок

Блоки подразумевают круглые скобки. Например, когда вы видите следующие блоки, вы предполагаете, что это означает -(5 + 2) а не -5 + 2 , потому что 5 и 2 являются частью одного блока, а - является частью другого блока.

блоки, представляющие -(5 + 2)

Но если вы заключаете каждый блок в круглые скобки, код становится гораздо менее читабельным. Сравните (((5) * (2)) + (3)) с 5 * 2 + 3 . Оба этих выражения дают одно и то же ( 13 ), но второе гораздо легче читать.

Правила приоритета операторов Blockly помогают генерировать код с минимальным количеством скобок для максимальной читаемости.

Генерировать «правильный» вывод

Если вам не нужно, чтобы сгенерированный код был удобочитаемым человеком, не нужно беспокоиться о минимизации круглых скобок. Обертывание каждого блока — хороший подход, который гарантирует, что сгенерированный код всегда будет оцениваться правильно.

Чтобы обеспечить корректность, всегда передавайте Order.ATOMIC в вызовы valueToCode и всегда возвращайте Order.NONE из генератора блочного кода.

Сгенерируйте оптимальные круглые скобки

Круглые скобки необходимо вставлять только в том случае, если без них сгенерированный код некорректен. Это происходит, когда приоритет оператора во внешнем блоке выше, чем приоритет оператора во внутреннем блоке.

Например, в следующих блоках есть унарный оператор отрицания и оператор сложения. Унарное отрицание имеет более сильный приоритет, чем оператор сложения.

отрицание и сложение

Таким образом, если вы не добавите круглые скобки, вы получите -5 + 2 , а - оценивается перед + , что не соответствует блокам.

Вы можете сообщить генератору, когда вставлять круглые скобки, сообщив ему, насколько сильны ваши различные операторы. Если он видит, что внешний оператор сильнее внутреннего, он вставляет круглые скобки, чтобы защитить внутренний оператор.

valueToCode принимает приоритет внешнего оператора, а возвращаемый кортеж определяет приоритет внутреннего оператора.

Вот пример блока, включающего два оператора:

Блок с унарным оператором отрицания, оператором сложения и дочерним блоком.

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];
}

приоритет значенияToCode

Когда вы вызываете 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 .

Order.ATOMIC имеет самый сильный приоритет. Его используют, когда:

Order.NONE — самый слабый приоритет. Его используют, когда: