Как мне теперь работать с AST в Irony?
У меня есть грамматика, которая отлично работает и анализирует в консоли Irony, но я ничего не получаю в виде дерева AST. Я следовал вместе со статьей на BASIC->Javascript, найденной здесь: http://www.codeproject.com/Articles/25069/JSBasic-A-BASIC-to-JavaScript-Compiler, но кажется, что материал Ast все перемещены / удалены. Я нашел Irony.Interpreter .dll, в котором есть кое-что из Ast, но, похоже, все это связано с примером реализации Expression.
Что мне здесь не хватает? Я хочу пройтись по своему дереву и сгенерировать исходный код, и я не уверен, с чего начать.
Я видел некоторые упоминания об использовании шаблона посетителя, с которым я в порядке, но я не знаю, как реализовать его и запустить так, как нравится Иронии.
2 ответа
Познакомьтесь с метко названным проектом Sarcasm для эталонной реализации грамматики, парсера и AST, построенных на иронии. Я нашел эту запись в блоге автора, чтобы помочь в создании AST.
Ниже приведено общее руководство по настройке и эксплуатации AST.
- Определите свою грамматику ( пример)
- Создать абстрактный базовый класс (
MyBaseNode
) исходя изAstNode
( пример). Скопируйте / Вставьте методы из примера Для каждого терминала и нетерминала создайте новый класс, полученный из
MyBaseNode
а также- Override
Accept
метод ( пример):
public override void Accept(IMyNodeVisitor visitor) { visitor.Visit(this); }
- Override
Init
(в основном на терминалах) илиInitChildren
(нетерминалы) в зависимости от обстоятельств. Вот где происходит волшебство АСТ.
- Override
Добавить интерфейс
IMyNodeVisitor
и добавитьVisit
Метод для каждого класса, определенного на предыдущем шаге ( пример):void Visit(MyDerivedNode1 node);
Установить
ASTNodeType
для каждого из ваших терминалов и нетерминалов в вашей грамматике с шага 1.В грамматике включите создание AST: ( пример)
LanguageFlags = LanguageFlags.CreateAst;
В Иронии разбор делается в 2 этапа. Сначала он создает дерево разбора, а затем создает ваше дерево AST.
Вы видите только первый шаг. Чтобы Ирония создала AST, вы можете:
Расскажите, как сопоставить ваши нетерминалы с узлами AST:
Например, глядя на образец грамматики Иронии ExpressionEvaluatorGrammar, мы видим:
var BinExpr = new NonTerminal("BinExpr", typeof(BinaryOperationNode));`
Здесь мы говорим Irony, чтобы сопоставить нетерминал BinExpr с BinaryOperationNode, который является нашим узлом AST.
Сделайте так, чтобы он генерировал AST при разборе:
Когда вы устанавливаете этот флаг, дерево AST будет генерироваться при разборе.
this.LanguageFlags = LanguageFlags.CreateAst;
Корень вашего дерева AST будет:
parseTree.Root.AstNode
Я нашел этот источник отличной отправной точкой.