4

I'm getting started with Irony (version Irony_2012_03_15) but I pretty quickly got stuck when trying to generate an AST. Below is a completely strpped language that throws the exception:

[Language("myLang", "0.1", "Bla Bla")]
    public class MyLang: Grammar {
        public NModel()
            : base(false) {

            var number = TerminalFactory.CreateCSharpNumber("number");
            var binExpr = new NonTerminal("binExpr", typeof(BinaryOperationNode));
            var binOp = new NonTerminal("BinOp");

            binExpr.Rule = number + binOp + number;
            binOp.Rule = ToTerm("+");
            RegisterOperators(1, "+");
            //MarkTransient(binOp);
            this.Root = binExpr;
            this.LanguageFlags = Parsing.LanguageFlags.CreateAst; // if I uncomment this line it throws the error
        }
    } 

As soon as I uncomment the last line it throws a NullReferenceException in the grammar explorer or when i want to parse a test. The error is on AstBuilder.cs line 96:

  parseNode.AstNode = config.DefaultNodeCreator();

DefaultNodeCreator is a delegate that has not been set.

I've tried setting things with MarkTransient etc but no dice.

Can someone help me afloat here? I'm proably missing something obvious. Looked for AST tutorials all over the webs but I can't seem to find an explanation on how that works.

Thanks in advance,

Gert-Jan

gjvdkamp
  • 9,929
  • 3
  • 38
  • 46

3 Answers3

2

Once you set the LanguageFlags.CreateAst flag on the grammar, you must provide additional information about how to create the AST.

You're supposed to be able to set AstContext.Default*Type for the whole language, but that is currently bugged.

  • Set TermFlags.NoAstNode. Irony will ignore this node and its children.

  • Set AstConfig.NodeCreator. This is a delegate that can do the right thing.

  • Set AstConfig.NodeType to the type of the AstNode. This type should be accessible, implement IAstInit, and have a public, no-parameters constructor. Accessible in this case means either public or internal with the InternalsVisibleTo attribute.

Jay Bazuzi
  • 45,157
  • 15
  • 111
  • 168
  • Hi Jay, thanks for your answer. Actually stopped using Irony as parser because of the available support. Pity, it looks very nice, too bad it's not catching on to what it deserves. Hope you got a necromancer badge out of this one! – gjvdkamp Aug 23 '12 at 11:03
  • @gjvdkamp What parser are you using now? I have the same problem and I'm also not satisfied with the documentation or web tutorials support for this project. It may be good, but it entirely fails to communicate it, making it useless. – ygoe Jun 17 '13 at 13:31
  • The last grammar that actually flew well was with ANTLR on .Net, also much because of ANTLRWorks. I've been out of this topic for years now so a lot may have happened in the mean time. The new versions of both look pretty promising... On F# you might want to look at fParsec or Active Patterns. – gjvdkamp Jun 20 '13 at 21:15
2

To be honest, I was facing the same problem and did not understand Jay Bazuzi answer, though it looks like valid one(maybe it's outdated).

If there's anyone like me;

I just inherited my Grammar from Irony.Interpreter.InterpretedLanguageGrammar class, and it works. Also, anyone trying to get AST working, make sure your nodes are "public" :- )

Erti-Chris Eelmaa
  • 25,338
  • 6
  • 61
  • 78
0

On top of Jay's and Erti-Chris's responses, this thread is also useful:

https://irony.codeplex.com/discussions/361018

The creator of Irony points out the relevant configuration code in InterpretedLanguageGrammar.BuildAst.

HTH

Sean Kearon
  • 10,987
  • 13
  • 77
  • 93