2016-06-28 5 views
1

Учитывая некоторое конкретное значение синтаксиса, как я могу сопоставить его с другим типом значения (в данном случае 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, где я указал типы?

ответ

2

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

  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. Если вы хотите на самом деле увеличить синтаксическое представление значения листа, вам нужно преобразовать обратно (разбор или конкретный узор) из полученного 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].