괄호 삽입

블록은 괄호를 의미합니다. 예를 들어 다음 블록은 52가 한 블록에 속하고 -가 다른 블록의 일부이므로 -5 + 2가 아니라 -(5 + 2)를 의미한다고 가정합니다.

-(5 + 2)를 나타내는 블록

하지만 모든 블록을 괄호로 묶으면 코드의 가독성이 훨씬 낮아집니다. (((5) * (2)) + (3))5 * 2 + 3를 비교합니다. 두 표현식은 모두 동일한 항목 (13)으로 평가되지만 두 번째 표현식이 훨씬 읽기 쉽습니다.

Blockly 연산자 우선순위 규칙을 사용하면 가독성을 최대화하기 위해 최소 괄호 수로 코드를 생성할 수 있습니다.

'올바른' 출력 생성

생성된 코드를 사람이 읽을 수 있게 할 필요가 없다면 괄호를 최소화하지 않아도 됩니다. 모든 블록을 래핑하는 것은 좋은 접근 방식이며 이렇게 하면 생성된 코드가 항상 올바르게 평가됩니다.

정확성을 보장하려면 항상 Order.ATOMICvalueToCode 호출에 전달하고 블록 코드 생성기에서 항상 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];
}

valueToCode 우선순위

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

순서 enum

모든 언어 생성기 모듈은 해당 언어의 모든 우선순위를 포함하는 Order enum을 정의합니다.

높은 우선순위일수록 지원 값이 낮고 우선순위가 낮을수록 지원 값이 높습니다. 강력한 우선순위는 강도가 '높은 순위'로, 약한 우선순위는 경쟁이 치열한 경쟁사인 것처럼 '순위가 낮은' 것으로 생각할 수 있습니다.

다음은 모든 기본 제공 언어의 Order enum을 찾을 수 있는 위치입니다.

특별 우선순위

생성기의 Order enum에 있는 대부분의 우선순위는 각 텍스트 기반 언어로 정의된 우선순위와 일치합니다. 하지만 Order.ATOMICOrder.NONE라는 두 가지 특수한 우선순위가 있습니다.

Order.ATOMIC가 가장 강력한 우선순위입니다. 다음과 같은 경우에 사용됩니다.

  • 코드를 항상 괄호로 묶어야 하므로 valueToCode에 전달합니다.
  • 블록에 연산자가 포함되어 있지 않으므로 블록 코드 생성기에서 반환합니다.

Order.NONE가 가장 약한 우선순위입니다. 다음과 같은 경우에 사용됩니다.

  • 코드를 항상 괄호로 묶어 블록 코드 생성기에서 반환하도록 하는 것이 좋습니다.
  • 내부 블록에서 작동하는 연산자가 없으므로 valueToCode에 전달합니다.