How to create AST tree?

Jul 16, 2015 at 2:51 PM
Hi,

I have a simple grammar that works as a parse tree but when I try to build it as an AST tree I get the error:

System.NullReferenceException: Object reference not set to an instance of the object

I have followed the advice to derive from AstNode for all non-terminals.

Below is the source code:
[Language("Calc", "1.0", "Calc 1.0 grammar")]
    public class CalcExpr : Grammar
    {
        public CalcExpr() : base(false)
        {
            LanguageFlags = LanguageFlags.CreateAst;
            
            //Terminals
            var number = new NumberLiteral("Number");
            //number.AstConfig.NodeType = typeof(Number);

            //Non-terminals
            var exprline = new NonTerminal("Statement", typeof(Exprline));
            var expr = new NonTerminal("Expression", typeof(Expr));
            var binexpr = new NonTerminal("BinaryExpression", typeof(BinExpr));
            var oper = new NonTerminal("Operator", typeof(Oper));
            var plus = new NonTerminal("Operator +", typeof(Plus));
            var minus = new NonTerminal("Operator -", typeof(Minus));

            //BNF Rules
            this.Root = exprline;
            exprline.Rule = MakePlusRule(exprline, expr);
            expr.Rule = number | binexpr;
            binexpr.Rule = expr + oper + expr;
            oper.Rule = plus | minus;
            plus.Rule = ToTerm("+");
            minus.Rule = ToTerm("-");

            //Operators
            RegisterOperators(1, "+", "-");

            //Punctuations
            MarkPunctuation("+", "-");
            base.MarkTransient(expr, oper);

        }//Constructor
    }//Class
class Exprline : AstNode
    {
        public AstNode ChildNode;

        public override void Init(AstContext context, ParseTreeNode treeNode)
        {
            base.Init(context, treeNode);

            var token = treeNode.Token;
            var term = treeNode.Term;
            var nodes = treeNode.GetMappedChildNodes();

            foreach (var node in nodes)
            {
                AddChild(string.Empty, node);
            }
        }
    }

    class Expr : AstNode
    {
        public AstNode ChildNode;

        public override void Init(AstContext context, ParseTreeNode treeNode)
        {
            base.Init(context, treeNode);

            var token = treeNode.Token;
            var term = treeNode.Term;
            var nodes = treeNode.GetMappedChildNodes();

            foreach (var node in nodes)
            {
                AddChild(string.Empty, node);
            }
        }
    }

    class BinExpr : AstNode
    {
        public AstNode ChildNode;

        public override void Init(AstContext context, ParseTreeNode treeNode)
        {
            base.Init(context, treeNode);

            var token = treeNode.Token;
            var term = treeNode.Term;
            var nodes = treeNode.GetMappedChildNodes();

            foreach (var node in nodes)
            {
                AddChild(string.Empty, node);
            }
        }
    }

    class Oper : AstNode
    {
        public AstNode ChildNode;

        public override void Init(AstContext context, ParseTreeNode treeNode)
        {
            base.Init(context, treeNode);

            var token = treeNode.Token;
            var term = treeNode.Term;
            var nodes = treeNode.GetMappedChildNodes();

            foreach (var node in nodes)
            {
                AddChild(string.Empty, node);
            }
        }
    }

    class Plus : AstNode
    {
        public AstNode ChildNode;

        public override void Init(AstContext context, ParseTreeNode treeNode)
        {
            base.Init(context, treeNode);

            var token = treeNode.Token;
            var term = treeNode.Term;
            var nodes = treeNode.GetMappedChildNodes();

            AsString = "Operator: " + token.Text;
            foreach (var node in nodes)
            {
                AddChild(string.Empty, node);
            }
        }
    }

    class Minus : AstNode
    {
        public AstNode ChildNode;

        public override void Init(AstContext context, ParseTreeNode treeNode)
        {
            base.Init(context, treeNode);

            var token = treeNode.Token;
            var term = treeNode.Term;
            var nodes = treeNode.GetMappedChildNodes();

            AsString = "Operator: " + token.Text;
            foreach (var node in nodes)
            {
                AddChild(string.Empty, node);
            }
        }
    }
What am I doing wrong?

Thank you.
Coordinator
Jul 31, 2015 at 10:39 PM
I think your definition of 'plus' and 'minus' is quite wrong. You declare non-terminal with a Rule = ToTerm("+") - this does not make sense. Look at sample expression evaluator grammar as a guidance