This project has moved and is read-only. For the latest updates, please go here.

How to build the AST ?

Nov 3, 2012 at 11:45 AM

Hi, how I can to build the AST for my grammar? Where I can download any examples?


Nov 3, 2012 at 10:35 PM

look and expression evaluator and miniPython

Nov 4, 2012 at 4:56 AM

Roman, thanks for your reply. 

For my first example all NonTerminal nodes I defined as typeof(NotSupportedNode). Also my grammar used RegexBasedTerminals.

When I set LanguageFlags.CreateAst flag in my grammar I have a NullReferenceException after load grammar into Grammar Explorer.

As I can see in pop-out window the NullReferenceException occurs in the \Irony\Ast\AstBuilder.cs line 97, 86 and 38.

Can you help me? Thanks

Nov 4, 2012 at 1:06 PM

The default AST nodes don't set up correctly without some work, so you will have to define a Node-Type for all NonTerminals that are not Transient.

I may get my Music Parser uploaded today, in which case you can check it out for some ideas.


Nov 6, 2012 at 7:53 AM
Edited Nov 6, 2012 at 8:14 AM

Thanks Pieter

To experiment, I created a mini-grammar and trying to build AST.

    [Language("Test Grammar")]
    public class TestGrammar : Grammar

        public TestGrammar()
            : base(false)
            this.GrammarComments = @"Test Grammar";

            var Id = new RegexBasedTerminal("Identifier", @"[a-zA-Z](_?[a-zA-Z0-9]?)*");
            var IntNum = new RegexBasedTerminal("IntNum", @"[0-9](_?[0-9])*");
            var RealNum = new RegexBasedTerminal("RealNum", @"[0-9](_?[0-9])*\.[0-9](_?[0-9])*([Ee][\+-]?[0-9](_?[0-9])*)?");

            NonTerminal Numeric = new NonTerminal("Numeric");
            NonTerminal Variable = new NonTerminal("Variable");
            NonTerminal Expr = new NonTerminal("Expr");
            NonTerminal Operand = new NonTerminal("Operand");
            NonTerminal OpUnary = new NonTerminal("OpUnary", typeof(UnaryOperationNode));
            NonTerminal OpMult = new NonTerminal("OpMult");
            NonTerminal OpAdd = new NonTerminal("OpAdd");
            NonTerminal Stmt = new NonTerminal("Stmt", typeof(AssignmentNode));
            NonTerminal StmtList = new NonTerminal("StmtList", typeof(StatementListNode));

            Numeric.Rule = IntNum
                           | RealNum;
            Variable.Rule = Id;
            Expr.Rule = OpAdd;
            OpAdd.Rule = OpMult
                         | OpAdd + "+" + OpMult
                         | OpAdd + "-" + OpMult;
            OpMult.Rule = OpUnary
                          | OpMult + "*" + OpUnary
                          | OpMult + "/" + OpUnary;
            OpUnary.Rule = Operand
                           | "+" + OpUnary
                           | "-" + OpUnary;
            Operand.Rule = "(" + Expr + ")"
                           | Numeric
                           | Variable;
            StmtList.Rule = Stmt + ";"
                            | Stmt + ";" + StmtList;
            Stmt.Rule = Variable + ":=" + Expr;

            this.Root = StmtList;
            this.LanguageFlags = LanguageFlags.CreateAst;

But AST doesn't build. I get several Null Exceptions. What I doing wrong?


Nov 6, 2012 at 5:18 PM

man, your grammar (in regard to AST node construction) does not make any sense. Automatic AST construction is optional in Irony grammar, but when you use it, your grammar rules must be carefully aligned with what each AST node type expects as arguments (child nodes).

Look at definition (Init method specifically) of each node you are going to use, then craft the corresponding grammar rule so that child elements (components in grammar rule) exactly match what the node expects. There's additional property AstConfig on the BnfTerm (Terminal or NonTerminal) that allows some rearrangement of nodes (PartsMap field) before they are used in construction of parent ASt node - use it for some flexibility. Otherwise, if your language semantics do not match Irony's AST node defaults, use node creator methods - delegate properties on non-terminals - to construct AST nodes.


Nov 6, 2012 at 9:25 PM

Also, I have finally uploaded an example to help with AST construction:

Comments and suggestions welcome.


Nov 7, 2012 at 6:13 AM

Pieter, thanks for your detailed example. A lot of my questions are resolved.

Roman, I don't understand your sarcasm :) For my first using of your Irony engine I followed the path of least resistance and tried to use already existed classes. Because Irony doesn't have any manual.

Nov 7, 2012 at 6:11 PM

kep4uk - my apologies if it sounded sarcastic, did not mean any, just tried to give direct instructions - do this and this, and maybe "the tone" in writing came out to be too informal.

Nov 8, 2012 at 4:02 PM

Hallo Pieter,

some words please how to implement your extension.

It is not a project ? Add Dlls to samples ? What samples ?






Nov 8, 2012 at 4:57 PM

The current Documentation tab follows below. If you have specific questions on that, we should move the dscussion over to here:

Getting Started

  1. Download Irony and PGIrony;
  2. Add Irony.dll and PGIrony.dll to your project as references;
  3. Add Required Namespace References to Grammar File;
  4. Define Subclass stubs for Grammar class and AST support classes;
  5. Define Terminals;
  6. Define NonTerminals;
  7. Define Rules;
  8. Define Subclass stubs for required AstNodes;
  9. Compile and test AstGrammarTest.dll in Irony.GrammarExplorer.;
  10. Expand your stubs for MyAstContext and subclasses of AstNode as required.