Как мне теперь работать с 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.

  1. Определите свою грамматику ( пример)
  2. Создать абстрактный базовый класс (MyBaseNode) исходя из AstNode ( пример). Скопируйте / Вставьте методы из примера
  3. Для каждого терминала и нетерминала создайте новый класс, полученный из MyBaseNode а также

    1. Override Accept метод ( пример):

    public override void Accept(IMyNodeVisitor visitor) { visitor.Visit(this); }

    1. Override Init (в основном на терминалах) или InitChildren (нетерминалы) в зависимости от обстоятельств. Вот где происходит волшебство АСТ.
  4. Добавить интерфейс IMyNodeVisitor и добавить Visit Метод для каждого класса, определенного на предыдущем шаге ( пример):

    void Visit(MyDerivedNode1 node);

  5. Установить ASTNodeType для каждого из ваших терминалов и нетерминалов в вашей грамматике с шага 1.

    1. Для терминалов - ( пример)

      MyTerminal1.AstConfig.NodeType = typeof(MyDerivedNode1);

    2. Для нетерминалов - ( пример)

      var MyNonTerminal2 = new NonTerminal("MyNonTerminal2", typeof(MyDerivedNode2));

  6. В грамматике включите создание AST: ( пример)

    LanguageFlags = LanguageFlags.CreateAst;

В Иронии разбор делается в 2 этапа. Сначала он создает дерево разбора, а затем создает ваше дерево AST.

Вы видите только первый шаг. Чтобы Ирония создала AST, вы можете:

  1. Расскажите, как сопоставить ваши нетерминалы с узлами AST:

    Например, глядя на образец грамматики Иронии ExpressionEvaluatorGrammar, мы видим:

    var BinExpr = new NonTerminal("BinExpr", typeof(BinaryOperationNode));`    
    

    Здесь мы говорим Irony, чтобы сопоставить нетерминал BinExpr с BinaryOperationNode, который является нашим узлом AST.

  2. Сделайте так, чтобы он генерировал AST при разборе:

    Когда вы устанавливаете этот флаг, дерево AST будет генерироваться при разборе.

    this.LanguageFlags = LanguageFlags.CreateAst;
    

Корень вашего дерева AST будет:

parseTree.Root.AstNode

Я нашел этот источник отличной отправной точкой.

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