public ExpressionEvaluatorGrammar() : base(caseSensitive: false)
        {
            this.GrammarComments =
      @"Irony expression evaluator. Case-insensitive. Supports big integers, float data types, variables, assignments,
arithmetic operations, augmented assignments (+=, -=), inc/dec (++,--), strings with embedded expressions; 
bool operations &,&&, |, ||; ternary '?:' operator.";
            // 1. Terminals
            var number = new NumberLiteral("number");
            //Let's allow big integers (with unlimited number of digits):
            number.DefaultIntTypes = new TypeCode[] { TypeCode.Int32, TypeCode.Int64, NumberLiteral.TypeCodeBigInt };
            var identifier = new IdentifierTerminal("identifier");
            var comment = new CommentTerminal("comment", "#", "\n", "\r");
            //comment must be added to NonGrammarTerminals list; it is not used directly in grammar rules,
            // so we add it to this list to let Scanner know that it is also a valid terminal. 
            base.NonGrammarTerminals.Add(comment);
            var comma = ToTerm(",");

            //String literal with embedded expressions  ------------------------------------------------------------------
            var stringLit = new StringLiteral("string", "\"", StringOptions.AllowsAllEscapes | StringOptions.IsTemplate);
            stringLit.AddStartEnd("'", StringOptions.AllowsAllEscapes | StringOptions.IsTemplate);
            stringLit.AstConfig.NodeType = typeof(StringTemplateNode);
            var Expr = new NonTerminal("Expr"); //declare it here to use in template definition 
            var templateSettings = new StringTemplateSettings(); //by default set to Ruby-style settings 
            templateSettings.ExpressionRoot = Expr; //this defines how to evaluate expressions inside template
            this.SnippetRoots.Add(Expr);
            stringLit.AstConfig.Data = templateSettings;
            //--------------------------------------------------------------------------------------------------------

            // 2. Non-terminals
            var Term = new NonTerminal("Term");
            var BinExpr = new NonTerminal("BinExpr", typeof(BinaryOperationNode));
            var ParExpr = new NonTerminal("ParExpr");
            var UnExpr = new NonTerminal("UnExpr", typeof(UnaryOperationNode));
            var TernaryIfExpr = new NonTerminal("TernaryIf", typeof(IfNode));
            var ArgList = new NonTerminal("ArgList", typeof(ExpressionListNode));
            var FunctionCall = new NonTerminal("FunctionCall", typeof(FunctionCallNode));
            var MemberAccess = new NonTerminal("MemberAccess", typeof(MemberAccessNode));
            var IndexedAccess = new NonTerminal("IndexedAccess", typeof(IndexedAccessNode));
            var ObjectRef = new NonTerminal("ObjectRef"); // foo, foo.bar or f['bar']
            var UnOp = new NonTerminal("UnOp");
            var BinOp = new NonTerminal("BinOp", "operator");
            var PrefixIncDec = new NonTerminal("PrefixIncDec", typeof(IncDecNode));
            var PostfixIncDec = new NonTerminal("PostfixIncDec", typeof(IncDecNode));
            var IncDecOp = new NonTerminal("IncDecOp");
            var AssignmentStmt = new NonTerminal("AssignmentStmt", typeof(AssignmentNode));
            var AssignmentOp = new NonTerminal("AssignmentOp", "assignment operator");
            var Statement = new NonTerminal("Statement");
            var Program = new NonTerminal("Program", typeof(StatementListNode));

            // 3. BNF rules
            Expr.Rule = Term | UnExpr | BinExpr | PrefixIncDec | PostfixIncDec | TernaryIfExpr;
            Term.Rule = number | ParExpr | stringLit | FunctionCall | identifier | MemberAccess | IndexedAccess;
            ParExpr.Rule = "(" + Expr + ")";
            UnExpr.Rule = UnOp + Term + ReduceHere();
            UnOp.Rule = ToTerm("+") | "-" | "!";
            BinExpr.Rule = Expr + BinOp + Expr;
            BinOp.Rule = ToTerm("+") | "-" | "*" | "/" | "**" | "==" | "<" | "<=" | ">" | ">=" | "!=" | "&&" | "||" | "&" | "|";
            PrefixIncDec.Rule = IncDecOp + identifier;
            PostfixIncDec.Rule = identifier + PreferShiftHere() + IncDecOp;
            IncDecOp.Rule = ToTerm("++") | "--";
            TernaryIfExpr.Rule = Expr + "?" + Expr + ":" + Expr;
            MemberAccess.Rule = Expr + PreferShiftHere() + "." + identifier;
            AssignmentStmt.Rule = ObjectRef + AssignmentOp + Expr;
            AssignmentOp.Rule = ToTerm("=") | "+=" | "-=" | "*=" | "/=";
            Statement.Rule = AssignmentStmt | Expr | Empty;
            ArgList.Rule = MakeStarRule(ArgList, comma, Expr);
            FunctionCall.Rule = Expr + PreferShiftHere() + "(" + ArgList + ")";
            FunctionCall.NodeCaptionTemplate = "call #{0}(...)";
            ObjectRef.Rule = identifier | MemberAccess | IndexedAccess;
            IndexedAccess.Rule = Expr + PreferShiftHere() + "[" + Expr + "]";

            Program.Rule = MakePlusRule(Program, NewLine, Statement);

            this.Root = Program;       // Set grammar root

            // 4. Operators precedence
            RegisterOperators(10, "?");
            RegisterOperators(15, "&", "&&", "|", "||");
            RegisterOperators(20, "==", "<", "<=", ">", ">=", "!=");
            RegisterOperators(30, "+", "-");
            RegisterOperators(40, "*", "/");
            RegisterOperators(50, Associativity.Right, "**");
            RegisterOperators(60, "!");
            // For precedence to work, we need to take care of one more thing: BinOp. 
            //For BinOp which is or-combination of binary operators, we need to either 
            // 1) mark it transient or 2) set flag TermFlags.InheritPrecedence
            // We use first option, making it Transient.  

            // 5. Punctuation and transient terms
            MarkPunctuation("(", ")", "?", ":", "[", "]");
            RegisterBracePair("(", ")");
            RegisterBracePair("[", "]");
            MarkTransient(Term, Expr, Statement, BinOp, UnOp, IncDecOp, AssignmentOp, ParExpr, ObjectRef);

            // 7. Syntax error reporting
            MarkNotReported("++", "--");
            AddToNoReportGroup("(", "++", "--");
            AddToNoReportGroup(NewLine);
            AddOperatorReportGroup("operator");
            AddTermsReportGroup("assignment operator", "=", "+=", "-=", "*=", "/=");

            //8. Console
            ConsoleTitle = "Irony Expression Evaluator";
            ConsoleGreeting =
      @"Irony Expression Evaluator 

  Supports variable assignments, arithmetic operators (+, -, *, /),
    augmented assignments (+=, -=, etc), prefix/postfix operators ++,--, string operations. 
  Supports big integer arithmetics, string operations.
  Supports strings with embedded expressions : ""name: #{name}""

Press Ctrl-C to exit the program at any time.
";
            ConsolePrompt = "?";
            ConsolePromptMoreInput = "?";

            //9. Language flags. 
            // Automatically add NewLine before EOF so that our BNF rules work correctly when there's no final line break in source
            this.LanguageFlags = LanguageFlags.NewLineBeforeEOF | LanguageFlags.CreateAst | LanguageFlags.SupportsBigInt;
        }
 private StringLiteral CreateStringLiteral(string name)
 {
     var term = new StringLiteral(name);
     term.AddStartEnd("\"", StringOptions.AllowsAllEscapes);
     term.AddStartEnd("'", StringOptions.AllowsDoubledQuote | StringOptions.AllowsOctalEscapes | StringOptions.AllowsUEscapes | StringOptions.AllowsXEscapes);
     return term;
 }
Beispiel #3
0
        private StringLiteral CreateStringLiteral(string name)
        {
            var term = new StringLiteral(name);

            term.AddStartEnd("\"", StringOptions.AllowsAllEscapes);
            term.AddStartEnd("'", StringOptions.AllowsDoubledQuote | StringOptions.AllowsOctalEscapes | StringOptions.AllowsUEscapes | StringOptions.AllowsXEscapes);
            return(term);
        }
Beispiel #4
0
        private static StringLiteral CreateScriptNetString(string name)
        {
            StringLiteral term = new StringLiteral(name, TermOptions.None);

            term.AddStartEnd("'", ScanFlags.AllowAllEscapes);
            term.AddStartEnd("\"", ScanFlags.AllowAllEscapes);
            term.AddPrefixFlag("@", ScanFlags.DisableEscapes | ScanFlags.AllowLineBreak | ScanFlags.AllowDoubledQuote);
            return(term);
        }
Beispiel #5
0
        private BnfTerm CreateSqlExtIdentifier(string name)
        {
            var identifierTerminal = new IdentifierTerminal(name, null, "@");
            var stringLiteral      = new StringLiteral(name + "_quoted");

            stringLiteral.AddStartEnd("[", "]", StringOptions.NoEscapes);
            stringLiteral.AddStartEnd("\"", StringOptions.NoEscapes);
            stringLiteral.SetOutputTerminal(this, identifierTerminal);
            return(identifierTerminal);
        }
Beispiel #6
0
        //Covers simple identifiers like abcd, and also quoted versions: [abc d], "abc d".
        public static IdentifierTerminal CreateSqlExtIdentifier(Grammar grammar, string name)
        {
            var           id   = CreateTerm(name);
            StringLiteral term = new StringLiteral(name + "_qouted");

            term.AddStartEnd("[", "]", StringOptions.NoEscapes);
            term.AddStartEnd("\"", StringOptions.NoEscapes);
            term.SetOutputTerminal(grammar, id); //term will be added to NonGrammarTerminals automatically
            return(id);
        }
Beispiel #7
0
        static StringLiteral createStringLiteral()
        {
            StringLiteral term = new StringLiteral("String");

            term.AddStartEnd("'", StringOptions.AllowsAllEscapes | StringOptions.AllowsLineBreak);
            term.AddStartEnd("\"", StringOptions.AllowsAllEscapes | StringOptions.AllowsLineBreak);
            term.AddStartEnd("%[", "]", StringOptions.AllowsAllEscapes | StringOptions.AllowsLineBreak);
            term.AddStartEnd("%(", ")", StringOptions.AllowsAllEscapes | StringOptions.AllowsLineBreak);
            term.AddStartEnd("%{", "}", StringOptions.AllowsAllEscapes | StringOptions.AllowsLineBreak);

            return(term);
        }
Beispiel #8
0
    public static StringLiteral CreatePythonString(string name) {
      StringLiteral term = new StringLiteral(name);
      term.AddStartEnd("'", StringOptions.AllowsAllEscapes);
      term.AddStartEnd("'''", StringOptions.AllowsAllEscapes | StringOptions.AllowsLineBreak);
      term.AddStartEnd("\"", StringOptions.AllowsAllEscapes);
      term.AddStartEnd("\"\"\"", StringOptions.AllowsAllEscapes | StringOptions.AllowsLineBreak);

      term.AddPrefix("u", StringOptions.AllowsAllEscapes);
      term.AddPrefix("r", StringOptions.NoEscapes );
      term.AddPrefix("ur", StringOptions.NoEscapes);
 
      return term;
    }
Beispiel #9
0
 public static StringLiteral CreateVbString(string name) {
   StringLiteral term = new StringLiteral(name);
   term.AddStartEnd("\"", StringOptions.NoEscapes | StringOptions.AllowsDoubledQuote);
   term.AddSuffix("$", TypeCode.String);
   term.AddSuffix("c", TypeCode.Char);
   return term;
 }
 public static StringLiteral CreateZodiacString(string name)
 {
     StringLiteral term = new StringLiteral(name);
     //term.AddStartEnd("'", StringOptions.AllowsAllEscapes);// AllowLineBreak??
     term.AddStartEnd("\"", StringOptions.AllowsAllEscapes);// AllowLineBreak??
     return term;
 }
Beispiel #11
0
        private void MakeSimpleId()
        {
            Identifier = new IdentifierTerminal("simple_id");
            var idStringLiteral = new StringLiteral("simple_id_quoted");

            idStringLiteral.AddStartEnd("\"", StringOptions.NoEscapes);
            idStringLiteral.AstConfig.NodeType = typeof(IdentifierNode);
            idStringLiteral.SetOutputTerminal(this, Identifier);
        }
Beispiel #12
0
        /// <summary>
        /// Create the term that represents an Entity identifier.
        /// </summary>
        public IdentifierTerminal CreateIdentifierTerm(string name)
        {
            var id   = new IdentifierTerminal(name, IdOptions.IsNotKeyword);
            var term = new StringLiteral(name + "_quoted");

            term.AddStartEnd("[", "]", StringOptions.AllowsDoubledQuote);
            term.SetOutputTerminal(this, id);
            return(id);
        }
Beispiel #13
0
        private NonTerminal AttributesList(BnfTerm identifier)
        {
            var options        = StringOptions.AllowsAllEscapes | StringOptions.AllowsLineBreak;
            var attributeValue = new StringLiteral("attributeValue", "'", options,
                                                   (context, node) => node.AstNode = node.Token.ValueString);

            attributeValue.AddStartEnd("\"", options);
            var attribute = NonTerminal("attribute", null, node => new Attribute
            {
                Name  = (CompositeIdentifier)node.ChildNodes[0].AstNode,
                Value = (string)node.ChildNodes[2].AstNode
            });
            var attributesList = NonTerminal("attributesList", null,
                                             node => node.ChildNodes.Select(c => (Attribute)c.AstNode).ToList());

            attribute.Rule      = identifier + "=" + attributeValue;
            attributesList.Rule = MakeStarRule(attributesList, attribute);
            return(attributesList);
        }
Beispiel #14
0
        public SqlGrammar()
            : base(false)
        { //SQL is case insensitive
            //Terminals
            var comment     = new CommentTerminal("comment", "/*", "*/");
            var lineComment = new CommentTerminal("line_comment", "--", "\n", "\r\n");

            NonGrammarTerminals.Add(comment);
            NonGrammarTerminals.Add(lineComment);
            var number = TerminalFactory.CreateCSharpNumber("number");

            number.Options = NumberOptions.AllowSign;
            var string_literal = new StringLiteral("string", "'", StringOptions.AllowsDoubledQuote);

            string_literal.AddStartEnd("N'", "'", StringOptions.AllowsDoubledQuote | StringOptions.AllowsLineBreak);
            var Id_simple = TerminalFactory.CreateSqlExtIdentifier(this, "id_simple"); //covers normal identifiers (abc) and quoted id's ([abc d], "abc d")

            Id_simple.AddPrefix("@@", IdOptions.NameIncludesPrefix);
            Id_simple.AddPrefix("@", IdOptions.NameIncludesPrefix);

            var comma        = ToTerm(",");
            var dot          = ToTerm(".");
            var equals       = ToTerm("=");
            var plus         = ToTerm("+");
            var CREATE       = ToTerm("CREATE");
            var NULL         = ToTerm("NULL");
            var NOT          = ToTerm("NOT");
            var UNIQUE       = ToTerm("UNIQUE");
            var WITH         = ToTerm("WITH");
            var TABLE        = ToTerm("TABLE");
            var VIEW         = ToTerm("VIEW");
            var DATABASE     = ToTerm("DATABASE");
            var ALTER        = ToTerm("ALTER");
            var ADD          = ToTerm("ADD");
            var COLUMN       = ToTerm("COLUMN");
            var DROP         = ToTerm("DROP");
            var CONSTRAINT   = ToTerm("CONSTRAINT");
            var INDEX        = ToTerm("INDEX");
            var CLUSTERED    = ToTerm("CLUSTERED");
            var NONCLUSTERED = ToTerm("NONCLUSTERED");
            var ON           = ToTerm("ON");
            var KEY          = ToTerm("KEY");
            var PRIMARY      = ToTerm("PRIMARY");
            var INSERT       = ToTerm("INSERT");
            var INTO         = ToTerm("INTO");
            var UPDATE       = ToTerm("UPDATE");
            var SET          = ToTerm("SET");
            var VALUES       = ToTerm("VALUES");
            var DELETE       = ToTerm("DELETE");
            var SELECT       = ToTerm("SELECT");
            var FROM         = ToTerm("FROM");
            var AS           = ToTerm("AS");
            var COUNT        = ToTerm("COUNT");
            var JOIN         = ToTerm("JOIN");
            var BY           = ToTerm("BY");
            var DEFAULT      = ToTerm("DEFAULT");
            var CHECK        = ToTerm("CHECK");
            var REPLICATION  = ToTerm("REPLICATION");
            var FOR          = ToTerm("FOR");
            var COLLATE      = ToTerm("COLLATE");
            var IDENTITY     = ToTerm("IDENTITY");
            var TEXTIMAGE_ON = ToTerm("TEXTIMAGE_ON");
            var IF           = ToTerm("IF");
            var ELSE         = ToTerm("ELSE");
            var BEGIN        = ToTerm("BEGIN");
            var END          = ToTerm("END");
            var GO           = ToTerm("GO");
            var PRINT        = ToTerm("PRINT");
            var IS           = ToTerm("IS");
            var USE          = ToTerm("USE");
            var EXEC         = ToTerm("EXEC");
            var NOCHECK      = ToTerm("NOCHECK");
            var CASCADE      = ToTerm("CASCADE");
            var TYPE         = ToTerm("TYPE");
            var PROCEDURE    = ToTerm("PROCEDURE");
            var DECLARE      = ToTerm("DECLARE");
            var TRY          = ToTerm("TRY");
            var CATCH        = ToTerm("CATCH");
            var CAST         = ToTerm("CAST");
            var AND          = ToTerm("AND");
            var OR           = ToTerm("OR");
            var GRANT        = ToTerm("GRANT");
            var UNION        = ToTerm("UNION");
            var ALL          = ToTerm("ALL");
            var CASE         = ToTerm("CASE");
            var WHEN         = ToTerm("WHEN");
            var THEN         = ToTerm("THEN");
            var RETURN       = ToTerm("RETURN");
            var COMMIT       = ToTerm("COMMIT");
            var TRAN         = ToTerm("TRAN");
            var TRANSACTION  = ToTerm("TRANSACTION");
            var TOP          = ToTerm("TOP");
            var MERGE        = ToTerm("MERGE");
            var USING        = ToTerm("USING");
            var MATCHED      = ToTerm("MATCHED");
            var TARGET       = ToTerm("TARGET");
            var TRUNCATE     = ToTerm("TRUNCATE");
            var ROLLBACK     = ToTerm("ROLLBACK");
            var STATISTICS   = ToTerm("STATISTICS");
            var ROLE         = ToTerm("ROLE");
            var WHILE        = ToTerm("WHILE");
            var BREAK        = ToTerm("BREAK");
            var REBUILD      = ToTerm("REBUILD");
            var CHECKPOINT   = ToTerm("CHECKPOINT");
            var HASH         = ToTerm("HASH");
            var OUTPUT       = ToTerm("OUTPUT");

            //Non-terminals
            var Id                     = new NonTerminal("Id");
            var IdWithAliasOpt         = new NonTerminal("IdWithAliasOpt");
            var stmt                   = new NonTerminal("stmt");
            var createTableStmt        = new NonTerminal("createTableStmt");
            var createIndexStmt        = new NonTerminal("createIndexStmt");
            var createViewStmt         = new NonTerminal("createViewStmt");
            var createTypeStmt         = new NonTerminal("createTypeStmt");
            var createProcedureStmt    = new NonTerminal("createProcedureStmt");
            var variableDefLists       = new NonTerminal("variableDefLists");
            var variableDefList        = new NonTerminal("variableDefList");
            var variableDef            = new NonTerminal("variableDef");
            var outputOpt              = new NonTerminal("outputOpt");
            var primaryKeyOpt          = new NonTerminal("primaryKeyOpt");
            var alterStmt              = new NonTerminal("alterStmt");
            var dropTableStmt          = new NonTerminal("dropTableStmt");
            var dropIndexStmt          = new NonTerminal("dropIndexStmt");
            var dropViewStmt           = new NonTerminal("dropViewStmt");
            var dropProcedureStmt      = new NonTerminal("dropProcedureStmt");
            var selectStmt             = new NonTerminal("selectStmt");
            var insertStmt             = new NonTerminal("insertStmt");
            var updateStmt             = new NonTerminal("updateStmt");
            var deleteStmt             = new NonTerminal("deleteStmt");
            var ifStmt                 = new NonTerminal("ifStmt");
            var elseStmt               = new NonTerminal("elseStmt");
            var fieldDef               = new NonTerminal("fieldDef");
            var fieldDefList           = new NonTerminal("fieldDefList");
            var nullSpecOpt            = new NonTerminal("nullSpecOpt");
            var typeName               = new NonTerminal("typeName");
            var constraintListOpt      = new NonTerminal("constraintListOpt");
            var constraintDef          = new NonTerminal("constraintDef");
            var indexContraintDef      = new NonTerminal("indexContraintDef");
            var constraintTypeOpt      = new NonTerminal("constraintTypeOptOpt");
            var defaultValueOpt        = new NonTerminal("defaultValueOpt");
            var idlist                 = new NonTerminal("idlist");
            var idOrExpression         = new NonTerminal("idOrExpression");
            var idOrExpressionList     = new NonTerminal("idOrExpressionList");
            var idlistForSelect        = new NonTerminal("idlistForSelect");
            var idlistParOpt           = new NonTerminal("idlistPar");
            var orderList              = new NonTerminal("orderList");
            var orderMember            = new NonTerminal("orderMember");
            var orderDirOpt            = new NonTerminal("orderDirOpt");
            var defaultValueParams     = new NonTerminal("defaultValueParams");
            var indexTypeOpt           = new NonTerminal("indexTypeOpt");
            var indexTypeList          = new NonTerminal("indexTypeList");
            var withClauseOpt          = new NonTerminal("withClauseOpt");
            var alterCmdOpt            = new NonTerminal("alterCmdOpt");
            var insertData             = new NonTerminal("insertData");
            var intoOpt                = new NonTerminal("intoOpt");
            var assignList             = new NonTerminal("assignList");
            var whereClauseOpt         = new NonTerminal("whereClauseOpt");
            var andClauseOpt           = new NonTerminal("andClauseOpt");
            var betweenClauseOpt       = new NonTerminal("betweenClauseOpt");
            var assignment             = new NonTerminal("assignment");
            var expression             = new NonTerminal("expression");
            var exprList               = new NonTerminal("exprList");
            var selRestrOpt            = new NonTerminal("selRestrOpt");
            var selList                = new NonTerminal("selList");
            var intoClauseOpt          = new NonTerminal("intoClauseOpt");
            var fromClauseOpt          = new NonTerminal("fromClauseOpt");
            var groupClauseOpt         = new NonTerminal("groupClauseOpt");
            var havingClauseOpt        = new NonTerminal("havingClauseOpt");
            var orderClauseOpt         = new NonTerminal("orderClauseOpt");
            var columnItemList         = new NonTerminal("columnItemList");
            var columnItem             = new NonTerminal("columnItem");
            var columnSource           = new NonTerminal("columnSource");
            var asOpt                  = new NonTerminal("asOpt");
            var aliasOpt               = new NonTerminal("aliasOpt");
            var aggregate              = new NonTerminal("aggregate");
            var aggregateArg           = new NonTerminal("aggregateArg");
            var aggregateName          = new NonTerminal("aggregateName");
            var tuple                  = new NonTerminal("tuple");
            var joinChainOpt           = new NonTerminal("joinChainOpt");
            var joinKindOpt            = new NonTerminal("joinKindOpt");
            var term                   = new NonTerminal("term");
            var unExpr                 = new NonTerminal("unExpr");
            var unOp                   = new NonTerminal("unOp");
            var binExpr                = new NonTerminal("binExpr");
            var binOp                  = new NonTerminal("binOp");
            var betweenExpr            = new NonTerminal("betweenExpr");
            var notOpt                 = new NonTerminal("notOpt");
            var funCall                = new NonTerminal("funCall");
            var stmtLine               = new NonTerminal("stmtLine");
            var semiOpt                = new NonTerminal("semiOpt");
            var stmtList               = new NonTerminal("stmtList");
            var funArgsOpt             = new NonTerminal("funArgsOpt");
            var inStmt                 = new NonTerminal("inStmt");
            var settingList            = new NonTerminal("settingList");
            var settingListItem        = new NonTerminal("settingListItem");
            var onOpt                  = new NonTerminal("onOpt");
            var textImageOnOpt         = new NonTerminal("textImageOnOpt");
            var defaultValueParamsList = new NonTerminal("defaultValueParamsList");
            var typeNameParamsList     = new NonTerminal("typeNameParamsList");
            var notForReplOpt          = new NonTerminal("notForReplOpt");
            var collateOpt             = new NonTerminal("collateOpt");
            var columnDef              = new NonTerminal("columnDef");
            var identityOpt            = new NonTerminal("identityOpt");
            var referencesOpt          = new NonTerminal("referencesOpt");
            var fieldDefLists          = new NonTerminal("fieldDefLists");
            var onListOpt              = new NonTerminal("onListOpt");
            var printStmt              = new NonTerminal("printStmt");
            var beginEndStmt           = new NonTerminal("beginEndStmt");
            var beginTryCatchStmt      = new NonTerminal("beginTryCatchStmt");
            var beginEndStmtList       = new NonTerminal("beginEndStmtList");
            var isNullOpt              = new NonTerminal("isNullOpt");
            var setStmtOpt             = new NonTerminal("setStmtOpt");
            var useStmt                = new NonTerminal("useStmt");
            var forOpt                 = new NonTerminal("forOpt");
            var execStmt               = new NonTerminal("execStmt");
            var cascadeOpt             = new NonTerminal("cascadeOpt");
            var cascadeListOpt         = new NonTerminal("cascadeListOpt");
            var alterProcedureStmt     = new NonTerminal("alterProcedureStmt");
            var declareStmt            = new NonTerminal("declareStmt");
            var concatStringItem       = new NonTerminal("concatStringItem");
            var concatStringList       = new NonTerminal("concatStringList");
            var castFunCall            = new NonTerminal("castFunCall");
            var funCallList            = new NonTerminal("funCallList");
            var funcallDelim           = new NonTerminal("funcallDelim");
            var declareList            = new NonTerminal("declareList");
            var declareListItem        = new NonTerminal("declareListItem");
            var grantStmt              = new NonTerminal("grantStmt");
            var joinChainOptList       = new NonTerminal("joinChainOptList");
            var leftParenOpt           = new NonTerminal("leftParenOpt");
            var rightParenOpt          = new NonTerminal("rightParenOpt");
            var unionAllOpt            = new NonTerminal("unionAllOpt");
            var selectCaseStmts        = new NonTerminal("selectCaseStmts");
            var selectCaseStmt         = new NonTerminal("selectCaseStmt");
            var caseWhenThenLists      = new NonTerminal("caseWhenThenLists");
            var caseWhenThenList       = new NonTerminal("caseWhenThenList");
            var caseWhenThenStmt       = new NonTerminal("caseWhenThenStmt");
            var unionAllListOpt        = new NonTerminal("unionAllListOpt");
            var returnStmt             = new NonTerminal("returnStmt");
            var beginTransStmt         = new NonTerminal("beginTransStmt");
            var rollbackTransStmt      = new NonTerminal("rollbackTransStmt");
            var topOpt                 = new NonTerminal("topOpt");
            var mergeStmt              = new NonTerminal("mergeStmt");
            var mergeWhenMatched       = new NonTerminal("mergeWhenMatched");
            var mergeWhenNotMatched    = new NonTerminal("mergeWhenNotMatched");
            var truncateStmt           = new NonTerminal("truncateStmt");
            var commitTransStmt        = new NonTerminal("commitTransStmt");
            var noLockOpt              = new NonTerminal("noLockOpt");
            var declareTableStmt       = new NonTerminal("declareTableStmt");
            var joinStmtOpt            = new NonTerminal("joinStmtOpt");
            var forXmlStmtOpt          = new NonTerminal("forXmlStmtOpt");
            var forXmlFunCallList      = new NonTerminal("forXmlFunCallList");
            var funArgsList            = new NonTerminal("funArgsList");
            var updateStatisticsStmt   = new NonTerminal("updateStatisticsStmt");
            var createRoleStmt         = new NonTerminal("createRoleStmt");
            var whileStmt              = new NonTerminal("whileStmt");
            var alterIndexStmt         = new NonTerminal("alterIndexStmt");
            var ifCondition            = new NonTerminal("ifCondition");
            var ifConditionChain       = new NonTerminal("ifConditionChain");
            var hashOpt                = new NonTerminal("hashOpt");
            var IdAsType               = new NonTerminal("IdAsType");
            var selectWithUnion        = new NonTerminal("selectWithUnion");
            var withStmt               = new NonTerminal("withStmt");

            //BNF Rules
            this.Root             = stmtList;
            stmtLine.Rule         = stmt + semiOpt;
            semiOpt.Rule          = Empty | ";";
            stmtList.Rule         = MakePlusRule(stmtList, stmtLine);
            setStmtOpt.Rule       = Empty | SET + Id + Id | SET + Id + equals + (leftParenOpt + selectStmt + rightParenOpt | Id | funCall | concatStringList | expression);
            useStmt.Rule          = USE + Id;
            execStmt.Rule         = EXEC + (Empty | Id | Id + ".." + Id) + (leftParenOpt + funArgsList + rightParenOpt);
            declareStmt.Rule      = DECLARE + declareList;
            declareTableStmt.Rule = DECLARE + Id + TABLE + "(" + fieldDefList + ")";
            declareListItem.Rule  = Id + typeName
                                    | Id + typeName + equals + term;
            declareList.Rule        = MakePlusRule(declareList, comma, declareListItem);
            castFunCall.Rule        = CAST + "(" + funCall + asOpt + (Empty | typeName) + ")" + asOpt + (Empty | typeName);
            grantStmt.Rule          = GRANT + term + ON + TYPE + "::" + Id + "TO" + Id;
            returnStmt.Rule         = RETURN + term;
            leftParenOpt.Rule       = Empty | "(";
            rightParenOpt.Rule      = Empty | ")";
            unionAllOpt.Rule        = Empty | UNION + ALL + leftParenOpt + selectStmt + rightParenOpt;
            unionAllListOpt.Rule    = MakeStarRule(unionAllListOpt, unionAllOpt);
            idOrExpression.Rule     = Id | expression;
            idOrExpressionList.Rule = MakeStarRule(idOrExpressionList, comma, idOrExpression);
            whileStmt.Rule          = WHILE + expression + beginEndStmt;

            //ID
            Id.Rule               = MakePlusRule(Id, dot, Id_simple);
            IdWithAliasOpt.Rule   = Id | Id + Id | Id + AS + Id;
            IdAsType.Rule         = Id + AS + typeName;
            concatStringItem.Rule = leftParenOpt + term + rightParenOpt;
            concatStringList.Rule = MakePlusRule(concatStringList, plus, concatStringItem);

            stmt.Rule = createProcedureStmt | createTableStmt | createIndexStmt | createViewStmt | createTypeStmt | createRoleStmt
                        | declareTableStmt | alterStmt | dropTableStmt | dropIndexStmt | dropViewStmt | dropProcedureStmt
                        | selectWithUnion | insertStmt | updateStmt | deleteStmt | whileStmt
                        | GO | ifStmt | elseStmt | beginEndStmt | printStmt | withStmt
                        | execStmt | setStmtOpt | useStmt | funCall | declareStmt | returnStmt
                        | grantStmt | mergeStmt | truncateStmt | updateStatisticsStmt
                        | beginTransStmt | commitTransStmt | rollbackTransStmt
                        | BREAK | CHECKPOINT
                        | ";";

            onOpt.Rule          = Empty | ON + Id;
            textImageOnOpt.Rule = Empty | TEXTIMAGE_ON + Id;
            forOpt.Rule         = Empty | FOR + Id;
            onListOpt.Rule      = MakePlusRule(onListOpt, onOpt);
            withStmt.Rule       = WITH + Id + AS + leftParenOpt + selectStmt + rightParenOpt;
            fieldDefLists.Rule  = MakePlusRule(fieldDefLists, fieldDefList);

            printStmt.Rule = PRINT + concatStringList;

            beginEndStmtList.Rule  = MakePlusRule(beginEndStmtList, stmt);
            beginEndStmt.Rule      = beginTryCatchStmt | BEGIN + beginEndStmtList + END;
            beginTryCatchStmt.Rule = BEGIN + TRY + beginEndStmtList + END + TRY + BEGIN + CATCH + beginEndStmtList + END + CATCH;
            beginTransStmt.Rule    = BEGIN + (TRAN | TRANSACTION) + (Empty | Id);
            commitTransStmt.Rule   = COMMIT + (TRAN | TRANSACTION) + (Empty | Id);
            rollbackTransStmt.Rule = ROLLBACK + (TRAN | TRANSACTION) + (Empty | Id);
            truncateStmt.Rule      = TRUNCATE + TABLE + Id;
            isNullOpt.Rule         = Empty | IS + NULL;

            funcallDelim.Rule = AND | OR;
            funCallList.Rule  = MakePlusRule(funCallList, funcallDelim, funCall);

            // If
            ifStmt.Rule      = IF + leftParenOpt + ifConditionChain + rightParenOpt;
            ifCondition.Rule = (notOpt + funCall + isNullOpt | NOT + leftParenOpt + expression + rightParenOpt)
                               | (Empty | "EXISTS") + "(" + (Id_simple + IS + NULL | settingListItem | selectWithUnion) + ")"
                               | "EXISTS" + "(" + selectWithUnion + ")"
                               | (Id_simple + IS + (Empty | NOT) + NULL | settingListItem)
                               | expression;
            ifConditionChain.Rule = MakePlusRule(ifConditionChain, AND | OR, ifCondition);
            elseStmt.Rule         = ELSE;

            createRoleStmt.Rule = CREATE + ROLE + Id;
            createViewStmt.Rule = CREATE + VIEW + Id + AS + leftParenOpt + selectWithUnion + rightParenOpt + unionAllListOpt;
            createTypeStmt.Rule = CREATE + TYPE + Id + FROM + Id
                                  | CREATE + TYPE + Id + AS + TABLE + "(" + fieldDefLists + ")";

            //Create procedure
            createProcedureStmt.Rule = CREATE + PROCEDURE + Id + "(" + variableDefLists + ")" + AS + BEGIN + stmtList + END;
            variableDefLists.Rule    = MakePlusRule(variableDefLists, variableDefList);
            variableDefList.Rule     = MakeListRule(variableDefList, comma, variableDef, TermListOptions.AllowTrailingDelimiter | TermListOptions.PlusList);
            variableDef.Rule         = Id + typeName + outputOpt;
            outputOpt.Rule           = Empty | OUTPUT;

            //Create table
            createTableStmt.Rule = CREATE + TABLE + Id + "(" + fieldDefLists + ")" + (onOpt | withClauseOpt) + textImageOnOpt;
            fieldDefList.Rule    = MakeListRule(fieldDefList, comma, fieldDef, TermListOptions.AllowTrailingDelimiter | TermListOptions.PlusList);
            fieldDef.Rule        = columnDef | constraintListOpt;
            columnDef.Rule       = Id + typeName + collateOpt + primaryKeyOpt + nullSpecOpt + referencesOpt + defaultValueOpt + withClauseOpt
                                   | Id + typeName + collateOpt + primaryKeyOpt + nullSpecOpt + constraintListOpt + withClauseOpt
                                   | Id + typeName + collateOpt + primaryKeyOpt + notForReplOpt + nullSpecOpt + defaultValueOpt + withClauseOpt
                                   | Id + typeName + collateOpt + primaryKeyOpt + notForReplOpt + nullSpecOpt + constraintListOpt + withClauseOpt
                                   | Id + typeName + equals + term
                                   | primaryKeyOpt + indexTypeOpt + idlistParOpt + withClauseOpt
                                   | term;
            referencesOpt.Rule      = Empty | "References" + Id + idlistParOpt;
            notForReplOpt.Rule      = Empty | (NOT + FOR + REPLICATION);
            nullSpecOpt.Rule        = Empty | (NOT + FOR + REPLICATION) | NULL | NOT + NULL | NOT + NULL + typeName | NULL + typeName;
            collateOpt.Rule         = Empty | COLLATE + Id_simple;
            identityOpt.Rule        = Empty | IDENTITY;
            typeNameParamsList.Rule = MakePlusRule(typeNameParamsList, comma, term);
            typeName.Rule           = Id_simple | Id_simple + "(" + typeNameParamsList + ")" | Id_simple + "(max)";
            constraintDef.Rule      = CONSTRAINT + Id + constraintTypeOpt + onListOpt;
            indexContraintDef.Rule  = constraintTypeOpt + onListOpt;
            constraintListOpt.Rule  = MakeStarRule(constraintListOpt, constraintDef);
            constraintTypeOpt.Rule  = Empty | defaultValueOpt + withClauseOpt
                                      | primaryKeyOpt + indexTypeList + idlistParOpt + withClauseOpt
                                      | CHECK + "(" + expression + ")" + withClauseOpt
                                      | NOT + NULL + idlistParOpt + withClauseOpt
                                      | "Foreign" + KEY + idlistParOpt + referencesOpt + notForReplOpt + withClauseOpt
                                      | "INCLUDE" + idlistParOpt + withClauseOpt + onOpt;
            idlistParOpt.Rule           = Empty | "(" + orderList + ")";
            idlist.Rule                 = MakePlusRule(idlist, comma, Id);
            idlistForSelect.Rule        = MakePlusRule(idlist, comma, IdWithAliasOpt);
            defaultValueParamsList.Rule = MakePlusRule(defaultValueParamsList, comma, term);
            defaultValueOpt.Rule        = Empty | (DEFAULT + defaultValueParams);
            defaultValueParams.Rule     = term | "(" + term + ")";

            //Create Index
            primaryKeyOpt.Rule   = Empty | PRIMARY + KEY | typeName;
            createIndexStmt.Rule = CREATE + indexTypeList + INDEX + Id + onOpt + "(" + orderList + ")" + constraintTypeOpt + whereClauseOpt + withClauseOpt + onOpt;
            orderList.Rule       = MakePlusRule(orderList, comma, orderMember);
            orderMember.Rule     = Id + orderDirOpt;
            orderDirOpt.Rule     = Empty | "ASC" | "DESC";
            indexTypeOpt.Rule    = Empty | UNIQUE | CLUSTERED | NONCLUSTERED;
            indexTypeList.Rule   = MakeStarRule(indexTypeList, indexTypeOpt);
            settingList.Rule     = MakePlusRule(settingList, comma, settingListItem);
            settingListItem.Rule = Id + equals + term;
            withClauseOpt.Rule   = Empty | (WITH + PRIMARY | WITH + "Disallow" + NULL | WITH + "Ignore" + NULL | WITH + "(" + settingList + ")" + onOpt + textImageOnOpt);
            cascadeOpt.Rule      = Empty | (ON + (UPDATE | DELETE) + CASCADE);
            cascadeListOpt.Rule  = MakePlusRule(cascadeListOpt, cascadeOpt);
            noLockOpt.Rule       = (Empty | WITH + leftParenOpt + "NOLOCK" + rightParenOpt);

            //Alter
            alterStmt.Rule = ALTER + (TABLE | DATABASE) + Id + setStmtOpt + alterCmdOpt
                             | alterProcedureStmt
                             | alterIndexStmt;
            alterCmdOpt.Rule = Empty | ADD + COLUMN + fieldDefList + constraintDef
                               | CHECK + CONSTRAINT + Id
                               | WITH + (CHECK | NOCHECK) + ADD + CONSTRAINT + Id + constraintTypeOpt + cascadeListOpt
                               | ADD + constraintDef + forOpt
                               | DROP + COLUMN + Id
                               | DROP + CONSTRAINT + Id;
            alterProcedureStmt.Rule = ALTER + PROCEDURE + Id + leftParenOpt + fieldDefLists + rightParenOpt + asOpt + beginEndStmt;
            alterIndexStmt.Rule     = ALTER + INDEX + Id + ON + Id + REBUILD + WITH + "(" + settingList + ")";

            //Drop stmts
            dropTableStmt.Rule     = DROP + TABLE + Id;
            dropIndexStmt.Rule     = DROP + INDEX + Id + ON + Id;
            dropViewStmt.Rule      = DROP + VIEW + Id;
            dropProcedureStmt.Rule = DROP + PROCEDURE + Id;

            //Insert stmt
            insertStmt.Rule = INSERT + (Empty | intoOpt + Id) + (idlistParOpt + insertData | execStmt);
            insertData.Rule = leftParenOpt + selectWithUnion + rightParenOpt | VALUES + "(" + exprList + ")";
            intoOpt.Rule    = Empty | INTO; //Into is optional in MSSQL

            //Update stmt
            updateStmt.Rule           = UPDATE + topOpt + (Empty | Id) + SET + assignList + fromClauseOpt + joinStmtOpt + whereClauseOpt + andClauseOpt;
            assignList.Rule           = MakePlusRule(assignList, comma, assignment);
            assignment.Rule           = Id + "=" + expression;
            updateStatisticsStmt.Rule = UPDATE + STATISTICS + Id;

            //Delete stmt
            deleteStmt.Rule = DELETE + (Empty | FROM) + Id + whereClauseOpt + andClauseOpt;

            //Select stmt
            selectCaseStmt.Rule    = CASE + caseWhenThenLists + ELSE + expression + END + (Empty | asOpt + Id);
            caseWhenThenLists.Rule = MakePlusRule(caseWhenThenLists, caseWhenThenList);
            caseWhenThenList.Rule  = WHEN + leftParenOpt + expression + rightParenOpt + THEN + term;
            variableDef.Rule       = Id + typeName + outputOpt;


            selectStmt.Rule = SELECT + topOpt + selRestrOpt + selList + intoClauseOpt + fromClauseOpt + forXmlStmtOpt + joinChainOptList + whereClauseOpt + andClauseOpt +
                              betweenClauseOpt + groupClauseOpt + havingClauseOpt + orderClauseOpt;
            selectWithUnion.Rule = MakePlusRule(selectWithUnion, UNION, selectStmt);
            mergeStmt.Rule       = MERGE + Id + AS + Id + USING + (Empty | Id) + leftParenOpt + (Empty | selectWithUnion) + rightParenOpt + AS + Id + ON + expression + mergeWhenMatched +
                                   mergeWhenNotMatched + mergeWhenNotMatched;
            mergeWhenMatched.Rule    = WHEN + MATCHED + andClauseOpt + THEN + stmt;
            mergeWhenNotMatched.Rule = Empty | WHEN + NOT + MATCHED + BY + Id + THEN + stmt;
            forXmlStmtOpt.Rule       = Empty | FOR + "XML" + forXmlFunCallList;
            forXmlFunCallList.Rule   = MakePlusRule(forXmlFunCallList, comma, funCall);

            topOpt.Rule           = Empty | TOP + leftParenOpt + (number | Id) + rightParenOpt;
            selRestrOpt.Rule      = Empty | "ALL" | "DISTINCT";
            selList.Rule          = columnItemList + semiOpt | "*";
            columnItemList.Rule   = MakePlusRule(columnItemList, comma, columnItem);
            columnItem.Rule       = columnSource;
            aliasOpt.Rule         = Empty | asOpt + Id;
            asOpt.Rule            = Empty | AS;
            columnSource.Rule     = Id + aliasOpt | Id + "=" + (selectCaseStmt | concatStringList | expression) | expression | expression + asOpt + (Empty | Id) | selectCaseStmt;
            aggregate.Rule        = aggregateName + "(" + aggregateArg + ")";
            aggregateArg.Rule     = expression | "*";
            aggregateName.Rule    = COUNT | "Avg" | "Min" | "Max" | "StDev" | "StDevP" | "Sum" | "Var" | "VarP";
            intoClauseOpt.Rule    = Empty | INTO + Id;
            fromClauseOpt.Rule    = Empty | FROM + leftParenOpt + (selectStmt | funCall | idlistForSelect) + rightParenOpt + (Empty | AS + Id) + noLockOpt;
            joinStmtOpt.Rule      = Empty | JOIN + Id + asOpt + Id + noLockOpt + ON + expression;
            joinChainOpt.Rule     = Empty | joinKindOpt + hashOpt + joinStmtOpt;
            joinChainOptList.Rule = MakeStarRule(joinChainOptList, joinChainOpt);
            joinKindOpt.Rule      = Empty | "INNER" | "OUTER" | "LEFT" | "RIGHT";
            hashOpt.Rule          = Empty | HASH;
            whereClauseOpt.Rule   = Empty | "WHERE" + expression;
            andClauseOpt.Rule     = Empty | "AND" + expression;
            betweenClauseOpt.Rule = Empty | "BETWEEN" + expression;
            groupClauseOpt.Rule   = Empty | "GROUP" + BY + idOrExpressionList;
            havingClauseOpt.Rule  = Empty | "HAVING" + expression;
            orderClauseOpt.Rule   = Empty | "ORDER" + BY + orderList;

            //Expression
            exprList.Rule   = MakePlusRule(exprList, comma, expression);
            expression.Rule = term | unExpr | binExpr | betweenExpr;                                 //-- BETWEEN doesn't work - yet; brings a few parsing conflicts
            term.Rule       = Id | IdAsType | string_literal | number | funCall | tuple | aggregate; // | inStmt;
            tuple.Rule      = "(" + exprList + ")";
            unExpr.Rule     = unOp + term;
            unOp.Rule       = NOT | "+" | "-" | "~";
            binExpr.Rule    = expression + binOp + expression;
            binOp.Rule      = ToTerm("+") | "-" | "*" | "/" | "%" //arithmetic
                              | "&" | "|" | "^"                   //bit
                              | "=" | ">" | "<" | ">=" | "<=" | "<>" | "!=" | "!<" | "!>"
                              | "AND" | "OR" | "LIKE" | NOT + "LIKE" | IS | "IN" | NOT + "IN";
            betweenExpr.Rule = expression + notOpt + "BETWEEN" + expression + "AND" + expression;
            notOpt.Rule      = Empty | NOT;

            //funCall covers some psedo-operators and special forms like ANY(...), SOME(...), ALL(...), EXISTS(...), IN(...)
            funCall.Rule     = Id + "(" + funArgsList + ")" + (Empty | AS + typeName);
            funArgsOpt.Rule  = Empty | selectStmt | expression | string_literal | Id + "=" + term;
            funArgsList.Rule = MakePlusRule(funArgsList, comma, funArgsOpt);
            inStmt.Rule      = expression + "IN" + "(" + exprList + ")";

            //Operators
            RegisterOperators(10, "*", "/", "%");
            RegisterOperators(9, "+", "-");
            RegisterOperators(8, "=", ">", "<", ">=", "<=", "<>", "!=", "!<", "!>", "LIKE", "IN");
            RegisterOperators(7, "^", "&", "|");
            RegisterOperators(6, NOT);
            RegisterOperators(5, "AND");
            RegisterOperators(4, "OR");

            MarkPunctuation(",", "(", ")");
            MarkPunctuation(asOpt, semiOpt);
            //Note: we cannot declare binOp as transient because it includes operators "NOT LIKE", "NOT IN" consisting of two tokens.
            // Transient non-terminals cannot have more than one non-punctuation child nodes.
            // Instead, we set flag InheritPrecedence on binOp , so that it inherits precedence value from it's children, and this precedence is used
            // in conflict resolution when binOp node is sitting on the stack
            base.MarkTransient(stmt, term, asOpt, aliasOpt, stmtLine, expression, unOp, tuple);
            binOp.SetFlag(TermFlags.InheritPrecedence);
        } //constructor
Beispiel #15
0
 private BnfTerm CreateSqlExtIdentifier(string name)
 {
     IdentifierTerminal identifierTerminal = new IdentifierTerminal(name, null, "@");
     StringLiteral stringLiteral = new StringLiteral(name + "_quoted");
     stringLiteral.AddStartEnd("[", "]", StringOptions.NoEscapes);
     stringLiteral.AddStartEnd("\"", StringOptions.NoEscapes);
     stringLiteral.SetOutputTerminal(this, (Terminal)identifierTerminal);
     return identifierTerminal;
 }
Beispiel #16
0
        public RubyGrammar()
        {
            #region Terminals
              //String Literals with single and double-quote start/end symbols
              StringLiteral STRING = new StringLiteral("STRING", TermOptions.SpecialIgnoreCase);
              STRING.AddStartEnd("\"", ScanFlags.None);
              STRING.AddStartEnd("'", ScanFlags.None);
              Terminal HereDoc = new Terminal("HereDoc"); //-- implement me!
              Terminal RegExLiteral = new Terminal("RegExLiteral"); //-- implement me!
              IdentifierTerminal IDENTIFIER = new IdentifierTerminal("identifier", "_!?", "_$@");
              //                                                name     extraChars      extraFirstChars
              IDENTIFIER.DisplayName = "variable";
              //we need to isolate reserved words to avoid ambiguities in grammar
              IDENTIFIER.AddKeywords("do", "end", "def", "class",
                                       "if", "case", "return", "yield", "while", "until");  //and some others...
              Terminal Number = new NumberLiteral("Number");
              Terminal Comment = new CommentTerminal("Comment", "#", "\n");
              NonGrammarTerminals.Add(Comment); //add comment explicitly to this list as it is not reachable from Root

              //some conveniency variables
              Terminal Pipe = Symbol("|");
              Terminal dot = Symbol(".");
              Terminal comma = Symbol(",");
              #endregion

              #region NonTerminals
              //NT variables names match element names in original grammar
              NonTerminal PROGRAM = new NonTerminal("PROGRAM");
              NonTerminal COMPSTMT = new NonTerminal("COMPSTMT");
              NonTerminal STMT = new NonTerminal("STMT");
              NonTerminal BLOCK = new NonTerminal("BLOCK");
              NonTerminal EXPR = new NonTerminal("EXPR");
              //NonTerminal CALL = new NonTerminal("CALL");
              NonTerminal COMMAND = new NonTerminal("COMMAND");
              NonTerminal FUNCTION = new NonTerminal("FUNCTION");
              NonTerminal ARG = EXPR;// new NonTerminal("ARG");
              NonTerminal PRIMARY = new NonTerminal("PRIMARY", "operand");
              NonTerminal WHEN_ARGS = new NonTerminal("WHEN_ARGS");
              NonTerminal THEN = new NonTerminal("THEN");
              NonTerminal BLOCK_BEGIN = new NonTerminal("BLOCK_BEGIN");
              NonTerminal BLOCK_END = new NonTerminal("BLOCK_END");
              NonTerminal BLOCK_VAR = new NonTerminal("BLOCK_VAR");
            //      NonTerminal MLHS_ITEM = new NonTerminal("MLHS_ITEM");
              NonTerminal LHS = new NonTerminal("LHS");
              NonTerminal MRHS = new NonTerminal("MRHS");
            //      NonTerminal MLHS = MRHS; // new NonTerminal("MLHS");
              NonTerminal CALL_ARGS = new NonTerminal("CALL_ARGS");
              NonTerminal CALL_ARGS_P = new NonTerminal("CALL_ARGS_P");
              NonTerminal AMP_ARG = new NonTerminal("AMP_ARG");
              NonTerminal STAR_ARG = new NonTerminal("STAR_ARG");
              NonTerminal ARGS = new NonTerminal("ARGS");
              NonTerminal ARGDECL = new NonTerminal("ARGDECL");
              NonTerminal ARGLIST = new NonTerminal("ARGLIST");
            //      NonTerminal SINGLETON = new NonTerminal("SINGLETON");
              NonTerminal ASSOCS = new NonTerminal("ASSOCS");
              NonTerminal ASSOC = new NonTerminal("ASSOC");
            //      NonTerminal VARIABLE = new NonTerminal("VARIABLE");  --merged into IDENTIFIER
              NonTerminal LITERAL = new NonTerminal("LITERAL", "value");
              NonTerminal TERM = new NonTerminal("TERM");
              NonTerminal DO = new NonTerminal("DO");
            //      NonTerminal VARNAME = new NonTerminal("VARNAME");   // note 1
              NonTerminal GLOBAL = new NonTerminal("GLOBAL");
              NonTerminal RETURN_STMT = new NonTerminal("RETURN_STMT");
              NonTerminal YIELD_STMT = new NonTerminal("YIELD_STMT");
              NonTerminal DEFINEDQ_STMT = new NonTerminal("DEFINEDQ_STMT");
              NonTerminal FUNCTION_STMT = new NonTerminal("FUNCTION_STMT");
              NonTerminal IF_STMT = new NonTerminal("IF_STMT");
              NonTerminal UNLESS_STMT = new NonTerminal("UNLESS_STMT");
              NonTerminal WHILE_STMT = new NonTerminal("WHILE_STMT");
              NonTerminal UNTIL_STMT = new NonTerminal("UNTIL_STMT");
              NonTerminal CASE_STMT = new NonTerminal("CASE_STMT");
              NonTerminal FOR_STMT = new NonTerminal("FOR_STMT");
              NonTerminal BLOCK_STMT = new NonTerminal("BLOCK_STMT");
              NonTerminal CLASS_DEF = new NonTerminal("CLASS_DEF");
              NonTerminal BASE_REF = new NonTerminal("BASE_REF");
              NonTerminal MODULE = new NonTerminal("MODULE_STMT");
              NonTerminal DEFFUNC_STMT = new NonTerminal("DEFFUNC_STMT");
              NonTerminal DEFSING_STMT = new NonTerminal("DEFSING_STMT");
              NonTerminal SINGLETON = new NonTerminal("SINGLETON");
              NonTerminal END = new NonTerminal("end");

              NonTerminal SYMBOL = new NonTerminal("SYMBOL");
              //Not in original grammar
              NonTerminal FNAME = new NonTerminal("FNAME");
              BLOCK_BEGIN.Rule = Symbol("do") | "{";
              BLOCK_END.Rule = Symbol("end") | "}";
              NonTerminal OPERATION = new NonTerminal("OPERATION");
              //      Terminal VARNAME = IDENTIFIER;
              NonTerminal AUG_ASGN = new NonTerminal("AUG_ASGN");
              NonTerminal BINOP = new NonTerminal("BINOP", "operator");
              NonTerminal UNOP = new NonTerminal("UNOP");
              NonTerminal DELIM = new NonTerminal("DELIM");

              #endregion

              #region Rules
              //Set grammar root
              this.Root = PROGRAM;

              //PROGRAM         : COMPSTMT
              PROGRAM.Rule = COMPSTMT; // +Grammar.Eof;
              //COMPSTMT        : STMT (TERM EXPR)* [TERM]
              COMPSTMT.Rule = NewLine.Q() + STMT.Plus(TERM) + TERM.Q();

              /* STMT   : CALL do [`|' [BLOCK_VAR] `|'] COMPSTMT end
                | undef FNAME
                | alias FNAME FNAME
                | STMT if EXPR
                | STMT while EXPR
                | STMT unless EXPR
                | STMT until EXPR
                | `BEGIN' `{' COMPSTMT `}'
                | `"end"' `{' COMPSTMT `}'
                | LHS `=' COMMAND [do [`|' [BLOCK_VAR] `|'] COMPSTMT end]
                | EXPR    */
              STMT.Rule =     FUNCTION
                      | COMMAND + BLOCK.Q()
                      | "undef" + FNAME | "alias" + FNAME + FNAME
                      | STMT + (Symbol("if")|"while"|"unless"|"until") + EXPR
                      | Symbol("BEGIN") + "{" + COMPSTMT + "}"
                     // | Symbol("end") + BLOCK_BEGIN + COMPSTMT + BLOCK_END    // don't quite get it
                   //   | LHS + "=" + COMMAND + BLOCK.Q()
                      | LHS + "=" + EXPR  //changed this
                      | LHS + AUG_ASGN + EXPR
                      | EXPR;
              BLOCK.Rule = "do" + WithQ(Pipe + BLOCK_VAR.Q() + Pipe) + COMPSTMT + "end";

              /* EXPR   : MLHS `=' MRHS
                | return CALL_ARGS
                | yield CALL_ARGS
                | EXPR and EXPR
                | EXPR or EXPR
                | not EXPR
                | COMMAND
                | `!' COMMAND
                | ARG   */
              //this one is completely changed, for better or worse...
              EXPR.Rule = //  MRHS + "=" + EXPR | //changed to EXPR
                     //  LHS + "=" + EXPR  //changed this
                    // | LHS + AUG_ASGN + EXPR
                      EXPR + BINOP + EXPR
                     | UNOP + EXPR
                     //| "(" + EXPR + ")"
                      | EXPR + "?" + EXPR + ":" + EXPR   //added this to cover "?" operator
                     | "defined?" + ARG
                     | PRIMARY
                      ;
              ARG = EXPR;
              // CALL   : FUNCTION | COMMAND
             // CALL.Expression = FUNCTION | COMMAND; //expression embedded directly into STMT

              /* COMMAND         : OPERATION CALL_ARGS
                | PRIMARY `.' OPERATION CALL_ARGS
                | PRIMARY `::' OPERATION CALL_ARGS
                | super CALL_ARGS   */
              COMMAND.Rule =  OPERATION + CALL_ARGS
                         | PRIMARY + DELIM + OPERATION + CALL_ARGS
                         | "super" + CALL_ARGS;
              OPERATION.Rule =  IDENTIFIER;
              DELIM.Rule = dot | "::";

              /* FUNCTION   : OPERATION [`(' [CALL_ARGS] `)']
                | PRIMARY `.' OPERATION `(' [CALL_ARGS] `)'
                | PRIMARY `::' OPERATION `(' [CALL_ARGS] `)'
                | PRIMARY `.' OPERATION
                | PRIMARY `::' OPERATION
                | super `(' [CALL_ARGS] `)'
                | super  */
              FUNCTION.Rule = OPERATION + CALL_ARGS_P
                   | PRIMARY + DELIM + OPERATION + CALL_ARGS_P.Q()
                   | "super" + CALL_ARGS_P;
              CALL_ARGS_P.Rule = "(" + CALL_ARGS.Q() + ")";
              /*  ARG   : LHS `=' ARG
                | LHS OP_ASGN ARG
                | ARG `..' ARG
                | ARG `...' ARG
                | ARG `+' ARG
                | ARG `-' ARG
                | ARG `*' ARG
                | ARG `/' ARG
                | ARG `%' ARG
                | ARG `**' ARG
                | `+' ARG
                | `-' ARG
                | ARG `|' ARG
                | ARG `^' ARG
                | ARG `&' ARG
                | ARG `<=>' ARG
                | ARG `>' ARG
                | ARG `>=' ARG
                | ARG `<' ARG
                | ARG `<=' ARG
                | ARG `==' ARG
                | ARG `===' ARG
                | ARG `!=' ARG
                | ARG `=~' ARG
                | ARG `!~' ARG
                | `!' ARG
                | `~' ARG
                | ARG `<<' ARG
                | ARG `>>' ARG
                | ARG `&&' ARG
                | ARG `||' ARG
                | defined? ARG
                | PRIMARY   */

            /*  ARG.Expression = LHS + "=" + EXPR  //changed this
                     | LHS + AUG_ASGN + EXPR
                     | ARG + BINOP + ARG  //moved to EXPR
                     | UNOP + ARG
                     | "defined?" + ARG
                     | PRIMARY
                     ; */
              AUG_ASGN.Rule = Symbol("+=") | "-=" | "*=" | "/=" | "%=" | "**=" | "&=" | "|=" | "^=" | "<<=" | ">>=" | "&&=" | "||=";

              BINOP.Rule = Symbol("..") | "..." | "+" | "-" | "*" | "/" | "%" | "**" | "|" | "^" | "&"
                         | "<=>" | ">" | ">=" | "<" | "<=" | "==" | "===" | "!=" | "=~" | "!~" | "<<" | ">>" | "&&" | "||"
                         | "and" | "or";  //added these two here
              UNOP.Rule = Symbol("+") | "-" | "!" | "~";
               /*PRIMARY:    */
              /*        `(' COMPSTMT `)'
                | LITERAL
                | VARIABLE
                | PRIMARY `::' IDENTIFIER
                | `::' IDENTIFIER
                | PRIMARY `[' [ARGS] `]'
                | `[' [ARGS [`,']] `]'
                | `{' [(ARGS|ASSOCS) [`,']] `}'
                | return [`(' [CALL_ARGS] `)']
                | yield [`(' [CALL_ARGS] `)']
                | defined? `(' ARG `)'
                | FUNCTION
                | FUNCTION `{' [`|' [BLOCK_VAR] `|'] COMPSTMT `}'
                | if EXPR THEN
                  COMPSTMT
                  (elsif EXPR THEN COMPSTMT)*
                  [else COMPSTMT]
                  end
                | unless EXPR THEN
                  COMPSTMT
                  [else COMPSTMT]
                  end
                | while EXPR DO COMPSTMT end
                | until EXPR DO COMPSTMT end
                | case COMPSTMT
                  (when WHEN_ARGS THEN COMPSTMT)+
                  [else COMPSTMT]
                  end
                | for BLOCK_VAR in EXPR DO
                  COMPSTMT
                  end
                | begin
                  COMPSTMT
                  [rescue [ARGS] DO COMPSTMT]+
                  [else COMPSTMT]
                  [ensure COMPSTMT]
                  end
                | class IDENTIFIER [`<' IDENTIFIER]
                  COMPSTMT
                  end"=
                | module IDENTIFIER
                  COMPSTMT
                  end
                | def FNAME ARGDECL
                  COMPSTMT
                  end
                | def SINGLETON (`.'|`::') FNAME ARGDECL
                  COMPSTMT
                  end */
              PRIMARY.Rule =
               // "(" + COMPSTMT + ")" |   //-- removed this to fix ambiguity
            LITERAL
            | LHS  //note 1.
            | "[" + WithQ(ARGS + comma.Q()) + "]"
            | "{" + WithQ( (ARGS|ASSOC) + comma.Q() ) + "}"
            | RETURN_STMT | YIELD_STMT | DEFINEDQ_STMT | FUNCTION_STMT | IF_STMT | UNLESS_STMT | WHILE_STMT
            | UNTIL_STMT | CASE_STMT | FOR_STMT | BLOCK_STMT | CLASS_DEF | MODULE | DEFFUNC_STMT | DEFSING_STMT;
             // LHS.Expression = VARIABLE | PRIMARY + "[" + ARGS.Q() + "]" | PRIMARY + "." + IDENTIFIER;

              RETURN_STMT.Rule = "return" + EXPR;// CALL_ARGS_P.Q(); //changed this
              YIELD_STMT.Rule = "yield" + CALL_ARGS_P.Q();
              DEFINEDQ_STMT.Rule = Symbol("defined?") + "(" + ARG + ")";
              FUNCTION_STMT.Rule = FUNCTION + WithQ("{" + WithQ("|" + BLOCK_VAR.Q() + "|") + COMPSTMT + "}");
              IF_STMT.Rule = "if" + EXPR + THEN + COMPSTMT + WithStar("elsif" + EXPR + THEN + COMPSTMT) + WithQ("else" + COMPSTMT) + END;
              UNLESS_STMT.Rule = "unless" + EXPR + THEN + COMPSTMT + "else" + COMPSTMT + END;
              WHILE_STMT.Rule = "while" + EXPR + DO + COMPSTMT + END;
              UNTIL_STMT.Rule = "until" + EXPR + DO + COMPSTMT + END;
              CASE_STMT.Rule = "case" + COMPSTMT + WithPlus("when" + WHEN_ARGS + THEN + COMPSTMT)
                                 + WithQ("else" + COMPSTMT) + END;
              FOR_STMT.Rule = "for" + BLOCK_VAR + "in" + EXPR + DO + COMPSTMT + END;
              BLOCK_STMT.Rule = "begin" + COMPSTMT + WithPlus("rescue" + ARGS.Q() + DO + COMPSTMT)
                                 + WithQ("else" + COMPSTMT) + WithQ("ensure" + COMPSTMT) + END;
              CLASS_DEF.Rule = "class" + IDENTIFIER + BASE_REF.Q() + COMPSTMT + END;
              BASE_REF.Rule = "<" + IDENTIFIER;
              MODULE.Rule = "module" + IDENTIFIER + COMPSTMT + END;
              DEFFUNC_STMT.Rule = "def" + FNAME + ARGDECL.Q() + COMPSTMT + END;
              DEFSING_STMT.Rule = "def" + SINGLETON + (dot|"::") + FNAME + ARGDECL.Q() + COMPSTMT + END;
              END.Rule = "end"; // TERM.Q() + "end";
              //  SINGLETON : VARIABLE | `(' EXPR `)'
              SINGLETON.Rule = IDENTIFIER | "(" + EXPR + ")";
              // WHEN_ARGS       : ARGS [`,' `*' ARG]  | `*' ARG
              WHEN_ARGS.Rule = ARGS + WithQ(comma + "*" + ARG) | "*" + ARG;
              // THEN   : TERM | then | TERM then
              THEN.Rule = TERM | "then" | TERM + "then";
              // DO     : TERM | do | TERM do
              DO.Rule = TERM | "do" | TERM + "do";
              //  BLOCK_VAR       : LHS | MLHS
            //      BLOCK_VAR.Expression = LHS | MLHS;   // -- ambiguous, changing to the following:
              BLOCK_VAR.Rule = IDENTIFIER | "(" + IDENTIFIER.Plus(comma) + ")";
              //  MLHS  : MLHS_ITEM `,' [MLHS_ITEM (`,' MLHS_ITEM)*] [`*' [LHS]]  | `*' LHS
            //      MLHS.Expression = MLHS_ITEM.Plus(",") + WithQ("*" + LHS.Q()) | "*" + LHS;  --ambiguous
              //MLHS.Expression = PRIMARY.Plus(",") + WithQ("*" + LHS.Q()) | "*" + LHS;
              //  MLHS_ITEM  : LHS | '(' MLHS ')'
              //MLHS_ITEM.Expression = LHS | "(" + MLHS + ")";  //--ambiguous!!! using PRIMARY
              //MLHS_ITEM = PRIMARY;

              /* LHS    : VARIABLE
                | PRIMARY `[' [ARGS] `]'
                | PRIMARY `.' IDENTIFIER  */
             // LHS.Expression = IDENTIFIER | PRIMARY + "[" + ARGS.Q() + "]" | PRIMARY + dot + IDENTIFIER;
              LHS.Rule = OPERATION
                     | PRIMARY + "[" + ARGS.Q() + "]"
                     | "(" + EXPR + ")";
              //   MRHS : ARGS [`,' `*' ARG] | `*' ARG
              MRHS.Rule = ARGS + WithQ(comma + "*" + ARG) | "*" + ARG;
              /* CALL_ARGS   : ARGS
                | ARGS [`,' ASSOCS] [`,' `*' ARG] [`,' `&' ARG]
                | ASSOCS [`,' `*' ARG] [`,' `&' ARG]
                | `*' ARG [`,' `&' ARG]
                | `&' ARG
                | COMMAND    */
              CALL_ARGS.Rule = // ARGS |  //removed this - it is covered by next expression
                             ARGS + WithQ(comma + ASSOCS) + STAR_ARG.Q() + AMP_ARG.Q()
                           | ASSOCS + STAR_ARG.Q() + AMP_ARG.Q()
                           | "*" + ARG + AMP_ARG.Q()
                           | "&" + ARG
                           | COMMAND;
              AMP_ARG.Rule = comma + "&" + ARG;
              STAR_ARG.Rule = comma + "*" + ARG;
              //  ARGS            : ARG (`,' ARG)*
              ARGS.Rule = ARG.Plus(comma);
              // ARGDECL         : `(' ARGLIST `)'  | ARGLIST TERM
              ARGDECL.Rule = "(" + ARGLIST + ")" | ARGLIST + TERM;
              /*   ARGLIST         : IDENTIFIER(`,'IDENTIFIER)*[`,'`*'[IDENTIFIER]][`,'`&'IDENTIFIER]
                | `*'IDENTIFIER[`,'`&'IDENTIFIER]
                | [`&'IDENTIFIER]    */
              ARGLIST.Rule = IDENTIFIER.Plus(comma) + WithQ(comma + "*" + IDENTIFIER.Q()) + WithQ(comma + "&" + IDENTIFIER)
                           | "*" + IDENTIFIER + WithQ(comma + "&" + IDENTIFIER)
                           | "&" + IDENTIFIER;
              // ASSOCS : ASSOC (`,' ASSOC)*
              ASSOCS.Rule = ASSOC.Plus(comma);
              //ASSOC : ARG `=>' ARG
              ASSOC.Rule = ARG + "=>" + ARG;
              //  VARIABLE : VARNAME | nil | self    -- variable is merged into IDENTIFIER
              //VARIABLE.Expression = IDENTIFIER | "nil" | "self";
              // LITERAL : numeric | SYMBOL | STRING | STRING2 | HERE_DOC | REGEXP
              LITERAL.Rule = Number | SYMBOL | STRING | HereDoc | RegExLiteral;
              SYMBOL.Rule = Symbol(":") + IDENTIFIER; // (FNAME | VARNAME); //note 1.
              /*  FNAME           : IDENTIFIER | `..' | `|' | `^' | `&'
                | `<=>' | `==' | `===' | `=~'
                | `>' | `>=' | `<' | `<='
                | `+' | `-' | `*' | `/' | `%' | `**'
                | `<<' | `>>' | `~'
                | `+@' | `-@' | `[]' | `[]='  */
              FNAME.Rule = IDENTIFIER | ".." | "|" | "^" | "&" | "<=>" | "==" | "===" | "=~"
                | ">" | ">=" | "<" | "<="  | "+" | "-" | "*" | "/" | "%" | "**"
                | "<<" | ">>" | "~" | "+@" | "-@" | "[]" | "[]=";
              // TERM : `;' | `\n'
              TERM.Rule = NewLine | ";";  //NewLine is produced by token filter
              #endregion

              //error handling
              EXPR.ErrorRule = SyntaxError;
              DEFFUNC_STMT.ErrorRule = "def" + SyntaxError + COMPSTMT + END;

              #region misc: Operators, TokenFilters, etc
              //Register operators - not sure if precedence is assigned correctly
              RegisterOperators(100, Associativity.Right, "**");
              RegisterOperators( 90, "<<", ">>");
              RegisterOperators( 80, "*", "/", "%");
              RegisterOperators( 70, "+", "-");
              RegisterOperators( 60, "&", "&&", "and");
              RegisterOperators( 50, "|", "||", "or", "^");
              RegisterOperators( 40, ">", ">=", "<", "<=", "?");
              RegisterOperators( 30, "<=>" , "==" , "===" , "!=" , "=~" , "!~");
              RegisterOperators( 20, "..", "...");

              RegisterPunctuation("(", ")", "," );

              CodeOutlineFilter filter = new CodeOutlineFilter(false);
              TokenFilters.Add(filter);
              #endregion
        }
		public ReportingLanguage():base(false)
		{
			// 1. Terminals

			var numberLiteral = TerminalFactory.CreateCSharpNumber("Number");
			
			var boolean = new ConstantTerminal("Boolean");
            boolean.Add("true", true);
            boolean.Add("false", false);
            boolean.Priority = 10;
            
            
            var nil = new ConstantTerminal("Null");
            nil.Add("null", null);
            nil.Add("nothing", null);
            nil.Priority = 10;
            
			var identifier = new IdentifierTerminal("Identifier");
         
			var stringLiteral = new StringLiteral("String","'",StringFlags.AllowsDoubledQuote);
			stringLiteral.AddStartEnd("\"",StringFlags.AllowsAllEscapes);
			
			Terminal dot = Symbol(".", "dot");
            Terminal less = Symbol("<");
            Terminal greater = Symbol(">");
            Terminal LCb = Symbol("(");
            Terminal RCb = Symbol(")");
            Terminal RFb = Symbol("}");
            Terminal LFb = Symbol("{");
            Terminal comma = Symbol(",");
//            Terminal LSb = Symbol("[");
//            Terminal RSb = Symbol("]");
              var exclamationMark = Symbol("!");
              
             Terminal and = Symbol("and");
            and.Priority = 10;

            Terminal or = Symbol("or");
            or.Priority = 10;
            
			var UserSection = Symbol("User");
			var GlobalSection = Symbol("Globals");
			var ParameterSection = Symbol("Parameters");
			var FieldsSection = Symbol("Fields");
			
			// 2. Non-terminals
			
			var FieldRef = new NonTerminal("FieldRef");
			var userSectionStmt = new NonTerminal("UserSectionStmt");
			var globalSectionStmt = new NonTerminal("GlobalSectionStmt");
			var parameterSectionStmt = new NonTerminal("ParameterSectionStmt");
			var fieldsSectionStmt = new NonTerminal("FieldsSectionStmt");
			
			var QualifiedName = new NonTerminal("QualifiedName");
			var FunctionExpression = new NonTerminal("FunctionExpression");
			
			var Condition = new NonTerminal("Condition");
            var Conditional = new NonTerminal("IfThen");  
			  
			var Expr = new NonTerminal("Expr");
			 
			var BinOp = new NonTerminal("BinOp");
			var LUnOp = new NonTerminal("LUnOp");
			 
			 
			var ExprList = new NonTerminal("ExprList");
			var BinExpr = new NonTerminal("BinExpr", typeof(BinExprNode));	
				
			var ProgramLine = new NonTerminal("ProgramLine");
			var Program = new NonTerminal("Program", typeof(StatementListNode));
			
			// 3. BNF rules
			 
			#region Reporting
			userSectionStmt.Rule = UserSection + exclamationMark + Symbol("UserId")
				|UserSection + exclamationMark + Symbol("Language");

			globalSectionStmt.Rule = GlobalSection + exclamationMark + Symbol("PageNumber")
				| GlobalSection + exclamationMark + Symbol("TotalPages")
				| GlobalSection + exclamationMark + Symbol("ExecutionTime")
				| GlobalSection + exclamationMark + Symbol("ReportFolder")
				| GlobalSection + exclamationMark + Symbol("ReportName");
			
			
			parameterSectionStmt.Rule = ParameterSection + exclamationMark + identifier;
			
			fieldsSectionStmt.Rule = FieldsSection + exclamationMark + identifier;
			#endregion
			
			Expr.Rule = Symbol("null")
				| boolean
				| nil
				| stringLiteral
				| numberLiteral
				| QualifiedName
				| FunctionExpression
				| LCb + Expr + RCb
				| LFb + QualifiedName + RFb
				| Conditional
				| BinExpr
				//| Expr + BinOp + Expr
				//| LUnOp + Expr
				
				| parameterSectionStmt
				| globalSectionStmt
				| userSectionStmt
				| fieldsSectionStmt;
			
		
			
			ExprList.Rule = MakePlusRule(ExprList, comma, Expr);
			
			BinOp.Rule = Symbol("+") | "-" | "*" | "%" | "^" | "&" | "|" | "/"
                         | "&&" | "||" | "==" | "!=" | greater | less
                         | ">=" | "<=" | "is" | "<>"
                         | "=" //| "+=" | "-="
                         | "." | and | or;
			
			LUnOp.Rule = Symbol("-")
                              | "!";
			   
			FunctionExpression.Rule = QualifiedName + LCb + ExprList.Q() + RCb
				| QualifiedName + LCb + BinExpr + RCb;
			
			
			QualifiedName.Rule = identifier
				| QualifiedName + dot + identifier 
				| parameterSectionStmt + "!" + identifier 
				| "#" + identifier ;
			
			Condition.Rule = LCb + Expr + RCb;

            Conditional.Rule = "if" + Condition + "then" + Expr |
                               "if" + Condition + "then" + Expr + "else" + Expr |
                               "if" + Condition + "then" + Expr + "otherwise" + Expr;
			
			
		
			BinExpr.Rule =  Expr + BinOp + Expr
				| LUnOp + Expr;
			
			ProgramLine.Rule = Expr + NewLine;
			
			Program.Rule = MakeStarRule(Program, ProgramLine);
			this.Root = Program;       // Set grammar root

			#region 5. Operators precedence
            RegisterOperators(1, "is", "=", "==", "!=", "<>", ">", "<", ">=", "<=");
            RegisterOperators(2, "+", "-");
            RegisterOperators(3, "*", "/", "%");
            RegisterOperators(4, Associativity.Right, "^");
            RegisterOperators(5, "|", "||", "or");
            RegisterOperators(6, "&", "&&", "and");
            RegisterOperators(7, "!");

            #endregion

			RegisterPunctuation("(", ")", "[", "]", "{", "}", ",", ";");
			MarkTransient( Expr, BinOp);
			
			//automatically add NewLine before EOF so that our BNF rules work correctly when there's no final line break in source
			this.SetLanguageFlags(LanguageFlags.NewLineBeforeEOF
			                      | LanguageFlags.SupportsInterpreter 
			                      | LanguageFlags.AutoDetectTransient 
			                      |LanguageFlags.CreateAst);
		}
Beispiel #18
0
        public static StringLiteral CreateDasmString(string name, Options options)
        {
            var lit = new StringLiteral(name);

            lit.AddStartEnd("\"", StringOptions.AllowsXEscapes);

            return lit;
        }
Beispiel #19
0
        public static StringLiteral CreateDasmCharacter(string name, Options options)
        {
            var lit = new StringLiteral(name);

            lit.AddStartEnd("'", StringOptions.AllowsXEscapes | StringOptions.IsChar);

            return lit;
        }
        public DslPayoffGrammar()
            : base(false)
        {
            #region 1. Terminals
            var number = new NumberLiteral("number", NumberOptions.NoDotAfterInt)
            {
                //Let's allow big integers (with unlimited number of digits):
                DefaultIntTypes = new [] { TypeCode.Int32, TypeCode.Int64, NumberLiteral.TypeCodeBigInt }
            };
            var comma      = ToTerm(",");
            var identifier = new IdentifierTerminal("identifier");

            var scheduleId = new RegexBasedTerminal("scheduleId", @"[a-z]+date");
            scheduleId.AstConfig.NodeType = typeof(ScheduleIdNode);

            //String literal with embedded expressions  ------------------------------------------------------------------
            var stringLit = new StringLiteral("string", "\"", StringOptions.AllowsAllEscapes | StringOptions.IsTemplate);
            stringLit.AddStartEnd("'", StringOptions.AllowsAllEscapes | StringOptions.IsTemplate);
            stringLit.AstConfig.NodeType = typeof(StringTemplateNode);
            var Expr             = new NonTerminal("Expr");   //declare it here to use in template definition
            var templateSettings = new StringTemplateSettings //by default set to Ruby-style settings
            {
                //this defines how to evaluate expressions inside template
                ExpressionRoot = Expr
            };
            this.SnippetRoots.Add(Expr);
            stringLit.AstConfig.Data = templateSettings;
            //--------------------------------------------------------------------------------------------------------
            #endregion

            #region 2. Non-terminals
            var Term          = new NonTerminal("Term");
            var BinExpr       = new NonTerminal("BinExpr", typeof(BinaryOperationNode));
            var ParExpr       = new NonTerminal("ParExpr");
            var UnExpr        = new NonTerminal("UnExpr", typeof(UnaryOperationNode));
            var TernaryIfExpr = new NonTerminal("TernaryIf", typeof(IfNode));
            var ArgList       = new NonTerminal("ArgList", typeof(ExpressionListNode));
            var FunctionCall  = new NonTerminal("FunctionCall", typeof(FunctionCallNode));
            var MemberAccess  = new NonTerminal("MemberAccess", typeof(MemberAccessNode));

            var UnOp  = new NonTerminal("UnOp");
            var BinOp = new NonTerminal("BinOp", "operator");

            var Fixing = new NonTerminal("Fixing", typeof(FixingNode));
            #endregion

            #region 3. BNF rules
            Expr.Rule    = Term | UnExpr | BinExpr | TernaryIfExpr | Fixing;
            Term.Rule    = number | ParExpr | stringLit | FunctionCall | identifier | MemberAccess;
            ParExpr.Rule = "(" + Expr + ")";
            UnExpr.Rule  = UnOp + Term + ReduceHere();
            UnOp.Rule    = ToTerm("+") | "-" | "!";
            BinExpr.Rule = Expr + BinOp + Expr;
            BinOp.Rule   = ToTerm("+") | "-" | "*" | "/" | "**" | "==" | "<" | "<=" | ">" | ">=" | "!=" | "&&" | "||" | "&" | "|";

            TernaryIfExpr.Rule = Expr + "?" + Expr + ":" + Expr;
            MemberAccess.Rule  = Expr + PreferShiftHere() + "." + identifier;
            ArgList.Rule       = MakeStarRule(ArgList, comma, Expr);
            FunctionCall.Rule  = identifier + PreferShiftHere() + "(" + ArgList + ")";
            FunctionCall.NodeCaptionTemplate = "call #{0}(...)";

            Fixing.Rule = (identifier) + PreferShiftHere() + "@" + scheduleId;
            #endregion

            Root = Expr; // Set grammar root

            #region 4. Operators precedence
            RegisterOperators(10, "?");
            RegisterOperators(15, "&", "&&", "|", "||");
            RegisterOperators(20, "==", "<", "<=", ">", ">=", "!=");
            RegisterOperators(30, "+", "-");
            RegisterOperators(40, "*", "/");
            RegisterOperators(50, Associativity.Right, "**");
            RegisterOperators(60, "!");
            // For precedence to work, we need to take care of one more thing: BinOp.
            //For BinOp which is or-combination of binary operators, we need to either
            // 1) mark it transient or 2) set flag TermFlags.InheritPrecedence
            // We use first option, making it Transient.

            // 5. Punctuation and transient terms
            MarkPunctuation("(", ")", "?", ":", "[", "]");
            RegisterBracePair("(", ")");
            RegisterBracePair("[", "]");
            MarkTransient(Term, Expr, BinOp, UnOp, ParExpr);

            // 7. Syntax error reporting
            MarkNotReported("++", "--");
            AddToNoReportGroup("(", "++", "--");
            AddToNoReportGroup(NewLine);
            AddOperatorReportGroup("operator");
            AddTermsReportGroup("assignment operator", "=", "+=", "-=", "*=", "/=");
            #endregion
            //9. Language flags.
            // Automatically add NewLine before EOF so that our BNF rules work correctly when there's no final line break in source
            LanguageFlags = LanguageFlags.NewLineBeforeEOF | LanguageFlags.CreateAst | LanguageFlags.SupportsBigInt;
        }
Beispiel #21
0
 public static StringLiteral CreateSqlExtIdentifier(String name)
 {
     StringLiteral term = new StringLiteral(name);
       term.AddStartEnd("[", "]", StringFlags.NoEscapes);
       term.AddStartEnd("\"", StringFlags.NoEscapes);
       return term;
 }
 private void MakeSimpleId()
 {
     Identifier = new IdentifierTerminal("simple_id");
     var idStringLiteral = new StringLiteral("simple_id_quoted");
     idStringLiteral.AddStartEnd("\"", StringOptions.NoEscapes);
     idStringLiteral.AstConfig.NodeType = typeof(IdentifierNode);
     idStringLiteral.SetOutputTerminal(this, Identifier);
 }
        private void InitGrammar()
        {
            this.GrammarComments = @"One first go at it.";

            // 1. Non-terminals
            var Expr = new NonTerminal("Expr"); //declare it here to use in template definition
            var Term = new NonTerminal("Term");
            var BinExpr = new NonTerminal("BinExpr", typeof(BinaryOperationNode));
            var ParExpr = new NonTerminal("ParExpr");
            var UnExpr = new NonTerminal("UnExpr", typeof(UnaryOperationNode));
            var TernaryIfExpr = new NonTerminal("TernaryIf", typeof(IfNode));
            var ArgList = new NonTerminal("ArgList", typeof(ExpressionListNode));
            var FunctionCall = new NonTerminal("FunctionCall", typeof(FunctionCallNode));
            var MemberAccess = new NonTerminal("MemberAccess", typeof(MemberAccessNode));
            // var IndexedAccess = new NonTerminal("IndexedAccess", typeof(IndexedAccessNode));
            // var ObjectRef = new NonTerminal("ObjectRef"); // foo, foo.bar or f['bar']
            var UnOp = new NonTerminal("UnOp");
            var BinOp = new NonTerminal("BinOp", "operator");
            var PrefixIncDec = new NonTerminal("PrefixIncDec", typeof(IncDecNode));
            var PostfixIncDec = new NonTerminal("PostfixIncDec", typeof(IncDecNode));
            var IncDecOp = new NonTerminal("IncDecOp");
            var AssignmentStmt = new NonTerminal("AssignmentStmt", typeof(AssignmentNode));
            var AssignmentOp = new NonTerminal("AssignmentOp", "assignment operator");

            // selects
            var SelectStatement = new NonTerminal("SelectStatement", typeof(SelectStatement));
            var SelectRoot = new NonTerminal("SelectRoot", typeof(SelectRoot));
            var SelectRootModel = new NonTerminal("SelectRootModel", typeof(EmptyStatementNode));
            var SelectRootElementList = new NonTerminal("SelectRootElementList", typeof(EmptyStatementNode));
            var SelectRootElement = new NonTerminal("SelectRootElement", typeof(EmptyStatementNode));

            var SelectExpression = new NonTerminal("SelectExpression", typeof(SelectExpressionNode));
            var SelectFunction = new NonTerminal("SelectFunction", typeof(SelectFunctionNode));
            var SelectMemberAccess = new NonTerminal("SelectMemberAccess", typeof(SelectMemberAccessNode));
            var SelectProperty = new NonTerminal("SelectProperty", typeof(SelectPropertyNode));
            var SelectFunctionName = new NonTerminal("SelectFunctionName", typeof(EmptyStatementNode));
            var SelectTerm = new NonTerminal("SelectItem", typeof(EmptyStatementNode));
            var NumberOrEmpty = new NonTerminal("NumberOrEmpty", typeof(EmptyStatementNode));
            var IfcClassProperty = new NonTerminal("IfcClassProperty", typeof(IfcClassPropertyNode));

            // core
            var Statement = new NonTerminal("Statement");
            var Program = new NonTerminal("Program", typeof(StatementListNode));

            // 2. Terminals
            var number = new NumberLiteral("number");
            number.DefaultIntTypes = new TypeCode[] { TypeCode.Int32, TypeCode.Int64 }; //Let's allow big integers (with unlimited number of digits):
            var identifier = new IdentifierTerminal("identifier");
            var comma = ToTerm(",");
            var PositiveIntegerNumber = new NumberLiteral("IntegerNumber", NumberOptions.IntOnly);
            var stringLit = new StringLiteral("string", "\"", StringOptions.AllowsAllEscapes);
            var ElementIdStart = ToTerm("@");
            stringLit.AddStartEnd("'", StringOptions.AllowsAllEscapes);

            /*
             * for embedded expressions:
            var templateSettings = new StringTemplateSettings(); //by default set to Ruby-style settings
            templateSettings.ExpressionRoot = Expr; //this defines how to evaluate expressions inside template
            this.SnippetRoots.Add(Expr);
            stringLit.AstConfig.Data = templateSettings;
             */

            // 3. BNF rules
            Expr.Rule = Term | UnExpr | BinExpr | PrefixIncDec | PostfixIncDec | TernaryIfExpr;
            Term.Rule = number | ParExpr | stringLit | FunctionCall | identifier | IfcClassProperty | MemberAccess; // | IndexedAccess; // | MemberAccess;
            ParExpr.Rule = "(" + Expr | SelectStatement + ")";
            UnExpr.Rule = UnOp + Term + ReduceHere();
            UnOp.Rule = ToTerm("+") | "-" | "!";
            BinExpr.Rule = Expr + BinOp + Expr;
            BinOp.Rule = ToTerm("+") | "-" | "*" | "/" | "**" | "==" | "<" | "<=" | ">" | ">=" | "!=" | "&&" | "||" | "&" | "|";
            PrefixIncDec.Rule = IncDecOp + identifier;
            PostfixIncDec.Rule = identifier + PreferShiftHere() + IncDecOp;
            IncDecOp.Rule = ToTerm("++") | "--";
            TernaryIfExpr.Rule = Expr + "?" + Expr + ":" + Expr;
            MemberAccess.Rule = Expr + PreferShiftHere() + "." + identifier;
            IfcClassProperty.Rule = ElementIdStart + identifier;

            AssignmentStmt.Rule = identifier + AssignmentOp + Expr;
            AssignmentOp.Rule = ToTerm("=") | "+=" | "-=" | "*=" | "/=";
            Statement.Rule = AssignmentStmt | Expr | SelectStatement | Empty;
            ArgList.Rule = MakeStarRule(ArgList, comma, Expr);
            FunctionCall.Rule = Expr + PreferShiftHere() + "(" + ArgList + ")";
            FunctionCall.NodeCaptionTemplate = "call #{0}(...)";

            // select
            var dot = ToTerm("."); dot.SetFlag(TermFlags.IsTransient);
            var select = ToTerm("select"); select.SetFlag(TermFlags.IsTransient);

            SelectStatement.Rule = select + SelectRoot + SelectExpression;

            var ModelAt = ToTerm("@"); ModelAt.SetFlag(TermFlags.IsTransient);
            SelectRoot.Rule = SelectRootModel +  ModelAt + SelectRootElementList;
            SelectRootModel.Rule = identifier | Empty;
            SelectRootElementList.Rule = MakeStarRule(SelectRootElementList, comma, SelectRootElement); // can be empty
            SelectRootElement.Rule = identifier | PositiveIntegerNumber | ToTerm("*");

            SelectExpression.Rule = Empty | SelectMemberAccess;
            SelectMemberAccess.Rule = dot + PreferShiftHere() + SelectTerm + SelectExpression;
            SelectTerm.Rule = SelectFunction | SelectProperty;
            SelectProperty.Rule = identifier;
            SelectFunction.Rule = SelectFunctionName + PreferShiftHere() + ToTerm("(") + ArgList + ")";
            SelectFunctionName.Rule = ToTerm("Where") | "Range" | "Count";

            Program.Rule = MakePlusRule(Program, NewLine, Statement);

            this.Root = Program;       // Set grammar root

            // 4. Operators precedence
            RegisterOperators(10, "?");
            RegisterOperators(15, "&", "&&", "|", "||");
            RegisterOperators(20, "==", "<", "<=", ">", ">=", "!=");
            RegisterOperators(30, "+", "-");
            RegisterOperators(40, "*", "/");
            RegisterOperators(50, Associativity.Right, "**");
            RegisterOperators(60, "!");
            // For precedence to work, we need to take care of one more thing: BinOp.
            //For BinOp which is or-combination of binary operators, we need to either
            // 1) mark it transient or 2) set flag TermFlags.InheritPrecedence
            // We use first option, making it Transient.

            // 5. Punctuation and transient terms
            MarkPunctuation("(", ")", "?", ":"); //, "[", "]");
            RegisterBracePair("(", ")");
            // RegisterBracePair("[", "]");
            MarkTransient(Term, Expr, Statement, BinOp, UnOp, IncDecOp, AssignmentOp, ParExpr); //, ObjectRef);
            MarkTransient(NumberOrEmpty, SelectExpression);
            MarkTransient(SelectTerm);

            // 7. Syntax error reporting
            MarkNotReported("++", "--");
            AddToNoReportGroup("(", "++", "--");
            AddToNoReportGroup(NewLine);
            AddOperatorReportGroup("operator");
            AddTermsReportGroup("assignment operator", "=", "+=", "-=", "*=", "/=");

            //8. Console
            ConsoleTitle = "mah";
            ConsoleGreeting = @"Irony Expression Evaluator";
            ConsolePrompt = "?";
            ConsolePromptMoreInput = "?";

            //9. Language flags.
            // Automatically add NewLine before EOF so that our BNF rules work correctly when there's no final line break in source
            this.LanguageFlags = LanguageFlags.NewLineBeforeEOF | LanguageFlags.SupportsBigInt | LanguageFlags.CreateAst;
        }
Beispiel #24
0
 //Covers simple identifiers like abcd, and also quoted versions: [abc d], "abc d".
 public static IdentifierTerminal CreateSqlExtIdentifier(Grammar grammar, string name) {
   var id = new IdentifierTerminal(name);
   StringLiteral term = new StringLiteral(name + "_qouted");
   term.AddStartEnd("[", "]", StringOptions.NoEscapes);
   term.AddStartEnd("\"", StringOptions.NoEscapes);
   term.SetOutputTerminal(grammar, id); //term will be added to NonGrammarTerminals automatically 
   return id;
 }
Beispiel #25
0
        public ExpressionEvaluatorGrammar() : base(caseSensitive: false)
        {
            this.GrammarComments =
                @"Irony expression evaluator. Case-insensitive. Supports big integers, float data types, variables, assignments,
arithmetic operations, augmented assignments (+=, -=), inc/dec (++,--), strings with embedded expressions; 
bool operations &,&&, |, ||; ternary '?:' operator.";
            // 1. Terminals
            var number = new NumberLiteral("number");

            //Let's allow big integers (with unlimited number of digits):
            number.DefaultIntTypes = new TypeCode[] { TypeCode.Int32, TypeCode.Int64, NumberLiteral.TypeCodeBigInt };
            var identifier = new IdentifierTerminal("identifier");
            var comment    = new CommentTerminal("comment", "#", "\n", "\r");

            //comment must be added to NonGrammarTerminals list; it is not used directly in grammar rules,
            // so we add it to this list to let Scanner know that it is also a valid terminal.
            base.NonGrammarTerminals.Add(comment);
            var comma = ToTerm(",");

            //String literal with embedded expressions  ------------------------------------------------------------------
            var stringLit = new StringLiteral("string", "\"", StringOptions.AllowsAllEscapes | StringOptions.IsTemplate);

            stringLit.AddStartEnd("'", StringOptions.AllowsAllEscapes | StringOptions.IsTemplate);
            stringLit.AstNodeType = typeof(StringTemplateNode);
            var Expr             = new NonTerminal("Expr");      //declare it here to use in template definition
            var templateSettings = new StringTemplateSettings(); //by default set to Ruby-style settings

            templateSettings.ExpressionRoot = Expr;              //this defines how to evaluate expressions inside template
            this.SnippetRoots.Add(Expr);
            stringLit.AstData = templateSettings;
            //--------------------------------------------------------------------------------------------------------

            // 2. Non-terminals
            var Term           = new NonTerminal("Term");
            var BinExpr        = new NonTerminal("BinExpr", typeof(BinaryOperationNode));
            var ParExpr        = new NonTerminal("ParExpr");
            var UnExpr         = new NonTerminal("UnExpr", typeof(UnaryOperationNode));
            var TernaryIfExpr  = new NonTerminal("TernaryIf", typeof(IfNode));
            var ArgList        = new NonTerminal("ArgList", typeof(ExpressionListNode));
            var FunctionCall   = new NonTerminal("FunctionCall", typeof(FunctionCallNode));
            var MemberAccess   = new NonTerminal("MemberAccess", typeof(MemberAccessNode));
            var IndexedAccess  = new NonTerminal("IndexedAccess", typeof(IndexedAccessNode));
            var ObjectRef      = new NonTerminal("ObjectRef"); // foo, foo.bar or f['bar']
            var UnOp           = new NonTerminal("UnOp");
            var BinOp          = new NonTerminal("BinOp", "operator");
            var PrefixIncDec   = new NonTerminal("PrefixIncDec", typeof(IncDecNode));
            var PostfixIncDec  = new NonTerminal("PostfixIncDec", typeof(IncDecNode));
            var IncDecOp       = new NonTerminal("IncDecOp");
            var AssignmentStmt = new NonTerminal("AssignmentStmt", typeof(AssignmentNode));
            var AssignmentOp   = new NonTerminal("AssignmentOp", "assignment operator");
            var Statement      = new NonTerminal("Statement");
            var Program        = new NonTerminal("Program", typeof(StatementListNode));

            // 3. BNF rules
            Expr.Rule           = Term | UnExpr | BinExpr | PrefixIncDec | PostfixIncDec | TernaryIfExpr;
            Term.Rule           = number | ParExpr | stringLit | FunctionCall | identifier | MemberAccess | IndexedAccess;
            ParExpr.Rule        = "(" + Expr + ")";
            UnExpr.Rule         = UnOp + Term + ReduceHere();
            UnOp.Rule           = ToTerm("+") | "-";
            BinExpr.Rule        = Expr + BinOp + Expr;
            BinOp.Rule          = ToTerm("+") | "-" | "*" | "/" | "**" | "==" | "<" | "<=" | ">" | ">=" | "!=" | "&&" | "||" | "&" | "|";
            PrefixIncDec.Rule   = IncDecOp + identifier;
            PostfixIncDec.Rule  = identifier + PreferShiftHere() + IncDecOp;
            IncDecOp.Rule       = ToTerm("++") | "--";
            TernaryIfExpr.Rule  = Expr + "?" + Expr + ":" + Expr;
            MemberAccess.Rule   = Expr + PreferShiftHere() + "." + identifier;
            AssignmentStmt.Rule = ObjectRef + AssignmentOp + Expr;
            AssignmentOp.Rule   = ToTerm("=") | "+=" | "-=" | "*=" | "/=";
            Statement.Rule      = AssignmentStmt | Expr | Empty;
            ArgList.Rule        = MakeStarRule(ArgList, comma, Expr);
            FunctionCall.Rule   = Expr + PreferShiftHere() + "(" + ArgList + ")";
            FunctionCall.NodeCaptionTemplate = "call #{0}(...)";
            ObjectRef.Rule     = identifier | MemberAccess | IndexedAccess;
            IndexedAccess.Rule = Expr + PreferShiftHere() + "[" + Expr + "]";

            Program.Rule = MakePlusRule(Program, NewLine, Statement);

            this.Root = Program; // Set grammar root

            // 4. Operators precedence
            RegisterOperators(10, "?");
            RegisterOperators(15, "&", "&&", "|", "||");
            RegisterOperators(20, "==", "<", "<=", ">", ">=", "!=");
            RegisterOperators(30, "+", "-");
            RegisterOperators(40, "*", "/");
            RegisterOperators(50, Associativity.Right, "**");

            // 5. Punctuation and transient terms
            MarkPunctuation("(", ")", "?", ":", "[", "]");
            RegisterBracePair("(", ")");
            RegisterBracePair("[", "]");
            MarkTransient(Term, Expr, Statement, BinOp, UnOp, IncDecOp, AssignmentOp, ParExpr, ObjectRef);

            // 7. Syntax error reporting
            MarkNotReported("++", "--");
            AddToNoReportGroup("(", "++", "--");
            AddToNoReportGroup(NewLine);
            AddOperatorReportGroup("operator");
            AddTermsReportGroup("assignment operator", "=", "+=", "-=", "*=", "/=");

            //8. Console
            ConsoleTitle    = "Irony Expression Evaluator";
            ConsoleGreeting =
                @"Irony Expression Evaluator 

  Supports variable assignments, arithmetic operators (+, -, *, /),
    augmented assignments (+=, -=, etc), prefix/postfix operators ++,--, string operations. 
  Supports big integer arithmetics, string operations.
  Supports strings with embedded expressions : ""name: #{name}""

Press Ctrl-C to exit the program at any time.
";
            ConsolePrompt          = "?";
            ConsolePromptMoreInput = "?";

            //9. Language flags.
            // Automatically add NewLine before EOF so that our BNF rules work correctly when there's no final line break in source
            this.LanguageFlags = LanguageFlags.NewLineBeforeEOF | LanguageFlags.CreateAst | LanguageFlags.SupportsBigInt;
        }
Beispiel #26
0
        public ODataFilterGrammar()
        {
            //Terminals

            var simpleIdentifier = TerminalFactory.CreateCSharpIdentifier("Identifier");
            var stringLiteral    = new StringLiteral("StringLiteral", "'", StringOptions.NoEscapes | StringOptions.AllowsDoubledQuote);
            var numberLiteral    = new NumberLiteral("NumberLiteral");

            // This impl has problems with .NET 4.5 - so ToTerm methods below were used instead.
            //var constant = new ConstantTerminal("Constant", typeof(Object));
            //constant.Add("true", true);
            //constant.Add("false", false);
            //constant.Add("null", null);
            var trueLiteral  = ToTerm("true", "Constant");
            var falseLiteral = ToTerm("false", "Constant");
            var nullLiteral  = ToTerm("null", "Constant");

            var dateTimeOffsetLiteral = new StringLiteral("DateTimeOffsetLiteral");

            dateTimeOffsetLiteral.AddStartEnd("datetimeoffset'", "'", StringOptions.None);
            var dateTimeLiteral = new StringLiteral("DateTimeLiteral");

            dateTimeLiteral.AddStartEnd("datetime'", "'", StringOptions.None);
            var timeLiteral = new StringLiteral("TimeLiteral");

            timeLiteral.AddStartEnd("time'", "'", StringOptions.None);
            var guidLiteral = new StringLiteral("GuidLiteral");

            guidLiteral.AddStartEnd("guid'", "'", StringOptions.None);

            //NonTerminals
            var baseExpr            = new NonTerminal("BaseExpr");
            var compositeIdentifier = new NonTerminal("CompositeIdentifier");
            var parenExpr           = new NonTerminal("ParenExpr");
            var methodCallExpr      = new NonTerminal("MethodCallExpr");
            var literalExpr         = new NonTerminal("LiteralExpr");
            var subExpr             = new NonTerminal("SubExpr");
            var lambdaExpr          = new NonTerminal("LambdaExpr");
            var lambdaVariable      = new NonTerminal("LambdaVariable");

            var memberExpr   = new NonTerminal("MemberExpr");
            var binaryExpr   = new NonTerminal("BinaryExpr");
            var binaryExprOp = new NonTerminal("BinaryExprOp");
            var unaryExpr    = new NonTerminal("UnaryExpr");
            var unaryExprOp  = new NonTerminal("UnaryExprOp");

            #region Methods
            // bool
            var anyMethodCallExpr         = new NonTerminal("AnyMethodCallExpr");
            var allMethodCallExpr         = new NonTerminal("AllMethodCallExpr");
            var substringOfMethodCallExpr = new NonTerminal("SubstringOfMethodCallExpr");
            var endsWithMethodCallExpr    = new NonTerminal("EndsWithMethodCallExpr");
            var startsWithMethodCallExpr  = new NonTerminal("StartsWithMethodCallExpr");

            // int
            var lengthMethodCallExpr  = new NonTerminal("LengthMethodCallExpr");
            var indexOfMethodCallExpr = new NonTerminal("IndexOfMethodCallExpr");

            // string
            var replaceMethodCallExpr    = new NonTerminal("ReplaceMethodCallExpr");
            var substring1MethodCallExpr = new NonTerminal("Substring1MethodCallExpr");
            var substring2MethodCallExpr = new NonTerminal("Substring2MethodCallExpr");
            var toLowerMethodCallExpr    = new NonTerminal("ToLowerMethodCallExpr");
            var toUpperMethodCallExpr    = new NonTerminal("ToUpperMethodCallExpr");
            var trimMethodCallExpr       = new NonTerminal("TrimMethodCallExpr");
            var concatMethodCallExpr     = new NonTerminal("ConcatMethodCallExpr");

            // date
            var secondMethodCallExpr = new NonTerminal("SecondMethodCallExpr");
            var minuteMethodCallExpr = new NonTerminal("MinuteMethodCallExpr");
            var hourMethodCallExpr   = new NonTerminal("HourMethodCallExpr");
            var dayMethodCallExpr    = new NonTerminal("DayMethodCallExpr");
            var monthMethodCallExpr  = new NonTerminal("MonthMethodCallExpr");
            var yearMethodCallExpr   = new NonTerminal("YearMethodCallExpr");

            // math
            var roundMethodCallExpr   = new NonTerminal("RoundMethodCallExpr");
            var floorMethodCallExpr   = new NonTerminal("FloorMethodCallExpr");
            var ceilingMethodCallExpr = new NonTerminal("CeilingMethodCallExpr");

            // type
            var isOf1MethodCallExpr = new NonTerminal("isOf1MethodCallExpr");
            var isOf2MethodCallExpr = new NonTerminal("isOf2MethodCallExpr");

            #endregion

            Root          = baseExpr;
            baseExpr.Rule = parenExpr
                            | literalExpr
                            | memberExpr
                            | methodCallExpr
                            | binaryExpr
                            | unaryExpr;


            parenExpr.Rule   = "(" + baseExpr + ")";
            literalExpr.Rule = stringLiteral
                               | numberLiteral
                               // | constant
                               | trueLiteral | falseLiteral | nullLiteral
                               | dateTimeLiteral
                               | dateTimeOffsetLiteral
                               | timeLiteral
                               | guidLiteral;

            subExpr.Rule = simpleIdentifier | anyMethodCallExpr | allMethodCallExpr;

            KeyTerm backSlash = ToTerm("/", "backslash");
            compositeIdentifier.Rule = MakePlusRule(compositeIdentifier, backSlash, subExpr);
            memberExpr.Rule          = compositeIdentifier;

            lambdaVariable.Rule = simpleIdentifier + ":";
            lambdaExpr.Rule     = lambdaVariable + baseExpr;

            unaryExpr.Rule   = unaryExprOp + baseExpr;
            unaryExprOp.Rule = (BnfExpression)"not" | "-";

            binaryExpr.Rule   = baseExpr + binaryExprOp + baseExpr;
            binaryExprOp.Rule = (BnfExpression)"eq" | "ne" | "lt" | "le" | "gt" | "ge" | "add" | "sub" | "mul" | "div" | "mod" | "and" | "or";

            methodCallExpr.Rule = anyMethodCallExpr
                                  | allMethodCallExpr
                                  | replaceMethodCallExpr
                                  | substring1MethodCallExpr
                                  | substring2MethodCallExpr
                                  | toLowerMethodCallExpr
                                  | toUpperMethodCallExpr
                                  | trimMethodCallExpr
                                  | concatMethodCallExpr
                                  | lengthMethodCallExpr
                                  | indexOfMethodCallExpr
                                  | secondMethodCallExpr
                                  | minuteMethodCallExpr
                                  | hourMethodCallExpr
                                  | dayMethodCallExpr
                                  | monthMethodCallExpr
                                  | yearMethodCallExpr
                                  | roundMethodCallExpr
                                  | floorMethodCallExpr
                                  | ceilingMethodCallExpr
                                  | isOf1MethodCallExpr
                                  | isOf2MethodCallExpr
                                  | substringOfMethodCallExpr
                                  | startsWithMethodCallExpr
                                  | endsWithMethodCallExpr;

            anyMethodCallExpr.Rule        = (BnfExpression)"any" + "(" + lambdaExpr + ")";
            allMethodCallExpr.Rule        = (BnfExpression)"all" + "(" + lambdaExpr + ")";
            replaceMethodCallExpr.Rule    = (BnfExpression)"replace" + "(" + baseExpr + "," + baseExpr + "," + baseExpr + ")";
            substring1MethodCallExpr.Rule = (BnfExpression)"substring" + "(" + baseExpr + "," + baseExpr + ")";
            substring2MethodCallExpr.Rule = (BnfExpression)"substring" + "(" + baseExpr + "," + baseExpr + "," + baseExpr + ")";
            toLowerMethodCallExpr.Rule    = (BnfExpression)"tolower" + "(" + baseExpr + ")";
            toUpperMethodCallExpr.Rule    = (BnfExpression)"toupper" + "(" + baseExpr + ")";
            trimMethodCallExpr.Rule       = (BnfExpression)"trim" + "(" + baseExpr + ")";
            concatMethodCallExpr.Rule     = (BnfExpression)"concat" + "(" + baseExpr + "," + baseExpr + ")";

            lengthMethodCallExpr.Rule  = (BnfExpression)"length" + "(" + baseExpr + ")";
            indexOfMethodCallExpr.Rule = (BnfExpression)"indexof" + "(" + baseExpr + "," + baseExpr + ")";

            substringOfMethodCallExpr.Rule = (BnfExpression)"substringof" + "(" + baseExpr + "," + baseExpr + ")";
            startsWithMethodCallExpr.Rule  = (BnfExpression)"startswith" + "(" + baseExpr + "," + baseExpr + ")";
            endsWithMethodCallExpr.Rule    = (BnfExpression)"endswith" + "(" + baseExpr + "," + baseExpr + ")";

            secondMethodCallExpr.Rule = (BnfExpression)"second" + "(" + baseExpr + ")";
            minuteMethodCallExpr.Rule = (BnfExpression)"minute" + "(" + baseExpr + ")";
            hourMethodCallExpr.Rule   = (BnfExpression)"hour" + "(" + baseExpr + ")";
            dayMethodCallExpr.Rule    = (BnfExpression)"day" + "(" + baseExpr + ")";
            monthMethodCallExpr.Rule  = (BnfExpression)"month" + "(" + baseExpr + ")";
            yearMethodCallExpr.Rule   = (BnfExpression)"year" + "(" + baseExpr + ")";

            roundMethodCallExpr.Rule   = (BnfExpression)"round" + "(" + baseExpr + ")";
            ceilingMethodCallExpr.Rule = (BnfExpression)"ceiling" + "(" + baseExpr + ")";
            floorMethodCallExpr.Rule   = (BnfExpression)"floor" + "(" + baseExpr + ")";

            isOf1MethodCallExpr.Rule = (BnfExpression)"isof" + "(" + baseExpr + ")";
            isOf2MethodCallExpr.Rule = (BnfExpression)"isof" + "(" + baseExpr + "," + baseExpr + ")";


            RegisterOperators(10, "or");
            RegisterOperators(20, "and");
            RegisterOperators(30, "eq", "ne", "lt", "le", "gt", "ge");
            RegisterOperators(40, "add", "sub", "mul", "div", "mod");
            RegisterOperators(50, "-");

            RegisterBracePair("(", ")");

            MarkPunctuation(",", "(", ")", "/", ":");

            MarkTransient(baseExpr);
            MarkTransient(binaryExprOp);
            MarkTransient(unaryExprOp);

            MarkTransient(parenExpr);
            MarkTransient(methodCallExpr);
            MarkTransient(literalExpr);
            MarkTransient(subExpr);
            MarkTransient(lambdaVariable);
        }
        public QueryLanguageGrammar()
            : base(false)
        {
            var comment = new CommentTerminal("lineComment", "//", "\n", "\r\n");

            NonGrammarTerminals.Add(comment);

            var comma = ToTerm(",");

            //LITERALS
            var integerLiteral = new NumberLiteral("integerLiteral", NumberOptions.IntOnly | NumberOptions.NoDotAfterInt);
            var stringLiteral = new StringLiteral("stringLiteral");
            stringLiteral.AddStartEnd("\"", StringOptions.NoEscapes);
            stringLiteral.AddStartEnd("'", StringOptions.NoEscapes);

            var decimalLiteral = new NumberLiteral("decimalLiteral", NumberOptions.AllowSign | NumberOptions.AllowStartEndDot);
            var parsedLiteral = new NonTerminal("parsedLiteral");
            var parsedLiteralType = CreateNonTerminal("parsedLiteralType", ToTerm("date") | "timeofday" | "datetime");

            parsedLiteral.Rule = parsedLiteralType + stringLiteral;

            var literals = CreateNonTerminal("literals", ToTerm("null") | "true" | "false" | integerLiteral | stringLiteral | decimalLiteral | parsedLiteral);

            //OPERATORS
            var binaryOperator = CreateNonTerminal("binaryOperator", ToTerm("*") | "-" | "+" | "/" | "%"
                | "=" | "!=" | "<>" | "<" | "<=" | ">" | ">=" | "is" | "contains" | "starts with" | "ends with" | "matches" | "like"
                | "and" | "or" | "not");

            //CLAUSES
            var selectClause = new NonTerminal("selectClause");
            var whereClause = new NonTerminal("whereClause");
            var groupByClause = new NonTerminal("groupByClause");
            var pivotClause = new NonTerminal("pivotClause");
            var orderByClause = new NonTerminal("orderByClause");
            var limitClause = new NonTerminal("limitClause");
            var offsetClause = new NonTerminal("offsetClause");
            var labelClause = new NonTerminal("labelClause");
            var formatClause = new NonTerminal("formatClause");
            var optionsClause = new NonTerminal("optionsClause");

            //IDENTIFIERS AND EXPRESSIONS
            var identifier = CreateIdentifier();
            var identifierList = new NonTerminal("identifierList");

            var selectList = new NonTerminal("selectList");
            var expressionList = new NonTerminal("expressionList");
            var expression = new NonTerminal("expression");
            //var unaryExpression = new NonTerminal("unaryExpression");
            var binaryExpression = new NonTerminal("binaryExpression");
            var parExpression = new NonTerminal("parExpression");

            var aggregate = new NonTerminal("aggregate");
            var aggregateName = new NonTerminal("aggregateName");

            //TODO: var scalar

            var term = new NonTerminal("term");

            var orderBy = new NonTerminal("orderBy");
            var orderDirection = new NonTerminal("orderDirection");
            var orderByList = new NonTerminal("orderByList");

            var label = new NonTerminal("label");
            var labelList = new NonTerminal("labelList");

            //ROOT
            var query = new NonTerminal("query");

            this.Root = query;

            query.Rule = selectClause + whereClause + groupByClause + pivotClause + orderByClause + limitClause + offsetClause + labelClause + formatClause + optionsClause;

            selectClause.Rule = Empty | "select" + selectList;
            whereClause.Rule = Empty | "where" + expression;
            groupByClause.Rule = Empty | "group by" + identifierList;
            pivotClause.Rule = Empty | "pivot" + identifierList;
            orderByClause.Rule = Empty | "order by" + orderByList;
            limitClause.Rule = Empty | "limit" + integerLiteral;
            offsetClause.Rule = Empty | "offset" + integerLiteral;
            labelClause.Rule = Empty | "label" + labelList;
            formatClause.Rule = Empty | "format" + labelList;
            optionsClause.Rule = Empty | "options" + "no_format" | "options" + "no_values";

            selectList.Rule = ToTerm("*") | expressionList;
            expressionList.Rule = MakePlusRule(expressionList, comma, expression);
            expression.Rule = term | binaryExpression; // unaryExpression
            term.Rule = literals | parExpression | identifier | aggregate;
            parExpression.Rule = "(" + expression + ")";
            //unaryExpression = unaryOperator + term;
            //unaryOperator.Rule =
            binaryExpression.Rule = expression + binaryOperator + expression;

            aggregate.Rule = aggregateName + "(" + identifier + ")";
            aggregateName.Rule = ToTerm("avg") | "count" | "max" | "min" | "sum";

            identifierList.Rule = MakePlusRule(identifierList, comma, identifier);

            orderBy.Rule = expression + orderDirection;
            orderDirection.Rule = Empty | "asc" | "desc";
            orderByList.Rule = MakePlusRule(orderByList, comma, orderBy);

            label.Rule = expression + stringLiteral;
            labelList.Rule = MakePlusRule(labelList, comma, label);

            //TODO: clean up, differentiate between comparison and calculation, add scalars

            MarkPunctuation(",", "(", ")");
            RegisterBracePair("(", ")");

            RegisterOperators(10, "*", "/", "%");
            RegisterOperators(9, "+", "-");
            RegisterOperators(8, "<", "<=", ">", ">=");
            RegisterOperators(7, "=", "<>", "!=", "is", "contains", "starts with", "ends with", "matches", "like");
            RegisterOperators(6, "and");
            RegisterOperators(5, "not");
            RegisterOperators(4, "or");

            MarkTransient(term, expression, parExpression, binaryOperator, aggregateName, parsedLiteralType, literals, selectList, expressionList, labelList, orderByList, orderDirection);
        }
Beispiel #28
0
        public MiaGrammar()
            : base(caseSensitive: true)
        {
            // 1. Terminals
            var number     = TerminalFactory.CreatePythonNumber("number");
            var identifier = TerminalFactory.CreatePythonIdentifier("identifier");
            //var propertyId = MiaTerminalFactory.CreatePropertyId("property");
            var varId   = MiaTerminalFactory.CreateVariableId("variable");
            var nounId  = MiaTerminalFactory.CreateNounId("noun");
            var verbId  = MiaTerminalFactory.CreateVerbId("verb");
            var comment = new CommentTerminal("comment", "//", "\n", "\r");

            //comment must to be added to NonGrammarTerminals list; it is not used directly in grammar rules,
            // so we add it to this list to let Scanner know that it is also a valid terminal.
            base.NonGrammarTerminals.Add(comment);
            var comma     = ToTerm(",");
            var colon     = ToTerm(":");
            var semicolon = ToTerm(";");
            var snippet1  = new StringLiteral("snippet");
            var snippet2  = new StringLiteral("snippet2");

            //snippet.AddStartEnd("{", "}", StringOptions.None);
            snippet1.AddStartEnd("{", "}", StringOptions.AllowsLineBreak);
            snippet2.AddStartEnd("{%", "%}", StringOptions.AllowsLineBreak);
            // 2. Non-terminals
            var Snippet        = new NonTerminal("Snippet");
            var Constituent    = new NonTerminal("Constituent");
            var Expr           = new NonTerminal("Expr");
            var Term           = new NonTerminal("Term");
            var BinExpr        = new NonTerminal("BinExpr");
            var ParExpr        = new NonTerminal("ParExpr");
            var UnExpr         = new NonTerminal("UnExpr");
            var UnOp           = new NonTerminal("UnOp", "unary-operator");
            var BinOp          = new NonTerminal("BinOp", "binary-operator");
            var ColonExpr      = new NonTerminal("ColonExpr", "ColonExpr");
            var CommaExpr      = new NonTerminal("CommaExpr", "CommaExpr");
            var PropertyExpr   = new NonTerminal("PropertyExpr", "PropertyExpr");
            var AssignmentStmt = new NonTerminal("AssignmentStmt");
            var Stmt           = new NonTerminal("Stmt");
            var ExtStmt        = new NonTerminal("ExtStmt");
            //
            var ReturnStmt = new NonTerminal("return");
            var PassStmt   = new NonTerminal("pass");
            var Block      = new NonTerminal("Block");
            var StmtList   = new NonTerminal("StmtList");
            //
            var DeclBlock    = new NonTerminal("DeclBlock");
            var DeclStmtList = new NonTerminal("DeclStmtList");

            var ParamList    = new NonTerminal("ParamList");
            var ArgList      = new NonTerminal("ArgList");
            var FunctionDef  = new NonTerminal("FunctionDef");
            var FunctionCall = new NonTerminal("FunctionCall");
            //
            var NamespaceDef = new NonTerminal("NamespaceDef");
            var BrainDef     = new NonTerminal("BrainDef");
            var ExpertDef    = new NonTerminal("ExpertDef");
            var MethodDef    = new NonTerminal("MethodDef");
            var PredicateDef = new NonTerminal("PredicateDef");
            var ClauseExpr   = new NonTerminal("ClauseExpr");
            var PropertyList = new NonTerminal("PropertyList");
            //
            var WhereActions   = new NonTerminal("WhereActions");
            var WhereAction    = new NonTerminal("WhereAction");
            var WhereStmt      = new NonTerminal("WhereStmt");
            var IfTrueStmt     = new NonTerminal("IfTrueStmt");
            var IfFalseStmt    = new NonTerminal("IfFalseStmt");
            var IfAllTrueStmt  = new NonTerminal("IfAllTrueStmt");
            var IfAllFalseStmt = new NonTerminal("IfAllFalseStmt");
            //
            var SelectStmt = new NonTerminal("SelectStmt");
            var CaseStmt   = new NonTerminal("CaseStmt");

            // 3. BNF rules
            //Expr.Rule = Term | UnExpr | BinExpr;
            Expr.Rule         = Term | UnExpr | BinExpr | PropertyExpr;
            Constituent.Rule  = number | ParExpr | nounId | varId | Snippet;
            Snippet.Rule      = snippet1 | snippet2;
            Term.Rule         = varId | nounId | ClauseExpr;
            ParExpr.Rule      = "(" + Expr + ")";
            UnExpr.Rule       = UnOp + Expr | UnOp + UnExpr;
            UnOp.Rule         = ToTerm("+") | "-" | "*" | "@" | "/" | "not";
            BinExpr.Rule      = Expr + BinOp + Expr;
            CommaExpr.Rule    = Expr + "," + Eos + Block;
            ColonExpr.Rule    = Expr + ":" + Eos + Block;
            PropertyExpr.Rule = Term + "`" + Term;
            BinOp.Rule        = ToTerm("&&") | "||" | "~=" | "==" | "->";

            AssignmentStmt.Rule = identifier + "=" + Expr;
            Stmt.Rule           = AssignmentStmt | Snippet | Expr | PassStmt | ReturnStmt | Empty;

            ReturnStmt.Rule = "return" + (Expr | Empty);
            PassStmt.Rule   = "pass";
            //Eos is End-Of-Statement token produced by CodeOutlineFilter
            Block.Rule     = Indent + StmtList + Dedent;
            DeclBlock.Rule = Indent + StmtList + Dedent;
            StmtList.Rule  = MakePlusRule(StmtList, ExtStmt);
            ExtStmt.Rule   =
                Stmt + Eos |
                ColonExpr |
                CommaExpr |
                NamespaceDef |
                BrainDef |
                ExpertDef |
                MethodDef |
                WhereStmt |
                PredicateDef |
                SelectStmt |
                CaseStmt;

            ParamList.Rule   = MakeStarRule(ParamList, comma, identifier);
            ArgList.Rule     = MakeStarRule(ArgList, comma, Expr);
            FunctionDef.Rule = "def" + identifier + "(" + ParamList + ")" + colon + Eos + Block;
            FunctionDef.NodeCaptionTemplate = "def #{1}(...)";
            FunctionCall.Rule = identifier + "(" + ArgList + ")";
            FunctionCall.NodeCaptionTemplate = "call #{0}(...)";
            //
            NamespaceDef.Rule = "namespace" + identifier + Eos + Block;
            BrainDef.Rule     = "brain" + identifier + Eos + Block;
            ExpertDef.Rule    = "expert" + identifier + Eos + Block;
            //MethodDef.Rule = "method" + identifier + "(" + (Expr | Empty) + ")" + Eos + Block;
            MethodDef.Rule    = ("method" + identifier + "(" + ArgList + ")" + Eos + Block) | ("method" + identifier + Eos + Block);
            PredicateDef.Rule = "predicate" + identifier + "(" + ParamList + ")" + Eos;
            //
            WhereActions.Rule   = MakePlusRule(WhereActions, WhereAction);
            WhereAction.Rule    = IfTrueStmt | IfFalseStmt | IfAllTrueStmt | IfAllFalseStmt;
            WhereStmt.Rule      = "where" + Eos + Block + WhereActions;
            IfTrueStmt.Rule     = "-->" + Eos + Block;
            IfFalseStmt.Rule    = "~->" + Eos + Block;
            IfAllTrueStmt.Rule  = "==>" + Eos + Block;
            IfAllFalseStmt.Rule = "~=>" + Eos + Block;
            //
            SelectStmt.Rule = "select" + Eos + Block;
            CaseStmt.Rule   = "case" + Snippet + Eos + Block;
            //
            PropertyList.Rule = MakeStarRule(PropertyList, comma, Expr);
            //
            ClauseExpr.Rule = verbId | (Constituent + verbId) | (verbId + Constituent) | (Constituent + verbId + Constituent);
            //
            //
            this.Root = StmtList;       // Set grammar root

            // 4. Token filters - created in a separate method CreateTokenFilters
            //    we need to add continuation symbol to NonGrammarTerminals because it is not used anywhere in grammar
            NonGrammarTerminals.Add(ToTerm(@"\"));

            // 5. Operators precedence
            //RegisterOperators(1, "+", "-");
            //RegisterOperators(2, "*", "/");
            //RegisterOperators(3, Associativity.Right, "**");

            // 6. Miscellaneous: punctuation, braces, transient nodes
            MarkPunctuation("(", ")", ":");
            RegisterBracePair("(", ")");
            //MarkTransient(Term, Expr, Stmt, ExtStmt, UnOp, BinOp, ExtStmt, ParExpr, Block);
            MarkTransient(Term, Expr, Stmt, UnOp, BinOp, ExtStmt, ParExpr, Block, Constituent, Snippet);

            // 7. Error recovery rule
            ExtStmt.ErrorRule     = SyntaxError + Eos;
            FunctionDef.ErrorRule = SyntaxError + Dedent;

            // 8. Syntax error reporting
            AddToNoReportGroup("(");
            AddToNoReportGroup(Eos);
            AddOperatorReportGroup("operator");

            // 9. Initialize console attributes
            ConsoleTitle    = "Mini-Python Console";
            ConsoleGreeting =
                @"Irony Sample Console for mini-Python.
 
   Supports a small sub-set of Python: assignments, arithmetic operators, 
   function declarations with 'def'. Supports big integer arithmetics.
   Supports Python indentation and line-joining rules, including '\' as 
   a line joining symbol. 

Press Ctrl-C to exit the program at any time.
";
            ConsolePrompt          = ">>>";
            ConsolePromptMoreInput = "...";

            // 10. Language flags
            //this.LanguageFlags = LanguageFlags.NewLineBeforeEOF | LanguageFlags.CreateAst | LanguageFlags.SupportsBigInt;
            this.LanguageFlags = LanguageFlags.NewLineBeforeEOF | LanguageFlags.SupportsBigInt;
        }//constructor
 private NonTerminal InitEmbeddedCs(KeyTerm beginSegment, KeyTerm endSegment)
 {
     var regexNonDirective = new RegexBasedTerminal("NonDirectivePrefix", "(?![+=@])") {
                     ErrorAlias = "<#@ can only be declared before any text or embedded code",
                     SkipsWhitespaceAfter = false };
     _embeddedCs = new NonTerminal("embeddedCs");
     var embeddedCsText = new FreeTextLiteral("embeddedCsText", endSegment.Text);
     var stringLit = new StringLiteral("embeddedCsText");
     stringLit.AddStartEnd(beginSegment.Text, endSegment.Text, StringOptions.AllowsLineBreak);
     _embeddedCs.Rule = beginSegment + regexNonDirective + embeddedCsText + endSegment;
     return EmbeddedCs;
 }
        public ReportingLanguage() : base(false)
        {
            // 1. Terminals

            var numberLiteral = TerminalFactory.CreateCSharpNumber("Number");

            var boolean = new ConstantTerminal("Boolean");

            boolean.Add("true", true);
            boolean.Add("false", false);
            boolean.Priority = 10;


            var nil = new ConstantTerminal("Null");

            nil.Add("null", null);
            nil.Add("nothing", null);
            nil.Priority = 10;

            var identifier = new IdentifierTerminal("Identifier");

            var stringLiteral = new StringLiteral("String", "'", StringFlags.AllowsDoubledQuote);

            stringLiteral.AddStartEnd("\"", StringFlags.AllowsAllEscapes);

            Terminal dot     = Symbol(".", "dot");
            Terminal less    = Symbol("<");
            Terminal greater = Symbol(">");
            Terminal LCb     = Symbol("(");
            Terminal RCb     = Symbol(")");
            Terminal RFb     = Symbol("}");
            Terminal LFb     = Symbol("{");
            Terminal comma   = Symbol(",");
//            Terminal LSb = Symbol("[");
//            Terminal RSb = Symbol("]");
            var exclamationMark = Symbol("!");

            Terminal and = Symbol("and");

            and.Priority = 10;

            Terminal or = Symbol("or");

            or.Priority = 10;

            var UserSection      = Symbol("User");
            var GlobalSection    = Symbol("Globals");
            var ParameterSection = Symbol("Parameters");
            var FieldsSection    = Symbol("Fields");

            // 2. Non-terminals

            var FieldRef             = new NonTerminal("FieldRef");
            var userSectionStmt      = new NonTerminal("UserSectionStmt");
            var globalSectionStmt    = new NonTerminal("GlobalSectionStmt");
            var parameterSectionStmt = new NonTerminal("ParameterSectionStmt");
            var fieldsSectionStmt    = new NonTerminal("FieldsSectionStmt");

            var QualifiedName      = new NonTerminal("QualifiedName");
            var FunctionExpression = new NonTerminal("FunctionExpression");

            var Condition   = new NonTerminal("Condition");
            var Conditional = new NonTerminal("IfThen");

            var Expr = new NonTerminal("Expr");

            var BinOp = new NonTerminal("BinOp");
            var LUnOp = new NonTerminal("LUnOp");


            var ExprList = new NonTerminal("ExprList");
            var BinExpr  = new NonTerminal("BinExpr", typeof(BinExprNode));

            var ProgramLine = new NonTerminal("ProgramLine");
            var Program     = new NonTerminal("Program", typeof(StatementListNode));

            // 3. BNF rules

            #region Reporting
            userSectionStmt.Rule = UserSection + exclamationMark + Symbol("UserId")
                                   | UserSection + exclamationMark + Symbol("Language");

            globalSectionStmt.Rule = GlobalSection + exclamationMark + Symbol("PageNumber")
                                     | GlobalSection + exclamationMark + Symbol("TotalPages")
                                     | GlobalSection + exclamationMark + Symbol("ExecutionTime")
                                     | GlobalSection + exclamationMark + Symbol("ReportFolder")
                                     | GlobalSection + exclamationMark + Symbol("ReportName");


            parameterSectionStmt.Rule = ParameterSection + exclamationMark + identifier;

            fieldsSectionStmt.Rule = FieldsSection + exclamationMark + identifier;
            #endregion

            Expr.Rule = Symbol("null")
                        | boolean
                        | nil
                        | stringLiteral
                        | numberLiteral
                        | QualifiedName
                        | FunctionExpression
                        | LCb + Expr + RCb
                        | LFb + QualifiedName + RFb
                        | Conditional
                        | BinExpr
                        //| Expr + BinOp + Expr
                        //| LUnOp + Expr

                        | parameterSectionStmt
                        | globalSectionStmt
                        | userSectionStmt
                        | fieldsSectionStmt;



            ExprList.Rule = MakePlusRule(ExprList, comma, Expr);

            BinOp.Rule = Symbol("+") | "-" | "*" | "%" | "^" | "&" | "|" | "/"
                         | "&&" | "||" | "==" | "!=" | greater | less
                         | ">=" | "<=" | "is" | "<>"
                         | "=" //| "+=" | "-="
                         | "." | and | or;

            LUnOp.Rule = Symbol("-")
                         | "!";

            FunctionExpression.Rule = QualifiedName + LCb + ExprList.Q() + RCb;

            QualifiedName.Rule = identifier
                                 | QualifiedName + dot + identifier
                                 | parameterSectionStmt + "!" + identifier
                                 | "#" + identifier;

            Condition.Rule = LCb + Expr + RCb;

            Conditional.Rule = "if" + Condition + "then" + Expr |
                               "if" + Condition + "then" + Expr + "else" + Expr |
                               "if" + Condition + "then" + Expr + "otherwise" + Expr;



            BinExpr.Rule = Expr + BinOp + Expr
                           | LUnOp + Expr;

            ProgramLine.Rule = Expr + NewLine;

            Program.Rule = MakeStarRule(Program, ProgramLine);
            this.Root    = Program;                // Set grammar root

            #region 5. Operators precedence
            RegisterOperators(1, "is", "=", "==", "!=", "<>", ">", "<", ">=", "<=");
            RegisterOperators(2, "+", "-");
            RegisterOperators(3, "*", "/", "%");
            RegisterOperators(4, Associativity.Right, "^");
            RegisterOperators(5, "|", "||", "or");
            RegisterOperators(6, "&", "&&", "and");
            RegisterOperators(7, "!");

            #endregion

            RegisterPunctuation("(", ")", "[", "]", "{", "}", ",", ";");
            MarkTransient(Expr, BinOp);

            //automatically add NewLine before EOF so that our BNF rules work correctly when there's no final line break in source
            this.SetLanguageFlags(LanguageFlags.NewLineBeforeEOF
                                  | LanguageFlags.SupportsInterpreter
                                  | LanguageFlags.AutoDetectTransient
                                  | LanguageFlags.CreateAst);
        }
        public LabGrammar() : base(false)
        {
            var numberLiteral = new NumberLiteral("number")
            {
                DefaultIntTypes = new TypeCode[1] {
                    TypeCode.Double
                }
            };
            var identifierTerminal = new IdentifierTerminal("identifier");

            NonGrammarTerminals.Add(new CommentTerminal("comment", "#", "\n", "\r"));
            KeyTerm term          = ToTerm(",");
            var     stringLiteral =
                new StringLiteral("string", "\"", StringOptions.AllowsAllEscapes | StringOptions.IsTemplate);

            stringLiteral.AddStartEnd("'", StringOptions.AllowsAllEscapes | StringOptions.IsTemplate);
            stringLiteral.AstConfig.NodeType = typeof(StringTemplateNode);
            var nonTerminal1     = new NonTerminal("Expr");
            var templateSettings = new StringTemplateSettings {
                ExpressionRoot = nonTerminal1
            };

            SnippetRoots.Add(nonTerminal1);
            stringLiteral.AstConfig.Data = templateSettings;
            var nonTerminal2     = new NonTerminal("Term");
            var nonTerminal3     = new NonTerminal("BinExpr", typeof(BinaryOperationNode));
            var nonTerminal4     = new NonTerminal("ParExpr");
            var nonTerminal5     = new NonTerminal("UnExpr", typeof(UnaryOperationNode));
            var nonTerminal6     = new NonTerminal("TernaryIf", typeof(IfNode));
            var listNonTerminal1 = new NonTerminal("ArgList", typeof(ExpressionListNode));
            var nonTerminal7     = new NonTerminal("FunctionCall", typeof(FunctionCallNode));
            var nonTerminal8     = new NonTerminal("MemberAccess", typeof(MemberAccessNode));
            var nonTerminal9     = new NonTerminal("IndexedAccess", typeof(IndexedAccessNode));
            var nonTerminal10    = new NonTerminal("ObjectRef");
            var nonTerminal11    = new NonTerminal("UnOp");
            var nonTerminal12    = new NonTerminal("BinOp", "operator");
            var nonTerminal13    = new NonTerminal("PrefixIncDec", typeof(IncDecNode));
            var nonTerminal14    = new NonTerminal("PostfixIncDec", typeof(IncDecNode));
            var nonTerminal15    = new NonTerminal("IncDecOp");
            var nonTerminal16    = new NonTerminal("AssignmentStmt", typeof(AssignmentNode));
            var nonTerminal17    = new NonTerminal("AssignmentOp", "assignment operator");
            var nonTerminal18    = new NonTerminal("Statement");
            var listNonTerminal2 = new NonTerminal("Program", typeof(StatementListNode));

            nonTerminal1.Rule =
                nonTerminal2 | nonTerminal5 |
                nonTerminal3 | nonTerminal13 |
                nonTerminal14 | nonTerminal6;
            nonTerminal2.Rule =
                numberLiteral | nonTerminal4 |
                stringLiteral | nonTerminal7 |
                identifierTerminal | nonTerminal8 | nonTerminal9;
            nonTerminal4.Rule = "(" + nonTerminal1 + ")";
            nonTerminal5.Rule = nonTerminal11 + nonTerminal2 +
                                ReduceHere();
            nonTerminal11.Rule = ToTerm("+") | "-" | "!";
            nonTerminal3.Rule  = nonTerminal1 + nonTerminal12 + nonTerminal1;
            nonTerminal12.Rule =
                ToTerm("+") |
                "-" | "*" |
                "/" | "**" | "==" | "<" | "<=" |
                ">" | ">=" | "!=" | "&&" | "||" | "&" | "|";
            nonTerminal13.Rule = nonTerminal15 + identifierTerminal;
            nonTerminal14.Rule = identifierTerminal + PreferShiftHere() +
                                 nonTerminal15;
            nonTerminal15.Rule = ToTerm("++") | "--";
            nonTerminal6.Rule  =
                nonTerminal1 + "?" + nonTerminal1 + ":" +
                nonTerminal1;
            nonTerminal8.Rule =
                nonTerminal1 + PreferShiftHere() + "." +
                identifierTerminal;
            nonTerminal16.Rule = nonTerminal10 + nonTerminal17 + nonTerminal1;
            nonTerminal17.Rule = ToTerm("=") | "+=" | "-=" | "*=" |
                                 "/=";
            nonTerminal18.Rule    = nonTerminal16 | nonTerminal1 | Empty;
            listNonTerminal1.Rule = MakeStarRule(listNonTerminal1, term, nonTerminal1);
            nonTerminal7.Rule     =
                nonTerminal1 + PreferShiftHere() + "(" +
                listNonTerminal1 + ")";
            nonTerminal7.NodeCaptionTemplate = "call #{0}(...)";
            nonTerminal10.Rule = identifierTerminal | nonTerminal8 |
                                 nonTerminal9;
            nonTerminal9.Rule =
                nonTerminal1 + PreferShiftHere() + "[" +
                nonTerminal1 + "]";
            listNonTerminal2.Rule =
                MakePlusRule(listNonTerminal2, NewLine, nonTerminal18);
            Root = listNonTerminal2;
            RegisterOperators(10, "?");
            RegisterOperators(15, "&", "&&", "|", "||");
            RegisterOperators(20, "==", "<", "<=", ">", ">=", "!=");
            RegisterOperators(30, "+", "-");
            RegisterOperators(40, "*", "/");
            RegisterOperators(50, Associativity.Right, "**");
            RegisterOperators(60, "!");
            MarkPunctuation("(", ")", "?", ":", "[", "]");
            RegisterBracePair("(", ")");
            RegisterBracePair("[", "]");
            MarkTransient(nonTerminal2, nonTerminal1, nonTerminal18, nonTerminal12, nonTerminal11, nonTerminal15,
                          nonTerminal17, nonTerminal4, nonTerminal10);
            MarkNotReported("++", "--");
            AddToNoReportGroup("(", "++", "--");
            AddToNoReportGroup(NewLine);
            AddOperatorReportGroup("operator");
            AddTermsReportGroup("assignment operator", "=", "+=", "-=", "*=", "/=");

            LanguageFlags = LanguageFlags.NewLineBeforeEOF | LanguageFlags.CreateAst | LanguageFlags.SupportsBigInt;
        }
 IdentifierTerminal CreateIdentifier()
 {
     var identifier = new IdentifierTerminal("identifier");
     var quotedIdentifier = new StringLiteral("identifier_quoted");
     quotedIdentifier.AddStartEnd("`", StringOptions.NoEscapes);
     quotedIdentifier.SetOutputTerminal(this, identifier);
     return identifier;
 }
    public ODataFilterGrammar() {
      //Terminals

      var simpleIdentifier = TerminalFactory.CreateCSharpIdentifier("Identifier");
      var stringLiteral = new StringLiteral("StringLiteral", "'", StringOptions.NoEscapes | StringOptions.AllowsDoubledQuote);
      var numberLiteral = new NumberLiteral("NumberLiteral");
      
      // This impl has problems with .NET 4.5 - so ToTerm methods below were used instead.
      //var constant = new ConstantTerminal("Constant", typeof(Object));
      //constant.Add("true", true);
      //constant.Add("false", false);
      //constant.Add("null", null);
      var trueLiteral = ToTerm("true", "Constant");
      var falseLiteral = ToTerm("false", "Constant");
      var nullLiteral = ToTerm("null", "Constant");

      var dateTimeOffsetLiteral = new StringLiteral("DateTimeOffsetLiteral");
      dateTimeOffsetLiteral.AddStartEnd("datetimeoffset'","'", StringOptions.None);
      var dateTimeLiteral = new StringLiteral("DateTimeLiteral");
      dateTimeLiteral.AddStartEnd("datetime'", "'", StringOptions.None);
      var timeLiteral = new StringLiteral("TimeLiteral");
      timeLiteral.AddStartEnd("time'", "'", StringOptions.None);
      var guidLiteral = new StringLiteral("GuidLiteral");
      guidLiteral.AddStartEnd("guid'", "'", StringOptions.None);

      //NonTerminals
      var baseExpr = new NonTerminal("BaseExpr");
      var compositeIdentifier = new NonTerminal("CompositeIdentifier");
      var parenExpr = new NonTerminal("ParenExpr");
      var methodCallExpr = new NonTerminal("MethodCallExpr"); 
      var literalExpr = new NonTerminal("LiteralExpr");
      var subExpr= new NonTerminal("SubExpr");
      var lambdaExpr = new NonTerminal("LambdaExpr");
      var lambdaVariable = new NonTerminal("LambdaVariable");

      var memberExpr = new NonTerminal("MemberExpr");
      var binaryExpr = new NonTerminal("BinaryExpr"); 
      var binaryExprOp = new NonTerminal("BinaryExprOp");
      var unaryExpr = new NonTerminal("UnaryExpr"); 
      var unaryExprOp = new NonTerminal("UnaryExprOp");      

      #region Methods
      // bool
      var anyMethodCallExpr = new NonTerminal("AnyMethodCallExpr");
      var allMethodCallExpr = new NonTerminal("AllMethodCallExpr");
      var substringOfMethodCallExpr = new NonTerminal("SubstringOfMethodCallExpr"); 
      var endsWithMethodCallExpr = new NonTerminal("EndsWithMethodCallExpr"); 
      var startsWithMethodCallExpr = new NonTerminal("StartsWithMethodCallExpr");

      // int
      var lengthMethodCallExpr = new NonTerminal("LengthMethodCallExpr"); 
      var indexOfMethodCallExpr = new NonTerminal("IndexOfMethodCallExpr"); 

      // string
      var replaceMethodCallExpr = new NonTerminal("ReplaceMethodCallExpr"); 
      var substring1MethodCallExpr = new NonTerminal("Substring1MethodCallExpr"); 
      var substring2MethodCallExpr = new NonTerminal("Substring2MethodCallExpr"); 
      var toLowerMethodCallExpr = new NonTerminal("ToLowerMethodCallExpr"); 
      var toUpperMethodCallExpr = new NonTerminal("ToUpperMethodCallExpr"); 
      var trimMethodCallExpr = new NonTerminal("TrimMethodCallExpr"); 
      var concatMethodCallExpr = new NonTerminal("ConcatMethodCallExpr"); 

      // date
      var secondMethodCallExpr = new NonTerminal("SecondMethodCallExpr"); 
      var minuteMethodCallExpr = new NonTerminal("MinuteMethodCallExpr"); 
      var hourMethodCallExpr = new NonTerminal("HourMethodCallExpr"); 
      var dayMethodCallExpr = new NonTerminal("DayMethodCallExpr"); 
      var monthMethodCallExpr = new NonTerminal("MonthMethodCallExpr"); 
      var yearMethodCallExpr = new NonTerminal("YearMethodCallExpr"); 

      // math
      var roundMethodCallExpr = new NonTerminal("RoundMethodCallExpr"); 
      var floorMethodCallExpr = new NonTerminal("FloorMethodCallExpr"); 
      var ceilingMethodCallExpr = new NonTerminal("CeilingMethodCallExpr"); 

      // type
      var isOf1MethodCallExpr = new NonTerminal("isOf1MethodCallExpr"); 
      var isOf2MethodCallExpr = new NonTerminal("isOf2MethodCallExpr"); 

      #endregion

      Root = baseExpr;
      baseExpr.Rule = parenExpr
                    | literalExpr
                    | memberExpr
                    | methodCallExpr
                    | binaryExpr
                    | unaryExpr;

   
      parenExpr.Rule = "(" + baseExpr + ")";
      literalExpr.Rule = stringLiteral
                        | numberLiteral
                        // | constant
                        | trueLiteral | falseLiteral | nullLiteral
                        | dateTimeLiteral
                        | dateTimeOffsetLiteral
                        | timeLiteral
                        | guidLiteral;

      subExpr.Rule = simpleIdentifier | anyMethodCallExpr | allMethodCallExpr;

      KeyTerm backSlash = ToTerm("/", "backslash");
      compositeIdentifier.Rule = MakePlusRule(compositeIdentifier, backSlash, subExpr);
      memberExpr.Rule =  compositeIdentifier;

      lambdaVariable.Rule = simpleIdentifier + ":";
      lambdaExpr.Rule = lambdaVariable + baseExpr;

      unaryExpr.Rule = unaryExprOp + baseExpr;
      unaryExprOp.Rule = (BnfExpression) "not" | "-";

      binaryExpr.Rule = baseExpr + binaryExprOp + baseExpr;
      binaryExprOp.Rule = (BnfExpression)"eq" | "ne" | "lt" | "le" | "gt" | "ge" | "add" | "sub" | "mul" | "div" | "mod" | "and" | "or";

      methodCallExpr.Rule = anyMethodCallExpr
                          | allMethodCallExpr
                          | replaceMethodCallExpr
                          | substring1MethodCallExpr
                          | substring2MethodCallExpr
                          | toLowerMethodCallExpr
                          | toUpperMethodCallExpr
                          | trimMethodCallExpr
                          | concatMethodCallExpr
                          | lengthMethodCallExpr
                          | indexOfMethodCallExpr
                          | secondMethodCallExpr
                          | minuteMethodCallExpr
                          | hourMethodCallExpr
                          | dayMethodCallExpr
                          | monthMethodCallExpr
                          | yearMethodCallExpr
                          | roundMethodCallExpr
                          | floorMethodCallExpr
                          | ceilingMethodCallExpr
                          | isOf1MethodCallExpr
                          | isOf2MethodCallExpr
                          | substringOfMethodCallExpr
                          | startsWithMethodCallExpr
                          | endsWithMethodCallExpr;

      anyMethodCallExpr.Rule = (BnfExpression) "any" + "(" + lambdaExpr + ")";
      allMethodCallExpr.Rule = (BnfExpression) "all" + "(" + lambdaExpr + ")";
      replaceMethodCallExpr.Rule = (BnfExpression)"replace" + "(" + baseExpr + "," + baseExpr + "," + baseExpr + ")";
      substring1MethodCallExpr.Rule = (BnfExpression)"substring" + "(" + baseExpr + "," + baseExpr + ")";
      substring2MethodCallExpr.Rule = (BnfExpression)"substring" + "(" + baseExpr + "," + baseExpr + "," + baseExpr + ")";
      toLowerMethodCallExpr.Rule = (BnfExpression)"tolower" + "(" + baseExpr + ")";
      toUpperMethodCallExpr.Rule = (BnfExpression)"toupper" + "(" + baseExpr + ")";
      trimMethodCallExpr.Rule = (BnfExpression)"trim" + "(" + baseExpr + ")";
      concatMethodCallExpr.Rule = (BnfExpression)"concat" + "(" + baseExpr + "," + baseExpr + ")";

      lengthMethodCallExpr.Rule = (BnfExpression)"length" + "(" + baseExpr + ")";
      indexOfMethodCallExpr.Rule = (BnfExpression)"indexof" + "(" + baseExpr + "," + baseExpr + ")";

      substringOfMethodCallExpr.Rule = (BnfExpression)"substringof" + "(" + baseExpr + "," + baseExpr + ")";
      startsWithMethodCallExpr.Rule = (BnfExpression)"startswith" + "(" + baseExpr + "," + baseExpr + ")";
      endsWithMethodCallExpr.Rule = (BnfExpression)"endswith" + "(" + baseExpr + "," + baseExpr + ")";

      secondMethodCallExpr.Rule = (BnfExpression)"second" + "(" + baseExpr + ")";
      minuteMethodCallExpr.Rule = (BnfExpression)"minute" + "(" + baseExpr + ")";
      hourMethodCallExpr.Rule = (BnfExpression)"hour" + "(" + baseExpr + ")";
      dayMethodCallExpr.Rule = (BnfExpression)"day" + "(" + baseExpr + ")";
      monthMethodCallExpr.Rule = (BnfExpression)"month" + "(" + baseExpr + ")";
      yearMethodCallExpr.Rule = (BnfExpression)"year" + "(" + baseExpr + ")";

      roundMethodCallExpr.Rule = (BnfExpression)"round" + "(" + baseExpr + ")";
      ceilingMethodCallExpr.Rule = (BnfExpression)"ceiling" + "(" + baseExpr + ")";
      floorMethodCallExpr.Rule = (BnfExpression)"floor" + "(" + baseExpr + ")";

      isOf1MethodCallExpr.Rule = (BnfExpression)"isof" + "(" + baseExpr + ")";
      isOf2MethodCallExpr.Rule = (BnfExpression)"isof" + "(" + baseExpr + "," + baseExpr + ")";

      
      RegisterOperators(10, "or");
      RegisterOperators(20, "and");
      RegisterOperators(30, "eq", "ne", "lt", "le", "gt", "ge");
      RegisterOperators(40, "add", "sub", "mul", "div", "mod");
      RegisterOperators(50, "-");

      RegisterBracePair("(", ")");

      MarkPunctuation(",", "(", ")" , "/", ":");

      MarkTransient(baseExpr);
      MarkTransient(binaryExprOp);
      MarkTransient(unaryExprOp);

      MarkTransient(parenExpr);
      MarkTransient(methodCallExpr);
      MarkTransient(literalExpr);
      MarkTransient(subExpr);
      MarkTransient(lambdaVariable);

    }