Как я могу преобразовать конкретные значения синтаксиса в другие виды значений?

Учитывая какое-то конкретное значение синтаксиса, как я могу сопоставить его с другим типом значения (в этом случае int)?

// Syntax
start syntax MyTree = \node: "(" MyTree left "," MyTree right ")"
                    | leaf: Leaf leaf
                    ;

layout MyLayout = [\ \t\n\r]*;

lexical Leaf = [0-9]+;

Это не работает, к сожалению:

public Tree increment() {
    MyTree tree = (MyTree)`(3, (1, 10))`;

    return visit(tree) {
      case l:(Leaf)`3` => l + 1  
    };
}

Или это единственный способ implode в ADT, где я указал типы?

1 ответ

Решение

Ваш вопрос имеет разные возможные ответы:

  1. с помощью implode Вы можете преобразовать дерево разбора в абстрактное дерево. Если ожидают конструкторы целевого абстрактного языка intзатем лексические деревья, которые совпадают [0-9]+ будет автоматически преобразован. Например, синтаксическое дерево для syntax Exp = intValue: IntValue; может быть преобразован в конструктор data Exp = intValue(int i); и это будет на самом деле построить i,
  2. в общем, для преобразования одного типа значений в другой в Rascal вы пишете (взаимно) рекурсивные функции, как в int eval (MyTree t) а также int (Leaf l),
  3. если вы хотите на самом деле увеличить синтаксическое представление значения Leaf, вы должны преобразовать обратно (синтаксический анализ или через конкретный шаблон) из результирующего int назад к Leaf,

Пример:

import String;
MyTree increment() {
    MyTree tree = (MyTree)`(3, (1, 10))`;

    return visit(tree) {
      case Leaf l => [Leaf] "<toInt("<l>") + 1>";  
    };
}

Сначала лексический преобразуется в строку "<l>", это затем анализируется как int с помощью toInt() и мы добавляем 1, используя + 1 а затем сопоставить int назад к строке "< ... >"после чего мы можем назвать Leaf использование парсера [Leaf],

Другие вопросы по тегам