Identifier Ast causes an error

Dec 10, 2013 at 2:08 PM
Hi, I have been using the GrammarExplorer provided by the project to write a new grammar.
There seems to be a simple problem. The grammar generates a good ast as well as a parse tree but when there is an Identifier it fails. All the AstNode classes have been overridden. Is it grammar dependent ? or something generic that I must have overlooked.

partial grammar:
//Terminals
var Identifier = new IdentifierTerminal("Identifier");
var Select = ToTerm("SELECT");

//Non Terminals
var Columns  = new NonTerminal("Columns",typeof(Columns));
var ColumnOpt = new NonTerminal("ColumnOpt",typeof(ColumnOpt));
var Column   = new NonTerminal("Column",typeof(Column));
var SelectStatement = new NonTerminal("SelectStatement",typeof(SelectStatement));
var Joins = new NonTerminal("Joins",typeof(Joins));
var AllJoins = new NonTerminal("AllJoins",typeof(AllJoins));

//Rules
Columns.Rule = ColumnOpt|ToTerm("*");
ColumnOpt.Rule = MakePlusRule(ColumnOpt, Comma, Column);
Column.Rule = Expression|(Expression+ToTerm("AS")+Identifier);
SelectStatement.Rule = (Select + Columns) | (Select + Columns + From + AllJoins);
Joins.Rule = ToTerm("CROSS")|ToTerm("INNER");
AllJoins.Rule = Identifier |( Identifier + Joins + ToTerm("JOIN") + Identifier) |( Identifier + Joins + ToTerm("JOIN") + Identifier + ToTerm("ON") + Expression);
*for Expression i have used the example from calculator sample.

it recognizes(Expected) && builds
SELECT *;
but fails to build Ast for
SELECT * FROM Xyz;
public class BaseAst : AstNode
        {
            AstNode _singleChild;
            public override void Init(AstContext context, ParseTreeNode treeNode)
            {
                base.Init(context, treeNode);
                var nodes = treeNode.GetMappedChildNodes();
                foreach (var child in nodes)
                {
                    if (child.AstNode != null)
                        AddChild(string.Empty, child);
                }
                AsString = "BaseNode";
                if (ChildNodes.Count == 0)
                    AsString += "*";
                else
                    ChildNodes[ChildNodes.Count - 1].Flags |= AstNodeFlags.IsTail;
            }

            private object EvaluateEmpty(ScriptThread thread)
            {
                return null;
            }

            private object EvaluateOne(ScriptThread thread)
            {
                thread.CurrentNode = this;
                object result = _singleChild.Evaluate(thread);
                thread.CurrentNode = Parent;
                return result;
            }

            private object EvaluateMultiple(ScriptThread thread)
            {
                thread.CurrentNode = this;
                object result = null;
                for (int i = 0; i < ChildNodes.Count; i++)
                {
                    result = ChildNodes[i].Evaluate(thread);
                }
                thread.CurrentNode = Parent;
                return result;
            }

            protected override object DoEvaluate(Irony.Interpreter.ScriptThread thread)
            {
                thread.CurrentNode = this;
                lock (LockObject)
                {
                    switch (ChildNodes.Count)
                    {
                        case 0:
                            Evaluate = EvaluateEmpty;
                            break;
                        case 1:
                            _singleChild = ChildNodes[0];
                            Evaluate = EvaluateOne;
                            break;
                        default:
                            Evaluate = EvaluateMultiple;
                            break;
                    }
                }
                var result = Evaluate(thread);
                thread.CurrentNode = Parent;
                return result;
            }
        }
I have created AstNode classes for all non terminals type
public class Columns: BaseAst{ public override void Init(AstContext context,ParseTreeNode treeNode){base.Init(context,treeNode);AsString+="Columns";}}
public class Column: BaseAst{ public override void Init(AstContext context,ParseTreeNode treeNode){base.Init(context,treeNode);AsString+="Column";}}
public class ColumnOpt: BaseAst{ public override void Init(AstContext context,ParseTreeNode treeNode){base.Init(context,treeNode);AsString+="ColumnOpt";}}
/*
..So on..
*/
What could have been wrong ?
Coordinator
Dec 12, 2013 at 7:27 PM
you probably use AstContext class, not InterpreterAstContext - which sets default AST node types for identifier and literals terminals.
Either initialize these in AstContext class, or set these in grammar constructor - assign directly in Identifier terminal.