How do I work with the AST in Irony now?
Asked Answered
R

2

8

I have a grammar that works and parses in the Irony console just fine, but I don't get anything in the AST treeview. I was following along with the BASIC->Javascript article found here: http://www.codeproject.com/Articles/25069/JSBasic-A-BASIC-to-JavaScript-Compiler, but it seems that the Ast stuff has all been moved/removed. I found the Irony.Interpreter .dll, which has some Ast stuff in it, but it seems all tied up in the Expression sample implementation.

What am I missing here? I want to walk my tree and generate source code, and I'm not sure where to start.

I've seen some mention of using the visitor pattern, which I'm fine with, but I don't know how to implement it and run it in a way that Irony likes.

Ruthy answered 21/2, 2013 at 21:47 Comment(1)
I just switched over to ANTLR, so I guess this is all moot now. So little help, it hurts. Oh well, thanks for any that took the time to look!Ruthy
U
7

Check out the aptly named Sarcasm project for a reference implementation of a grammar, parser, and AST built on Irony. I found this blog entry by the author to be helpful in building the AST.

The following is a general purpose guide to getting the AST up and running.

  1. Define your grammar (example)
  2. Create an abstract base class (MyBaseNode) deriving from AstNode (example). Copy/Paste the methods from the example
  3. For each terminal and non-terminal create a new class derived from MyBaseNode and

    1. Override Accept method (example):

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

    1. Override Init (mostly on terminals) or InitChildren (non-terminals) as appropriate. This is where the AST magic happens.
  4. Add an interface IMyNodeVisitor and add a Visit method for each class defined in the previous step (example):

    void Visit(MyDerivedNode1 node);

  5. Set the ASTNodeType for each of your terminals and non-terminals in your grammar from step 1.

    1. For terminals - (example)

      MyTerminal1.AstConfig.NodeType = typeof(MyDerivedNode1);

    2. For non-terminals - (example)

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

  6. In the grammar enable AST creation: (example)

    LanguageFlags = LanguageFlags.CreateAst;

Unreflecting answered 22/9, 2015 at 5:47 Comment(2)
Holy smokes. Sarcasm isn't just a reference implementation, it is Sarcasm, an EBNF-like DSL that generates Irony! This is like inception mixed with ouroboros.Serendipity
The link to the Sarcasm project is dead. (Or is that some sort of intentional "who's on first" joke that I didn't get?)Edgebone
P
4

In Irony parsing is done in 2 phases. First it creates a parse tree and then it creates your AST tree.

You are only seeing the first step. In order for Irony to create the AST you can:

  1. Tell it how to to map your NonTerminals to AST nodes:

    E.g. looking at the Irony sample grammer ExpressionEvaluatorGrammar we see:

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

    Here the we are telling Irony to map the BinExpr NonTerminal to a BinaryOperationNode which is our AST node.

  2. Make it generate the AST when parsing:

    When you set this flag the AST tree will be generated when you parse.

    this.LanguageFlags = LanguageFlags.CreateAst;
    

The root of your AST tree will then be:

parseTree.Root.AstNode

I found this source a great starting point.

Paolo answered 18/10, 2013 at 10:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.