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