Exemple #1
0
        public BackOGrammar_old() : base(false)
        {
            var lineComment = new CommentTerminal("line_comment", "--", "\n", "\r\n");

            NonGrammarTerminals.Add(lineComment);

            var number         = new NumberLiteral("number");
            var string_literal = new StringLiteral("string", "'", StringOptions.AllowsDoubledQuote);
            var Id_simple      = TerminalFactory.CreateSqlExtIdentifier(this, "id_simple");        //covers normal identifiers (abc) and quoted id's ([abc d], "abc d")
            var comma          = ToTerm(",");
            var dot            = ToTerm(".");
            var CREATE         = ToTerm("CREATE");
            var NULL           = ToTerm("NULL");
            var NOT            = ToTerm("NOT");
            //var ADD = ToTerm("ADD");
            //var COLUMN = ToTerm("COLUMN");
            var UPDATE = ToTerm("UPDATE");
            var SET    = ToTerm("SET");
            var DELETE = ToTerm("DELETE");
            var SELECT = ToTerm("SELECT");
            var FROM   = ToTerm("FROM");
            var COUNT  = ToTerm("COUNT");
            var JOIN   = ToTerm("JOIN");
            //var BY = ToTerm("BY");
        }
Exemple #2
0
        public ExpressionEvaluatorGrammar()
            : base(false)
        { //false means case insensitive
            //Non-Terminal Node
            var program        = new NonTerminal("program", typeof(ProgramNode));
            var expression     = new NonTerminal("expression", typeof(ExpressionNode));
            var binaryOperator = new NonTerminal("binaryOperator", typeof(BinaryOperatorNode));


            //Identifier for Number and Variable
            var number = TerminalFactory.CreateCSharpNumber("number");

            number.AstConfig.NodeType = typeof(MyNumber);

            var Id        = new NonTerminal("Id");
            var Id_simple = TerminalFactory.CreateSqlExtIdentifier(this, "id_simple");

            Id.AstConfig.NodeType = typeof(MyVariable);

            var stringLiteral = new StringLiteral("string", "\'", StringOptions.None);


            Id.Rule = MakePlusRule(Id, Id_simple);

            this.Root = program;
            //Expression
            program.Rule = expression;

            expression.Rule = number | Id | stringLiteral
                              | expression + binaryOperator + expression
                              | "(" + expression + ")";


            binaryOperator.Rule = ToTerm("+") | "-" | "*" | "/" | "%"                                       //arithmetic
                                  | "&" | "|" | "^"                                                         //bit
                                  | "=" | ">" | "<" | ">=" | "<=" | "<>" | "!=" | "!<" | "!>"               // comparator
                                  | "AND" | "OR" | "CONTAINS" | ToTerm("NOT") + "CONTAINS" | ToTerm("NOT"); //others

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


            this.LanguageFlags = LanguageFlags.CreateAst;

            this.MarkPunctuation("(", ")");
        }
        public SqlGrammar() : base(false)
        {
            var comment     = new CommentTerminal("comment", "/*", "*/");
            var lineComment = new CommentTerminal("line_comment", "--", "\n", "\r\n");

            NonGrammarTerminals.Add(comment);
            NonGrammarTerminals.Add(lineComment);
            var number         = new NumberLiteral("number");
            var string_literal = new StringLiteral("string", "'", StringOptions.AllowsDoubledQuote);
            var Id_simple      = TerminalFactory.CreateSqlExtIdentifier(this, "id_simple"); //covers normal identifiers (abc) and quoted id's ([abc d], "abc d")
            var comma          = ToTerm(",");
            var dot            = ToTerm(".");
            var CREATE         = ToTerm("CREATE");
            var NULL           = ToTerm("NULL");
            var NOT            = ToTerm("NOT");
            var ON             = ToTerm("ON");
            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 TRUE           = ToTerm("TRUE");
            var FALSE          = ToTerm("FALSE");

            //Non-terminals
            var Id                        = new NonTerminal("Id");
            var statement                 = new NonTerminal("stmt");
            var selectStatement           = new NonTerminal("selectStatement");
            var idlist                    = new NonTerminal("idlist");
            var aliaslist                 = new NonTerminal("aliaslist");
            var aliasItem                 = new NonTerminal("aliasItem");
            var orderList                 = new NonTerminal("orderList");
            var orderMember               = new NonTerminal("orderMember");
            var orderDirOptional          = new NonTerminal("orderDirOpt");
            var whereClauseOptional       = new NonTerminal("whereClauseOpt");
            var expression                = new NonTerminal("expression");
            var expressionList            = new NonTerminal("exprList");
            var optionalSelectRestriction = new NonTerminal("optionalSelectRestriction");
            var selectorList              = new NonTerminal("selList");
            var fromClauseOpt             = new NonTerminal("fromClauseOpt");
            var groupClauseOpt            = new NonTerminal("groupClauseOpt");
            var havingClauseOpt           = new NonTerminal("havingClauseOpt");
            var orderClauseOpt            = new NonTerminal("orderClauseOpt");
            var limitClauseOpt            = new NonTerminal("limitClauseOpt");
            var offsetClauseOpt           = new NonTerminal("offsetClauseOpt");
            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 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 inExpr                    = new NonTerminal("inExpr");
            var parSelectStatement        = new NonTerminal("parSelectStmt");
            var notOpt                    = new NonTerminal("notOpt");
            var funCall                   = new NonTerminal("funCall");
            var parameter                 = new NonTerminal("parameter");
            var statementLine             = new NonTerminal("stmtLine");
            var optionalSemicolon         = new NonTerminal("semiOpt");
            var statementList             = new NonTerminal("stmtList");
            var functionArguments         = new NonTerminal("funArgs");
            var inStatement               = new NonTerminal("inStmt");
            var boolean                   = new NonTerminal("boolean");

            //BNF Rules
            this.Root              = statementList;
            statementLine.Rule     = statement + optionalSemicolon;
            optionalSemicolon.Rule = Empty | ";";
            statementList.Rule     = MakePlusRule(statementList, statementLine);

            statement.Rule = selectStatement;

            Id.Rule = MakePlusRule(Id, dot, Id_simple);

            aliasOpt.Rule = Empty | asOpt + Id;
            asOpt.Rule    = Empty | AS;

            idlist.Rule = MakePlusRule(idlist, comma, columnSource);

            aliaslist.Rule = MakePlusRule(aliaslist, comma, aliasItem);
            aliasItem.Rule = Id + aliasOpt;

            //Create Index
            orderList.Rule        = MakePlusRule(orderList, comma, orderMember);
            orderMember.Rule      = Id + orderDirOptional;
            orderDirOptional.Rule = Empty | "ASC" | "DESC";

            //Select stmt
            selectStatement.Rule = SELECT + optionalSelectRestriction + selectorList + fromClauseOpt + whereClauseOptional +
                                   groupClauseOpt + havingClauseOpt + orderClauseOpt + limitClauseOpt + offsetClauseOpt;
            optionalSelectRestriction.Rule = Empty | "ALL" | "DISTINCT";
            selectorList.Rule   = columnItemList | "*";
            columnItemList.Rule = MakePlusRule(columnItemList, comma, columnItem);
            columnItem.Rule     = columnSource + aliasOpt;

            columnSource.Rule        = funCall | Id;
            fromClauseOpt.Rule       = Empty | FROM + aliaslist + joinChainOpt;
            joinChainOpt.Rule        = Empty | joinKindOpt + JOIN + aliaslist + ON + Id + "=" + Id;
            joinKindOpt.Rule         = Empty | "INNER" | "LEFT" | "RIGHT";
            whereClauseOptional.Rule = Empty | "WHERE" + expression;
            groupClauseOpt.Rule      = Empty | "GROUP" + BY + idlist;
            havingClauseOpt.Rule     = Empty | "HAVING" + expression;
            orderClauseOpt.Rule      = Empty | "ORDER" + BY + orderList;
            limitClauseOpt.Rule      = Empty | "LIMIT" + expression;
            offsetClauseOpt.Rule     = Empty | "OFFSET" + expression;

            //Expression
            expressionList.Rule     = MakePlusRule(expressionList, comma, expression);
            expression.Rule         = term | unExpr | binExpr | betweenExpr | parameter;
            term.Rule               = Id | boolean | string_literal | number | funCall | tuple | parSelectStatement | inStatement;
            boolean.Rule            = TRUE | FALSE;
            tuple.Rule              = "(" + expressionList + ")";
            parSelectStatement.Rule = "(" + selectStatement + ")";
            unExpr.Rule             = unOp + term;
            unOp.Rule               = NOT | "+" | "-" | "~";
            binExpr.Rule            = expression + binOp + expression;
            binOp.Rule              = ToTerm("+") | "-" | "*" | "/" | "%" //arithmetic
                                      | "&" | "|" | "^"                   //bit
                                      | "=" | ">" | "<" | ">=" | "<=" | "<>" | "!=" | "!<" | "!>"
                                      | "AND" | "OR" | "LIKE" | NOT + "LIKE" | "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 + "(" + functionArguments + ")";
            functionArguments.Rule = selectStatement | expressionList | "*";
            inStatement.Rule       = expression + "IN" + "(" + expressionList + ")";
            parameter.Rule         = "@" + Id | "@" + Id + ":" + term;

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

            MarkPunctuation(",", "(", ")");
            MarkPunctuation(asOpt, optionalSemicolon);
            //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(statement, term, asOpt, aliasOpt, statementLine, expression, unOp, tuple);
            binOp.SetFlag(TermFlags.InheritPrecedence);
        }
        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         = new NumberLiteral("number");
            var string_literal = new StringLiteral("string", "'", StringOptions.AllowsDoubledQuote);
            var Id_simple      = TerminalFactory.CreateSqlExtIdentifier(this, "id_simple"); //covers normal identifiers (abc) and quoted id's ([abc d], "abc d")
            var comma          = ToTerm(",");
            var dot            = 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 ALTER          = ToTerm("ALTER");
            var ADD            = ToTerm("ADD");
            var COLUMN         = ToTerm("COLUMN");
            var DROP           = ToTerm("DROP");
            var CONSTRAINT     = ToTerm("CONSTRAINT");
            var INDEX          = ToTerm("INDEX");
            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");

            //Non-terminals
            var Id                = new NonTerminal("Id");
            var stmt              = new NonTerminal("stmt");
            var createTableStmt   = new NonTerminal("createTableStmt");
            var createIndexStmt   = new NonTerminal("createIndexStmt");
            var alterStmt         = new NonTerminal("alterStmt");
            var dropTableStmt     = new NonTerminal("dropTableStmt");
            var dropIndexStmt     = new NonTerminal("dropIndexStmt");
            var selectStmt        = new NonTerminal("selectStmt");
            var insertStmt        = new NonTerminal("insertStmt");
            var updateStmt        = new NonTerminal("updateStmt");
            var deleteStmt        = new NonTerminal("deleteStmt");
            var fieldDef          = new NonTerminal("fieldDef");
            var fieldDefList      = new NonTerminal("fieldDefList");
            var nullSpecOpt       = new NonTerminal("nullSpecOpt");
            var typeName          = new NonTerminal("typeName");
            var typeSpec          = new NonTerminal("typeSpec");
            var typeParamsOpt     = new NonTerminal("typeParams");
            var constraintDef     = new NonTerminal("constraintDef");
            var constraintListOpt = new NonTerminal("constraintListOpt");
            var constraintTypeOpt = new NonTerminal("constraintTypeOpt");
            var idlist            = new NonTerminal("idlist");
            var idlistPar         = new NonTerminal("idlistPar");
            var uniqueOpt         = new NonTerminal("uniqueOpt");
            var orderList         = new NonTerminal("orderList");
            var orderMember       = new NonTerminal("orderMember");
            var orderDirOpt       = new NonTerminal("orderDirOpt");
            var withClauseOpt     = new NonTerminal("withClauseOpt");
            var alterCmd          = new NonTerminal("alterCmd");
            var insertData        = new NonTerminal("insertData");
            var intoOpt           = new NonTerminal("intoOpt");
            var assignList        = new NonTerminal("assignList");
            var whereClauseOpt    = new NonTerminal("whereClauseOpt");
            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 inExpr            = new NonTerminal("inExpr");
            var parSelectStmt     = new NonTerminal("parSelectStmt");
            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 funArgs           = new NonTerminal("funArgs");
            var inStmt            = new NonTerminal("inStmt");

            //BNF Rules
            this.Root     = stmtList;
            stmtLine.Rule = stmt + semiOpt;
            semiOpt.Rule  = Empty | ";";
            stmtList.Rule = MakePlusRule(stmtList, stmtLine);

            //ID
            Id.Rule = MakePlusRule(Id, dot, Id_simple);

            stmt.Rule = createTableStmt | createIndexStmt | alterStmt
                        | dropTableStmt | dropIndexStmt
                        | selectStmt | insertStmt | updateStmt | deleteStmt
                        | "GO";
            //Create table
            createTableStmt.Rule = CREATE + TABLE + Id + "(" + fieldDefList + ")" + constraintListOpt;
            fieldDefList.Rule    = MakePlusRule(fieldDefList, comma, fieldDef);
            fieldDef.Rule        = Id + typeName + typeParamsOpt + nullSpecOpt;
            nullSpecOpt.Rule     = NULL | NOT + NULL | Empty;
            typeName.Rule        = ToTerm("BIT") | "DATE" | "TIME" | "TIMESTAMP" | "DECIMAL" | "REAL" | "FLOAT" | "SMALLINT" | "INTEGER"
                                   | "INTERVAL" | "CHARACTER"
                                   // MS SQL types:
                                   | "DATETIME" | "INT" | "DOUBLE" | "CHAR" | "NCHAR" | "VARCHAR" | "NVARCHAR"
                                   | "IMAGE" | "TEXT" | "NTEXT";
            typeParamsOpt.Rule     = "(" + number + ")" | "(" + number + comma + number + ")" | Empty;
            constraintDef.Rule     = CONSTRAINT + Id + constraintTypeOpt;
            constraintListOpt.Rule = MakeStarRule(constraintListOpt, constraintDef);
            constraintTypeOpt.Rule = PRIMARY + KEY + idlistPar | UNIQUE + idlistPar | NOT + NULL + idlistPar
                                     | "Foreign" + KEY + idlistPar + "References" + Id + idlistPar;
            idlistPar.Rule = "(" + idlist + ")";
            idlist.Rule    = MakePlusRule(idlist, comma, Id);

            //Create Index
            createIndexStmt.Rule = CREATE + uniqueOpt + INDEX + Id + ON + Id + orderList + withClauseOpt;
            uniqueOpt.Rule       = Empty | UNIQUE;
            orderList.Rule       = MakePlusRule(orderList, comma, orderMember);
            orderMember.Rule     = Id + orderDirOpt;
            orderDirOpt.Rule     = Empty | "ASC" | "DESC";
            withClauseOpt.Rule   = Empty | WITH + PRIMARY | WITH + "Disallow" + NULL | WITH + "Ignore" + NULL;

            //Alter
            alterStmt.Rule = ALTER + TABLE + Id + alterCmd;
            alterCmd.Rule  = ADD + COLUMN + fieldDefList + constraintListOpt
                             | ADD + constraintDef
                             | DROP + COLUMN + Id
                             | DROP + CONSTRAINT + Id;

            //Drop stmts
            dropTableStmt.Rule = DROP + TABLE + Id;
            dropIndexStmt.Rule = DROP + INDEX + Id + ON + Id;

            //Insert stmt
            insertStmt.Rule = INSERT + intoOpt + Id + idlistPar + insertData;
            insertData.Rule = selectStmt | VALUES + "(" + exprList + ")";
            intoOpt.Rule    = Empty | INTO; //Into is optional in MSSQL

            //Update stmt
            updateStmt.Rule = UPDATE + Id + SET + assignList + whereClauseOpt;
            assignList.Rule = MakePlusRule(assignList, comma, assignment);
            assignment.Rule = Id + "=" + expression;

            //Delete stmt
            deleteStmt.Rule = DELETE + FROM + Id + whereClauseOpt;

            //Select stmt
            selectStmt.Rule = SELECT + selRestrOpt + selList + intoClauseOpt + fromClauseOpt + whereClauseOpt +
                              groupClauseOpt + havingClauseOpt + orderClauseOpt;
            selRestrOpt.Rule     = Empty | "ALL" | "DISTINCT";
            selList.Rule         = columnItemList | "*";
            columnItemList.Rule  = MakePlusRule(columnItemList, comma, columnItem);
            columnItem.Rule      = columnSource + aliasOpt;
            aliasOpt.Rule        = Empty | asOpt + Id;
            asOpt.Rule           = Empty | AS;
            columnSource.Rule    = aggregate | Id;
            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 + idlist + joinChainOpt;
            joinChainOpt.Rule    = Empty | joinKindOpt + JOIN + idlist + ON + Id + "=" + Id;
            joinKindOpt.Rule     = Empty | "INNER" | "LEFT" | "RIGHT";
            whereClauseOpt.Rule  = Empty | "WHERE" + expression;
            groupClauseOpt.Rule  = Empty | "GROUP" + BY + idlist;
            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 | string_literal | number | funCall | tuple | parSelectStmt; // | inStmt;
            tuple.Rule         = "(" + exprList + ")";
            parSelectStmt.Rule = "(" + selectStmt + ")";
            unExpr.Rule        = unOp + term;
            unOp.Rule          = NOT | "+" | "-" | "~";
            binExpr.Rule       = expression + binOp + expression;
            binOp.Rule         = ToTerm("+") | "-" | "*" | "/" | "%" //arithmetic
                                 | "&" | "|" | "^"                   //bit
                                 | "=" | ">" | "<" | ">=" | "<=" | "<>" | "!=" | "!<" | "!>"
                                 | "AND" | "OR" | "LIKE" | NOT + "LIKE" | "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 + "(" + funArgs + ")";
            funArgs.Rule = selectStmt | exprList;
            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
Exemple #5
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
Exemple #6
0
        public NaturalLanguageGrammar()
            : base(false)
        {
            //Terminals
            var cuantos   = ToTerm("cuantos");
            var cuantas   = ToTerm("cuantas");
            var cual      = ToTerm("cual");
            var que       = ToTerm("que");
            var cuando    = ToTerm("cuando");
            var tiene     = ToTerm("tiene");
            var esta      = ToTerm("esta");
            var en        = ToTerm("en");
            var antes     = ToTerm("antes");
            var despues   = ToTerm("despues");
            var de        = ToTerm("de");
            var mas       = ToTerm("mas");
            var menos     = ToTerm("menos");
            var mayor     = ToTerm("mayor");
            var menor     = ToTerm("menor");
            var muestra   = ToTerm("muestra");
            var muestrame = ToTerm("muestrame");
            var todos     = ToTerm("todos");
            var todas     = ToTerm("todas");
            var los       = ToTerm("los");
            var las       = ToTerm("las");
            var el        = ToTerm("el");
            var la        = ToTerm("la");
            var actualiza = ToTerm("actualiza");
            var cambia    = ToTerm("cambia");
            var su        = ToTerm("su");
            var por       = ToTerm("por");
            var plus      = ToTerm("+");
            var minus     = ToTerm("-");
            var mult      = ToTerm("*");
            var entre     = ToTerm("entre");
            var divided   = ToTerm("/");
            var cuanto    = ToTerm("cuanto");
            var es        = ToTerm("es");


            var number         = new NumberLiteral("number");
            var number2        = new NumberLiteral("number2");
            var string_literal = new StringLiteral("string", "'", StringOptions.AllowsDoubledQuote);

            //non terminals
            var cuantosStatement        = new NonTerminal("cuantosStatement");
            var queStatement            = new NonTerminal("queStatement");
            var cuandoStatement         = new NonTerminal("cuandoStatement");
            var cualMayorMenorStatement = new NonTerminal("queMayorMenorStatement");
            var cualMasMenosStatement   = new NonTerminal("queMasMenosStatement");
            var muestraTodoStatement    = new NonTerminal("muestraTodoStatement");
            var muestraUnoStatement     = new NonTerminal("muestraUnoStatement");
            var actualizaStatement      = new NonTerminal("actualizaStatement");
            var operacionesStatement    = new NonTerminal("operacionesStatement");

            var tabla  = new NonTerminal("tabla");
            var tabla2 = new NonTerminal("tabla2");

            var campo            = new NonTerminal("campo");
            var whereCampo       = new NonTerminal("whereCampo");
            var id               = new NonTerminal("id");
            var comando          = new NonTerminal("comando");
            var whereId          = new NonTerminal("whereId");
            var valueSet         = new NonTerminal("valueSet");
            var antesdespues     = new NonTerminal("antesdespues");
            var cuantoscuantas   = new NonTerminal("cuantoscuantas");
            var mayormenor       = new NonTerminal("mayormenor");
            var masmenos         = new NonTerminal("masmenos");
            var todostodas       = new NonTerminal("todostodas");
            var ella             = new NonTerminal("ella");
            var loslas           = new NonTerminal("loslas");
            var muestramuestrame = new NonTerminal("muestramuestrame");
            var suma             = new NonTerminal("suma");
            var resta            = new NonTerminal("resta");
            var multiplicacion   = new NonTerminal("multiplicacion");
            var division         = new NonTerminal("division");

            var Id_simple = TerminalFactory.CreateSqlExtIdentifier(this, "id_simple"); //this covers normal identifiers (abc) and quoted id's ([abc d], "abc d")

            id.Rule               = Id_simple;
            tabla.Rule            = id;
            tabla2.Rule           = id;
            antesdespues.Rule     = (antes | despues);
            cuantoscuantas.Rule   = cuantos | cuantas;
            mayormenor.Rule       = mayor | menor;
            masmenos.Rule         = mas | menos;
            todostodas.Rule       = todos | todas;
            ella.Rule             = el | la;
            loslas.Rule           = los | las;
            muestramuestrame.Rule = muestra | muestrame;
            campo.Rule            = id;
            whereCampo.Rule       = id;
            whereId.Rule          = string_literal | number;
            valueSet.Rule         = string_literal | number;
            suma.Rule             = mas | plus;
            resta.Rule            = menos | minus;
            multiplicacion.Rule   = por | mult;
            division.Rule         = entre | divided;

            //Cuanto pregunta
            cuantosStatement.Rule = (cuantoscuantas + tabla + tiene + tabla2 + whereId) | (en + cuantoscuantas + tabla + esta + tabla2 + whereId);

            //que pregunta
            queStatement.Rule = (que + campo + tiene + tabla + whereId) | (que + tabla + campo + antesdespues + de + whereId);
            //que Mayor menor pregunta
            cualMayorMenorStatement.Rule = cual + tabla + tiene + mayormenor + campo;
            //que menos mas pregunta
            cualMasMenosStatement.Rule = cual + tabla + tiene + masmenos + tabla2;

            //cuando preguta
            cuandoStatement.Rule = cuando + campo + tabla + whereId;

            //muestra Todo pregunta
            muestraTodoStatement.Rule = muestramuestrame + todostodas + loslas + tabla;
            //muestra uno pregunta
            muestraUnoStatement.Rule = muestramuestrame + ella + tabla + whereId;

            //actualiza comando
            actualizaStatement.Rule = actualiza + ella + tabla + whereCampo + cambia + su + campo + por + valueSet;

            //operaciones matematicas
            operacionesStatement.Rule = cuanto + es + number + (multiplicacion | suma | resta | division) + number2;


            comando.Rule = cuantosStatement | queStatement | cuandoStatement | cualMasMenosStatement | cualMayorMenorStatement | muestraTodoStatement | muestraUnoStatement | actualizaStatement | operacionesStatement;
            this.Root    = comando;
        }
        public GraphQueryGrammar() : base(false)
        {
            // comments
            var comment = new CommentTerminal("comment", "/*", "*/");
            //var lineComment = new CommentTerminal("line_comment", "--", "\n", "\r\n");
            var lineComment = new CommentTerminal("line_comment", "//", "\r", "\n", "\u2085", "\u2028", "\u2029");

            NonGrammarTerminals.Add(comment);
            NonGrammarTerminals.Add(lineComment);

            // terminals
            var string_literal = new StringLiteral("string", "'", StringOptions.AllowsDoubledQuote);
            var number         = new NumberLiteral("number", NumberOptions.AllowSign);
            var name           = TerminalFactory.CreateSqlExtIdentifier(this, "name"); //covers normal identifiers (abc) and quoted id's ([abc d], "abc d")
            var comma          = ToTerm(",");
            var dot            = ToTerm(".");
            var SELECT         = ToTerm("SELECT");
            var WHERE          = ToTerm("WHERE");
            var CALCULATE      = ToTerm("CALCULATE");
            var GROUP_BY       = ToTerm("GROUP BY");
            var LAYOUT         = ToTerm("LAYOUT");
            var NOT            = ToTerm("NOT");

            // non terminals
            var identifier         = new NonTerminal("identifier");
            var wildcardIdentifier = new NonTerminal("wildcardIdentifier");
            var statementList      = new NonTerminal("statementList");
            var query              = new NonTerminal("query");
            var selectPropsClause  = new NonTerminal("selectPropsClause");
            var whereClauseOpt     = new NonTerminal("whereClauseOpt");
            var calculateClauseOpt = new NonTerminal("calculateClauseOpt");
            var groupByClauseOpt   = new NonTerminal("groupByClauseOpt");
            var layoutClauseOpt    = new NonTerminal("layoutClauseOpt");
            var metricList         = new NonTerminal("metricList");
            var metric             = new NonTerminal("metric");
            var metricParamsOpt    = new NonTerminal("metricParamsOpt");
            var metricParam        = new NonTerminal("metricParam");
            var metricParamsList   = new NonTerminal("metricParamsList");


            var props                   = new NonTerminal("props");
            var prop                    = new NonTerminal("prop");
            var propAliasOpt            = new NonTerminal("propAliasOpt");
            var expression              = new NonTerminal("expression");
            var parenthesizedExpression = new NonTerminal("parenthesizedExpression");
            var edgeTraversalExpression = new NonTerminal("edgeTraversalExpression");
            var valueExpression         = new NonTerminal("valueExpression");
            var valueOperator           = new NonTerminal("valueOperator");
            var term                    = new NonTerminal("term");
            var binaryExpression        = new NonTerminal("binaryExpression");
            var booleanTerminal         = new NonTerminal("booleanTerminal");
            var binaryOperator          = new NonTerminal("binaryOperator");

            var assignmentExpression = new NonTerminal("assignmentExpression");
            var layoutProps          = new NonTerminal("layoutProps");

            var selectPropExpression          = new NonTerminal("selectPropExpression");
            var parenthesizedSelectExpression = new NonTerminal("parenthesizedSelectExpression");
            var binarySelectExpression        = new NonTerminal("binarySelectExpression");
            var binarySelectOperator          = new NonTerminal("binarySelectOperator");

            this.Root          = statementList;
            statementList.Rule = MakePlusRule(statementList, query);

            // SELECT statement
            query.Rule = SELECT + selectPropsClause + whereClauseOpt + calculateClauseOpt + groupByClauseOpt + layoutClauseOpt;

            // select column list
            selectPropsClause.Rule = props;// | "*";
            prop.Rule         = selectPropExpression + propAliasOpt;
            propAliasOpt.Rule = (Empty | "AS" + identifier);
            props.Rule        = MakePlusRule(props, comma, prop);

            wildcardIdentifier.Rule            = MakePlusRule(wildcardIdentifier, dot, (name | "*"));
            identifier.Rule                    = MakePlusRule(identifier, dot, name);
            selectPropExpression.Rule          = (wildcardIdentifier | binarySelectExpression | parenthesizedSelectExpression | string_literal | number);
            parenthesizedSelectExpression.Rule = ToTerm("(") + selectPropExpression + ")";
            binarySelectExpression.Rule        = selectPropExpression + binarySelectOperator + selectPropExpression;
            binarySelectOperator.Rule          = ToTerm("UNION") | "LIKE";

            // WHERE clause
            whereClauseOpt.Rule = Empty | WHERE + expression;

            expression.Rule = edgeTraversalExpression | valueExpression | parenthesizedExpression | binaryExpression | booleanTerminal;

            edgeTraversalExpression.Rule = (ToTerm("edge") | "in_edge" | "out_edge" | "mutual_edge") + "(" + expression + ")";

            parenthesizedExpression.Rule = ToTerm("(") + expression + ")";

            valueExpression.Rule = term + valueOperator + term;
            valueOperator.Rule   = ToTerm("=") | "!=" | ">" | "<" | ">=" | "<=" | "LIKE" | NOT + "LIKE" | "INTERSECTS";

            term.Rule = identifier | string_literal | number;

            booleanTerminal.Rule = ToTerm("any") | "true" | "false";

            binaryExpression.Rule = expression + binaryOperator + expression;
            binaryOperator.Rule   = ToTerm("AND") | "OR";

            //// CALCULATE clause
            calculateClauseOpt.Rule = Empty | CALCULATE + metricList;

            metricList.Rule       = MakePlusRule(metricList, comma, metric);
            metric.Rule           = identifier + metricParamsOpt;
            metricParamsOpt.Rule  = Empty | "(" + metricParamsList + ")";
            metricParam.Rule      = expression | identifier | string_literal | number;
            metricParamsList.Rule = MakePlusRule(metricParamsList, comma, metricParam);

            //// GROUP BY clause
            groupByClauseOpt.Rule = Empty | GROUP_BY + metricList;

            // LAYOUT clause
            layoutClauseOpt.Rule      = Empty | LAYOUT + layoutProps;
            layoutProps.Rule          = MakePlusRule(assignmentExpression, comma, assignmentExpression);
            assignmentExpression.Rule = term + "=" + term;

            // OPERATORS
            MarkTransient(expression, parenthesizedExpression, binaryOperator, selectPropsClause, term, metricParamsOpt, metricParam, selectPropExpression, parenthesizedSelectExpression,
                          binarySelectOperator);
            MarkPunctuation(",", "(", ")");
            RegisterBracePair("(", ")");

            RegisterOperators(80, "=", ">", "<", ">=", "<=", "<>", "!=", "!<", "!>", "LIKE", "IN");
            RegisterOperators(70, "UNION", "LIKE");
            RegisterOperators(60, NOT);
            RegisterOperators(50, "AND");
            RegisterOperators(40, "OR");

            //AddToNoReportGroup(selectPropsClause, "-");
        }
Exemple #8
0
        public CuLeGrammar()
            : base(false) // Case Insensitive
        {
            //Terminals
            var comment     = new CommentTerminal("comment", "/*", "*/");
            var lineComment = new CommentTerminal("line_comment", "--", "\n", "\r\n");

            var Id_simple = TerminalFactory.CreateSqlExtIdentifier(this, "id_simple"); //covers normal identifiers (abc) and quoted id's ([abc d], "abc d")

            NonGrammarTerminals.Add(comment);
            NonGrammarTerminals.Add(lineComment);

            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 FOREACH = ToTerm("FOREACH");

            var COLUMN = ToTerm("COLUMN");

            var CONSTRAINT = ToTerm("CONSTRAINT");

            var KEY     = ToTerm("KEY");
            var PRIMARY = ToTerm("PRIMARY");

            var dot    = ToTerm(".");
            var comma  = ToTerm(",");
            var number = new NumberLiteral("number");

            //Non-terminals

            var Id              = new NonTerminal("Id");
            var stmt            = new NonTerminal("stmt");
            var createTableStmt = new NonTerminal("createTableStmt");

            var fieldDef          = new NonTerminal("fieldDef");
            var fieldDefList      = new NonTerminal("fieldDefList");
            var typeName          = new NonTerminal("typeName");
            var typeSpec          = new NonTerminal("typeSpec");
            var typeParamsOpt     = new NonTerminal("typeParams");
            var constraintDef     = new NonTerminal("constraintDef");
            var constraintListOpt = new NonTerminal("constraintListOpt");
            var constraintTypeOpt = new NonTerminal("constraintTypeOpt");
            var idlist            = new NonTerminal("idlist");
            var idlistPar         = new NonTerminal("idlistPar");
            var stmtList          = new NonTerminal("stmtList");
            var stmtLine          = new NonTerminal("stmtLine");
            var semiOpt           = new NonTerminal("semiOpt");
            var nullSpecOpt       = new NonTerminal("nullSpecOpt");

            var CuLeRule     = new NonTerminal("CuLeRule");
            var CuLeRuleList = new NonTerminal("CuLeRuleList");
            var CuLeRuleStmt = new NonTerminal("CuLeRuleStmt");
            var CuLeRuleName = new NonTerminal("CuLeRuleName");

            var Set       = new NonTerminal("Set");
            var Attribute = new NonTerminal("Attribute");
            var Tuple     = new NonTerminal("Tuple");
            var TupleList = new NonTerminal("TupleList");
            var Constant  = new NonTerminal("Constant");

            var Quantifier     = new NonTerminal("Quantifier");
            var QuantifierList = new NonTerminal("QuantifierList");
            var QuantifierStmt = new NonTerminal("QuantifierStmt");


            var TransactionParameter            = new NonTerminal("TransactionParameter");
            var TransactionSingleValueParameter = new NonTerminal("TransactionSingleValueParameter");
            // var TransactionMultiValueParameter = new NonTerminal("TransactionMultiValueParameter");
            var TransactionParameterName = new NonTerminal("TransactionParameterName");
            var TransactionParameterType = new NonTerminal("TransactionParameterType");
            var TransactionParameterList = new NonTerminal("TransactionParameterList");

            var TableName = new NonTerminal("TableName");

            var ArgumentName = new NonTerminal("ArgumentName");


            var Multiplicity     = new NonTerminal("Multiplicity");
            var Cardinality_1to1 = new NonTerminal("Cardinality_1to1");
            var Cardinality_1ton = new NonTerminal("Cardinality_1ton");
            var Cardinality_nton = new NonTerminal("Cardinality_nton");

            var SetOperator = new NonTerminal("SetOperator");

            var SetOperator_IN = new NonTerminal("SetOperator_IN");
            var SetOperator_EQ = new NonTerminal("SetOperator_EQ");
            var SetOperator_NE = new NonTerminal("SetOperator_NE");
            var SetOperator_ST = new NonTerminal("SetOperator_ST");
            var SetOperator_GT = new NonTerminal("SetOperator_GT");
            var SetOperator_GE = new NonTerminal("SetOperator_GE");
            var SetOperator_SE = new NonTerminal("SetOperator_SE");

            var WhereClause     = new NonTerminal("WhereClause");
            var WhereExpression = new NonTerminal("WhereExpression");

            var TransactionStmt   = new NonTerminal("TransactionStmt");
            var Changing          = new NonTerminal("Changing");
            var Precondition      = new NonTerminal("Precondition");
            var Input_Restriction = new NonTerminal("Input_Restriction");
            var Result            = new NonTerminal("Result");
            var ChangeObject      = new NonTerminal("ChangeObject");
            var ChangeObjectList  = new NonTerminal("ChangeObjectList");

            var CuLeAssertion     = new NonTerminal("CuLeAssertion");
            var CuLeAssertionList = new NonTerminal("CuLeAssertionList");

            var State = new NonTerminal("State");



            //BNF Rules
            this.Root     = stmtList;
            stmtLine.Rule = stmt + semiOpt;
            semiOpt.Rule  = Empty | ";";
            stmtList.Rule = MakePlusRule(stmtList, stmtLine);

            //ID
            //Id.Rule = MakePlusRule(Id, dot, Id_simple);
            Id.Rule = Id_simple;


            stmt.Rule = createTableStmt | CuLeRuleStmt | TransactionStmt;
            //Create table
            createTableStmt.Rule = CREATE + TABLE + Id + "(" + fieldDefList + ")" + constraintListOpt;
            fieldDefList.Rule    = MakePlusRule(fieldDefList, comma, fieldDef);
            fieldDef.Rule        = Id + typeName + typeParamsOpt + nullSpecOpt;
            nullSpecOpt.Rule     = NULL | NOT + NULL | Empty;
            //typeName.Rule = ToTerm("BIT") | "DATE" | "TIME" | "TIMESTAMP" | "DECIMAL" | "REAL" | "FLOAT" | "SMALLINT" | "INTEGER" | "CHARACTER"

            //    // MS SQL types:
            //                             | "DATETIME" | "INT" | "DOUBLE" | "CHAR" | "NCHAR" | "VARCHAR" | "NVARCHAR"
            //                             | "IMAGE" | "TEXT" | "NTEXT";

            typeName.Rule = ToTerm("DATE") | "TIME" | "DECIMAL" | "FLOAT" | "INTEGER" | "CHARACTER" | "INT" | "DOUBLE" | "CHAR";

            //typeParamsOpt.Rule = "(" + number + ")" | "(" + number + comma + number + ")" | Empty;
            typeParamsOpt.Rule     = "(" + number + ")" | Empty;
            constraintDef.Rule     = CONSTRAINT + Id + constraintTypeOpt;
            constraintListOpt.Rule = MakeStarRule(constraintListOpt, constraintDef);
            constraintTypeOpt.Rule = PRIMARY + KEY + idlistPar | UNIQUE + idlistPar | NOT + NULL + idlistPar
                                     | "FOREIGN" + KEY + idlistPar + "REFERENCES" + Id + idlistPar
                                     | "FOREIGN" + KEY + idlistPar + "REFERENCES" + Id + idlistPar + "Multiplicity" + Multiplicity;
            idlistPar.Rule = "(" + idlist + ")";
            idlist.Rule    = MakePlusRule(idlist, comma, Id);


            Multiplicity.Rule = Cardinality_1to1 | Cardinality_1ton | Cardinality_nton;

            Cardinality_1to1.Rule = "1 to 1";
            Cardinality_1ton.Rule = "1 to many";
            Cardinality_nton.Rule = "many to many";

            WhereClause.Rule = "( WHERE" + WhereExpression + ")";

            WhereExpression.Rule = ArgumentName + SetOperator + Set | "(" + WhereExpression + ")" | WhereExpression + "AND" + WhereExpression | WhereExpression + "OR" + WhereExpression;



            Set.Rule = ArgumentName | "{" + TupleList + "}" | "EMPTYSET" | Set + "." + Attribute | Set + "Union" + Set | Set + "Intersect" + Set | Constant | Set + WhereClause | Set + "Minus" + Set | "<" + State + ">" + Set | "(" + Set + ")";

            Tuple.Rule        = Id;
            TableName.Rule    = Id;
            Attribute.Rule    = Id | "~" + Id;
            ArgumentName.Rule = Id;

            Constant.Rule = "CONSTANT" + typeName + "(" + Id_simple + ")";

            TupleList.Rule = MakePlusRule(TupleList, comma, Tuple);

            Quantifier.Rule = TableName + Tuple;

            QuantifierList.Rule = MakePlusRule(QuantifierList, comma, Quantifier);

            QuantifierStmt.Rule = FOREACH + "(" + QuantifierList + ")";

            SetOperator_IN.Rule = "IN";
            SetOperator_EQ.Rule = "=";
            SetOperator_NE.Rule = "!=";
            SetOperator_ST.Rule = "<";
            SetOperator_GT.Rule = ">";
            SetOperator_GE.Rule = ">=";
            SetOperator_SE.Rule = "<=";


            SetOperator.Rule = SetOperator_IN | SetOperator_EQ | SetOperator_NE | SetOperator_ST | SetOperator_GT | SetOperator_GE | SetOperator_SE;

            CuLeRule.Rule = Set + SetOperator + Set
                            | "(" + CuLeRule + ")"
                            | CuLeRule + "OR" + CuLeRule
                            | CuLeRule + "AND" + CuLeRule
                            | "NOT" + CuLeRule
                            | "IF" + CuLeRule + "THEN" + CuLeRule
                            | "IF" + CuLeRule + "THEN" + CuLeRule + "ELSE" + CuLeRule
                            | CuLeRule + "IFF" + CuLeRule
            ;



            CuLeRuleList.Rule = MakePlusRule(CuLeRuleList, comma, CuLeRule);

            CuLeRuleName.Rule = "Rule" + Id + ":";

            CuLeRuleStmt.Rule = CuLeRuleName + CuLeRuleList | CuLeRuleName + QuantifierStmt + ": (" + CuLeRuleList + ")";

            TransactionStmt.Rule = "Transaction" + Id + "(" + TransactionParameterList + ")" + "{" + Changing + Precondition + Input_Restriction + Result + "}";

            Changing.Rule = "Changing" + "(" + ChangeObjectList + ")" | Empty + Changing | Changing + Empty;

            Precondition.Rule = "Precondition" + CuLeAssertionList | Precondition + Empty | Empty + Precondition;

            Input_Restriction.Rule = "Input_Restriction" + "(" + CuLeRuleList + ")" | "Input_Restriction" + "(" + Empty + ")";

            Result.Rule = "Result" + CuLeAssertionList | Empty + Result | Result + Empty;

            ChangeObjectList.Rule = MakePlusRule(ChangeObjectList, comma, ChangeObject);


            ChangeObject.Rule = Set;

            TransactionParameterName.Rule = Id;

            TransactionParameterType.Rule = Id;

            TransactionSingleValueParameter.Rule = TransactionParameterType + TransactionParameterName;

            TransactionParameter.Rule = TransactionSingleValueParameter;

            TransactionParameterList.Rule = MakePlusRule(TransactionParameterList, comma, TransactionParameter);

            CuLeAssertion.Rule     = "(" + CuLeRuleList + ")" | "(" + QuantifierStmt + ": (" + CuLeRuleList + ")" + ")";
            CuLeAssertionList.Rule = MakePlusRule(CuLeAssertionList, comma, CuLeAssertion);

            State.Rule = Id;
        }
        public SqlGrammar() : base(false)
        {
            var comment     = new CommentTerminal("comment", "/*", "*/");
            var lineComment = new CommentTerminal("line_comment", "--", "\n", "\r\n");

            NonGrammarTerminals.Add(comment);
            NonGrammarTerminals.Add(lineComment);

            var number = new NumberLiteral("number");

            number.AstConfig.NodeType = typeof(NumberNode);
            var stringLiteral = new StringLiteral("string", "'", StringOptions.AllowsDoubledQuote);

            stringLiteral.AstConfig.NodeType = typeof(StringLiteralNode);
            var simpleId = TerminalFactory.CreateSqlExtIdentifier(this, "id_simple");

            simpleId.AstConfig.NodeType = typeof(SimpleIdNode);
            var dateTime = new RegexBasedTerminal("date time", @"\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d.\d\d\d\d\d\d\d");

            dateTime.AstConfig.NodeType = typeof(DateTimeNode);

            var comma             = ToTerm(",");
            var dot               = ToTerm(".");
            var CREATE            = ToTerm("CREATE");
            var SHOW              = ToTerm("SHOW");
            var NULL              = ToTerm("NULL");
            var NOT               = ToTerm("NOT");
            var UNIQUE            = ToTerm("UNIQUE");
            var TABLE             = ToTerm("TABLE");
            var ALTER             = ToTerm("ALTER");
            var ADD               = ToTerm("ADD");
            var COLUMN            = ToTerm("COLUMN");
            var DROP              = ToTerm("DROP");
            var CONSTRAINT        = ToTerm("CONSTRAINT");
            var KEY               = ToTerm("KEY");
            var PRIMARY           = ToTerm("PRIMARY");
            var SELECT            = ToTerm("SELECT");
            var FROM              = ToTerm("FROM");
            var AS                = ToTerm("AS");
            var COUNT             = ToTerm("COUNT");
            var BY                = ToTerm("BY");
            var INTO              = ToTerm("INTO");
            var ON                = ToTerm("ON");
            var BEGIN_TRANSACTION = ToTerm("BEGIN TRANSACTION");
            var COMMIT            = ToTerm("COMMIT");
            var ROLLBACK          = ToTerm("ROLLBACK");
            var SET               = ToTerm("SET");
            var UPDATE            = ToTerm("UPDATE");
            var INSERT            = ToTerm("INSERT");
            var VALUES            = ToTerm("VALUES");
            var STAR              = ToTerm("*");
            var ALL               = ToTerm("ALL");
            var UNION             = ToTerm("UNION");
            var INTERSECT         = ToTerm("INTERSECT");
            var EXCEPT            = ToTerm("EXCEPT");
            var JOIN              = ToTerm("JOIN");
            var DELETE            = ToTerm("DELETE");
            var FOR               = ToTerm("FOR");
            var SYSTEM_TIME       = ToTerm("SYSTEM_TIME");
            var BETWEEN           = ToTerm("BETWEEN");
            var AND               = ToTerm("AND");
            var OF                = ToTerm("OF");
            var TO                = ToTerm("TO");
            var OR                = ToTerm("OR");

            var stmtList   = new NonTerminal("stmtList", typeof(StmtListNode));
            var stmtLine   = new NonTerminal("stmtLine", typeof(StmtLineNode));
            var semiOpt    = new NonTerminal("semiOpt", typeof(SqlNode));
            var sqlCommand = new NonTerminal("sqlSequence", typeof(SqlCommandNode));

            var transaction         = new NonTerminal("transaction", typeof(TransactionNode));
            var transactionList     = new NonTerminal("transactionList", typeof(TransactionListNode));
            var transactionBeginOpt = new NonTerminal("transactionBeginOp", typeof(TransactionBeginOptNode));
            var transactionEndOpt   = new NonTerminal("transactionEndOp", typeof(TransactionEndOptNode));
            var transactionName     = new NonTerminal("transactionName", typeof(TransactionNameNode));

            var id = new NonTerminal("id", typeof(IdNode));
            var createTableStmt = new NonTerminal("CreateTableStmt", typeof(CreateTableCommandNode));
            var showTableStmt   = new NonTerminal("ShowTableStmt", typeof(ShowTableCommandNode));

            var dropTableStmt     = new NonTerminal("DropTableStmt", typeof(DropTableCommandNode));
            var fieldDef          = new NonTerminal("fieldDef", typeof(FieldDefNode));
            var fieldDefList      = new NonTerminal("fieldDefList", typeof(FieldDefListNode));
            var nullSpecOpt       = new NonTerminal("nullSpecOpt", typeof(NullSpectOptNode));
            var typeName          = new NonTerminal("typeName", typeof(TypeNameNode));
            var typeParamsOpt     = new NonTerminal("typeParams", typeof(TypeParamsOptNode));
            var constraintDef     = new NonTerminal("constraintDef", typeof(ConstraintDefNode));
            var constraintListOpt = new NonTerminal("constraintListOpt", typeof(ConstraintListOptNodes));

            var alterStmt = new NonTerminal("AlterStmt", typeof(SqlNode));
            var alterCmd  = new NonTerminal("alterCmd", typeof(SqlNode));
            //var expressionWithoutBrackets = new NonTerminal("expression", typeof(ExpressionNode));
            var asOpt    = new NonTerminal("asOpt", typeof(SqlNode));
            var aliasOpt = new NonTerminal("aliasOpt", typeof(SqlNode));
            var tuple    = new NonTerminal("tuple", typeof(SqlNode));
            var term     = new NonTerminal("term", typeof(TermNode));
            var unOp     = new NonTerminal("unOp", typeof(UnOpNode));
            var binOp    = new NonTerminal("binOp", typeof(BinOpNode));

            var selectStmt          = new NonTerminal("SelectStmt", typeof(SelectCommandNode));
            var expressionList      = new NonTerminal("exprList", typeof(ExpressionListNode));
            var selRestrOpt         = new NonTerminal("selRestrOpt", typeof(SqlNode));
            var selList             = new NonTerminal("selList", typeof(SelListNode));
            var intoClauseOpt       = new NonTerminal("intoClauseOpt", typeof(SqlNode));
            var forClauseOpt        = new NonTerminal("forClauseOpt", typeof(ForClauseOptNode));
            var systemTimeOpt       = new NonTerminal("systemTimeOpt", typeof(SystemTimeOptNode));
            var fromClauseOpt       = new NonTerminal("fromClauseOpt", typeof(FromClauseNode));
            var betweenTimeSelector = new NonTerminal("betweenSelector", typeof(BetweenTimeSelectorNode));
            var fromToTimeSelector  = new NonTerminal("fromToSelector", typeof(FromToTimeSelectorNode));
            var asOfTimeSelector    = new NonTerminal("asOfSelector", typeof(AsOfTimeSelectorNode));
            var groupClauseOpt      = new NonTerminal("groupClauseOpt", typeof(SqlNode));
            var havingClauseOpt     = new NonTerminal("havingClauseOpt", typeof(SqlNode));
            var orderClauseOpt      = new NonTerminal("orderClauseOpt", typeof(SqlNode));
            var whereClauseOpt      = new NonTerminal("whereClauseOpt", typeof(WhereClauseNode));
            var columnItemList      = new NonTerminal("columnItemList", typeof(ColumnItemListNode));
            var columnItem          = new NonTerminal("columnItem", typeof(ColumnItemNode));
            var columnSource        = new NonTerminal("columnSource", typeof(ColumnSourceNode));
            var idList        = new NonTerminal("idList", typeof(IdListNode));
            var idlistPar     = new NonTerminal("idlistPar", typeof(SqlNode));
            var aggregate     = new NonTerminal("aggregate", typeof(SqlNode));
            var aggregateArg  = new NonTerminal("aggregateArg", typeof(SqlNode));
            var aggregateName = new NonTerminal("aggregateName", typeof(SqlNode));

            var orderList   = new NonTerminal("orderList", typeof(SqlNode));
            var orderMember = new NonTerminal("orderMember", typeof(SqlNode));
            var orderDirOpt = new NonTerminal("orderDirOpt", typeof(SqlNode));

            var unExpr        = new NonTerminal("unExpr", typeof(UnExprNode));
            var binExpr       = new NonTerminal("binExpr", typeof(BinExprNode));
            var funCall       = new NonTerminal("funCall", typeof(SqlNode));
            var parSelectStmt = new NonTerminal("parSelectStmt", typeof(SqlNode));
            var betweenExpr   = new NonTerminal("betweenExpr", typeof(SqlNode));
            var notOpt        = new NonTerminal("notOpt", typeof(SqlNode));
            var funArgs       = new NonTerminal("funArgs", typeof(SqlNode));
            var inStmt        = new NonTerminal("inStmt", typeof(SqlNode));

            var updateStmt     = new NonTerminal("UpdateStmt", typeof(UpdateCommandNode));
            var insertStmt     = new NonTerminal("InsertStmt", typeof(InsertCommandNode));
            var intoOpt        = new NonTerminal("intoOpt", typeof(SqlNode));
            var insertDataList = new NonTerminal("insertDataList", typeof(InsertDataListNode));
            var insertObject   = new NonTerminal("insertObject", typeof(InsertObjectNode));
            var insertData     = new NonTerminal("InsertData", typeof(InsertDataNode));
            var assignList     = new NonTerminal("assignList", typeof(AssignmentListNode));
            var assignment     = new NonTerminal("assignment", typeof(AssignmentNode));
            var columnNames    = new NonTerminal("columnNames", typeof(ColumnNamesNode));

            var expression = new NonTerminal("expression", typeof(ExpressionNode));

            var idOperator = new NonTerminal("idOperator", typeof(IdOperatorNode));
            var idLink     = new NonTerminal("idLink", typeof(IdLinkNode));

            var joinChainOpt  = new NonTerminal("joinChainOpt", typeof(JoinChainOptNode));
            var joinKindOpt   = new NonTerminal("joinKindOpt", typeof(JoinKindOptNode));
            var joinStatement = new NonTerminal("joinStatement", typeof(JoinStatementNode));

            var unionChainOpt = new NonTerminal("unionChainOpt", typeof(UnionChainOptNode));
            var unionKindOpt  = new NonTerminal("unionKindOpt", typeof(UnionKindOptNode));

            var intersectChainOpt = new NonTerminal("intersectChainOpt", typeof(InsertCommandNode));
            var exceptChainOpt    = new NonTerminal("exceptChainOpt", typeof(ExceptChainOptNode));

            var deleteStmt = new NonTerminal("DeleteStmt", typeof(DeleteCommandNode));

            //BNF Rules
            Root = transactionList;
            transactionName.Rule     = id | Empty;
            transactionBeginOpt.Rule = BEGIN_TRANSACTION + transactionName;
            transactionEndOpt.Rule   = COMMIT | ROLLBACK;
            transaction.Rule         = transactionBeginOpt + stmtList + transactionEndOpt | stmtLine;
            transactionList.Rule     = MakePlusRule(transactionList, transaction);
            stmtList.Rule            = MakePlusRule(stmtList, stmtLine);
            stmtLine.Rule            = sqlCommand + semiOpt;
            sqlCommand.Rule          = createTableStmt | alterStmt | deleteStmt
                                       | dropTableStmt | showTableStmt | selectStmt | updateStmt | insertStmt;
            semiOpt.Rule = Empty | ";";

            //ID link node
            idOperator.Rule = joinChainOpt | unionChainOpt | intersectChainOpt | exceptChainOpt | selectStmt;
            idLink.Rule     = "(" + idOperator + ")" | id;

            //Join
            joinChainOpt.Rule  = idLink + joinKindOpt + JOIN + idLink + ON + joinStatement;
            joinKindOpt.Rule   = Empty | "INNER" | "LEFT" | "RIGHT" | "Full";
            joinStatement.Rule = expression;//"(" + id + "=" + id + ")" | id + "=" + id;

            //Union
            unionChainOpt.Rule = idLink + UNION + unionKindOpt + idLink;
            unionKindOpt.Rule  = Empty | ALL;

            //Intersect
            intersectChainOpt.Rule = idLink + INTERSECT + idLink;

            //Except
            exceptChainOpt.Rule = idLink + EXCEPT + idLink;

            //ID
            id.Rule        = MakePlusRule(id, dot, simpleId);
            idlistPar.Rule = "(" + idList + ")";
            idList.Rule    = MakePlusRule(idList, comma, id);

            //Create table
            createTableStmt.Rule = CREATE + TABLE + id + "(" + fieldDefList + ")";
            fieldDefList.Rule    = MakePlusRule(fieldDefList, comma, fieldDef);
            fieldDef.Rule        = id + typeName + typeParamsOpt + constraintListOpt + nullSpecOpt;
            nullSpecOpt.Rule     = NULL | NOT + NULL | Empty;
            typeName.Rule        = ToTerm("DATETIME") | "INT" | "DOUBLE" | "CHAR" | "NCHAR" | "VARCHAR" | "NVARCHAR"
                                   | "IMAGE" | "TEXT" | "NTEXT";

            typeParamsOpt.Rule = "(" + number + ")" | "(" + number + comma + number + ")" | Empty;

            constraintListOpt.Rule = MakeStarRule(constraintListOpt, constraintDef);
            constraintDef.Rule     = (UNIQUE) | (PRIMARY + KEY) | ("FOREIGN" + KEY + "REFERENCES" + id) | ("DEFAULT" + stringLiteral) | ("INDEX" + id);

            //Delete stmt
            deleteStmt.Rule = DELETE + FROM + id + whereClauseOpt;

            //Alter
            alterStmt.Rule = ALTER + TABLE + id + alterCmd;
            alterCmd.Rule  = ADD + simpleId + "(" + fieldDefList + ")" | DROP + COLUMN + id
                             | ALTER + COLUMN + id + typeName + (ADD + CONSTRAINT + constraintListOpt
                                                                 | DROP + CONSTRAINT + constraintListOpt);

            //Drop stmts
            dropTableStmt.Rule = DROP + TABLE + id;

            //Show table
            showTableStmt.Rule = SHOW + TABLE + id;

            //Select stmt
            selectStmt.Rule = SELECT + selRestrOpt + selList + intoClauseOpt + fromClauseOpt + forClauseOpt + whereClauseOpt +
                              groupClauseOpt + havingClauseOpt + orderClauseOpt;
            selRestrOpt.Rule         = Empty | ALL | "DISTINCT";
            selList.Rule             = columnItemList | STAR;
            columnItemList.Rule      = MakePlusRule(columnItemList, comma, columnItem);
            columnItem.Rule          = columnSource + aliasOpt;
            aliasOpt.Rule            = Empty | asOpt + id;
            asOpt.Rule               = Empty | AS;
            columnSource.Rule        = aggregate | id;
            aggregate.Rule           = aggregateName + "(" + aggregateArg + ")";
            aggregateArg.Rule        = expression | STAR;
            aggregateName.Rule       = COUNT | "Avg" | "Min" | "Max" | "StDev" | "StDevP" | "Sum" | "Var" | "VarP";
            intoClauseOpt.Rule       = Empty | INTO + id;
            forClauseOpt.Rule        = Empty | FOR + systemTimeOpt;
            systemTimeOpt.Rule       = SYSTEM_TIME + betweenTimeSelector | SYSTEM_TIME + fromToTimeSelector | SYSTEM_TIME + asOfTimeSelector;
            betweenTimeSelector.Rule = BETWEEN + dateTime + AND + dateTime;
            fromToTimeSelector.Rule  = FROM + dateTime + TO + dateTime;
            asOfTimeSelector.Rule    = AS + OF + dateTime;
            fromClauseOpt.Rule       = Empty | FROM + idLink;
            whereClauseOpt.Rule      = Empty | "WHERE" + expression;
            groupClauseOpt.Rule      = Empty | "GROUP" + BY + idList;
            havingClauseOpt.Rule     = Empty | "HAVING" + expression;
            orderClauseOpt.Rule      = Empty | "ORDER" + BY + orderList;
            orderList.Rule           = MakePlusRule(orderList, comma, orderMember);
            orderMember.Rule         = id + orderDirOpt;
            orderDirOpt.Rule         = Empty | "ASC" | "DESC";

            //Insert stmt
            insertStmt.Rule     = INSERT + intoOpt + id + columnNames + insertData;
            insertDataList.Rule = MakePlusRule(insertDataList, comma, insertObject);
            insertObject.Rule   = "(" + expressionList + ")";
            columnNames.Rule    = idlistPar | Empty;
            insertData.Rule     = selectStmt | VALUES + insertDataList;
            intoOpt.Rule        = Empty | INTO; //Into is optional in MSSQL

            //Update stmt
            updateStmt.Rule = UPDATE + id + SET + assignList + whereClauseOpt;
            assignList.Rule = MakePlusRule(assignList, comma, assignment);
            assignment.Rule = id + "=" + expression;

            //Expression
            expressionList.Rule = MakePlusRule(expressionList, comma, expression);
            //expression.Rule = /*"(" + expressionWithoutBrackets + ")" |*/ expressionWithoutBrackets;
            expression.Rule    = "(" + expression + ")" | binExpr | unExpr | term; // Add betweenExpr
            term.Rule          = id | stringLiteral | number;                      //| funCall | tuple | parSelectStmt;// | inStmt;
            tuple.Rule         = "(" + expressionList + ")";
            parSelectStmt.Rule = "(" + selectStmt + ")";
            unExpr.Rule        = unOp + "(" + expression + ")" | unOp + term;
            unOp.Rule          = NOT | "+" | "-" | "~";
            binExpr.Rule       = expression + binOp + expression;
            binOp.Rule         = ToTerm("+") | "-" | "*" | "/" | "%" | "&" | "|" | "^"
                                 | "=" | ">" | "<" | ">=" | "<=" | "<>" | "!=" | "!<" | "!>"
                                 | "AND" | "OR" | "LIKE" | NOT + "LIKE" | "IN" | NOT + "IN";
            betweenExpr.Rule = expression + notOpt + BETWEEN + expression + AND + expression;
            notOpt.Rule      = Empty | NOT;
            funCall.Rule     = id + "(" + funArgs + ")";
            funArgs.Rule     = selectStmt | expressionList;
            inStmt.Rule      = expression + "IN" + "(" + expressionList + ")";

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

            MarkPunctuation(",", "(", ")");
            MarkPunctuation(asOpt, semiOpt);

            MarkTransient(sqlCommand, term, asOpt, aliasOpt, stmtLine, tuple, /*expression,*/ idlistPar, idOperator);
            //LanguageFlags = LanguageFlags.CreateAst;
            binOp.SetFlag(TermFlags.InheritPrecedence);
        }