Esempio n. 1
0
        public LuaGrammar()
            : base(true)
        {
            #region Declare Terminals Here
            StringLiteral STRING = CreateLuaString("string");
            NumberLiteral NUMBER = CreateLuaNumber("number");

            LuaLongStringTerminal LONGSTRING = new LuaLongStringTerminal("long-string");

            // This includes both single-line and block comments
            var Comment = new LuaCommentTerminal("block-comment");

            //  Regular Operators

            //  Member Select Operators
            var DOT = Operator(".");
            DOT.EditorInfo = new TokenEditorInfo(TokenType.Operator, TokenColor.Text, TokenTriggers.MemberSelect);

            var COLON = Operator(":");
            COLON.EditorInfo = new TokenEditorInfo(TokenType.Operator, TokenColor.Text, TokenTriggers.MemberSelect);

            //  Standard Operators
            var EQ = Operator("=");

            //yujiang: Ignore comment
            NonGrammarTerminals.Add(Comment);

            #region Keywords
            var LOCAL = Keyword("local");
            var DO = Keyword("do");
            var END = Keyword("end");
            var WHILE = Keyword("while");
            var REPEAT = Keyword("repeat");
            var UNTIL = Keyword("until");
            var IF = Keyword("if");
            var THEN = Keyword("then");
            var ELSEIF = Keyword("elseif");
            var ELSE = Keyword("else");
            var FOR = Keyword("for");
            var IN = Keyword("in");
            var FUNCTION = Keyword("function");
            var RETURN = Keyword("return");
            var BREAK = Keyword("break");
            var NIL = Keyword("nil");
            var FALSE = Keyword("false");
            var TRUE = Keyword("true");
            var NOT = Keyword("not");
            var AND = Keyword("and");
            var OR = Keyword("or");
            #endregion
            IdentifierTerminal Name = new IdentifierTerminal("identifier");

             #endregion

            #region Declare NonTerminals Here
            NonTerminal Chunk = new NonTerminal("chunk");
            NonTerminal Block = new NonTerminal("block");

            NonTerminal Statement = new NonTerminal("statement");
            NonTerminal LastStatement = new NonTerminal("last statement");
            NonTerminal FuncName = new NonTerminal("function name");
            NonTerminal VarList = new NonTerminal("var list");
            NonTerminal Var = new NonTerminal("var");
            NonTerminal NameList = new NonTerminal("name list");
            NonTerminal ExprList = new NonTerminal("expr list");
            NonTerminal Expr = new NonTerminal("expr");
            NonTerminal PrefixExpr = new NonTerminal("prefix expr");
            NonTerminal FunctionCall = new NonTerminal("function call");
            NonTerminal Args = new NonTerminal("args");
            NonTerminal NamedFunction = new NonTerminal("named function");
            NonTerminal NamelessFunction = new NonTerminal("nameless function");
            NonTerminal FuncBody = new NonTerminal("function body");
            NonTerminal ParList = new NonTerminal("parlist");
            NonTerminal TableConstructor = new NonTerminal("table constructor");
            NonTerminal FieldList = new NonTerminal("field list");
            NonTerminal Field = new NonTerminal("field");
            NonTerminal FieldSep = new NonTerminal("field seperator");
            NonTerminal BinOp = new NonTerminal("binop");
            NonTerminal UnOp = new NonTerminal("unop");

            #endregion

            #region Place Rules Here
            //Using Lua 5.1 grammar as defined in
            //http://www.lua.org/manual/5.1/manual.html#8
            this.Root = Chunk;

            //chunk ::= {stat [`;´]} [laststat [`;´]]
            Chunk.Rule = (Statement + ToTerm(";").Q()).Star() + (LastStatement + ToTerm(";").Q()).Q();

            //block ::= chunk
            Block = Chunk;

            //stat ::=  varlist `=´ explist |
            //     functioncall |
            //     do block end |
            //     while exp do block end |
            //     repeat block until exp |
            //     if exp then block {elseif exp then block} [else block] end |
            //     for Name `=´ exp `,´ exp [`,´ exp] do block end |
            //     for namelist in explist do block end |
            //     function funcname funcbody |
            //     local function Name funcbody |
            //     local namelist [`=´ explist]
            Statement.Rule = VarList + "=" + ExprList |
                            FunctionCall |
                            DO + Block + END |
                            WHILE + Expr + DO + Block + END |
                            REPEAT + Block + UNTIL + Expr |
                            IF + Expr + THEN + Block + (ELSEIF + Expr + THEN + Block).Star() + (ELSE + Block).Q() + END |
                            FOR + Name + "=" + Expr + "," + Expr + ("," + Expr).Q() + DO + Block + END |
                            FOR + NameList + IN + ExprList + DO + Block + END |
                            NamedFunction |
                            LOCAL + NamedFunction |
                            LOCAL + NameList + ("=" + ExprList).Q();

            //laststat ::= return [explist] | break
            LastStatement.Rule = RETURN + ExprList.Q() | BREAK;

            //funcname ::= Name {`.´ Name} [`:´ Name]
            FuncName.Rule = Name + (DOT + Name).Star() + (COLON + Name).Q();

            //NamedFunction = 'function' + FuncName + FuncBody
            NamedFunction.Rule = FUNCTION + FuncName + FuncBody;

            //varlist ::= var {`,´ var}
            VarList.Rule = MakePlusRule(VarList, ToTerm(","), Var);

            //namelist ::= Name {`,´ Name}
            NameList.Rule = MakePlusRule(NameList, ToTerm(","), Name);

            //explist ::= {exp `,´} exp
            ExprList.Rule = MakePlusRule(ExprList, ToTerm(","), Expr);

            //exp ::=  nil | false | true | Number | String | `...´ | function |
            //     prefixexp | tableconstructor | exp binop exp | unop exp
            Expr.Rule = NIL | FALSE | TRUE | NUMBER | STRING | LONGSTRING | "..." | NamelessFunction |
                PrefixExpr | TableConstructor | Expr + BinOp + Expr | UnOp + Expr;

            //var ::=  Name | prefixexp `[´ exp `]´ | prefixexp `.´ Name
            Var.Rule = Name | PrefixExpr + "[" + Expr + "]" | PrefixExpr + DOT + Name;

            //prefixexp ::= var | functioncall | `(´ exp `)´
            PrefixExpr.Rule = Var | FunctionCall | "(" + Expr + ")";

            //functioncall ::=  prefixexp args | prefixexp `:´ Name args
            FunctionCall.Rule = PrefixExpr + Args | PrefixExpr + COLON + Name + Args;

            //args ::=  `(´ [explist] `)´ | tableconstructor | String
            Args.Rule = "(" + ExprList.Q() + ")" | TableConstructor | STRING | LONGSTRING;

            //function ::= function funcbody
            NamelessFunction.Rule = FUNCTION + FuncBody;

            //funcbody ::= `(´ [parlist] `)´ block end
            FuncBody.Rule = "(" + ParList.Q() + ")" + Block + END;

            //parlist ::= namelist [`,´ `...´] | `...´
            ParList.Rule = NameList + (ToTerm(",") + "...").Q() | "...";

            //tableconstructor ::= `{´ [fieldlist] `}´
            TableConstructor.Rule = "{" + FieldList.Q() + "}";

            //fieldlist ::= field {fieldsep field} [fieldsep]
            FieldList.Rule = Field + (FieldSep + Field).Star() + FieldSep.Q();

            //field ::= `[´ exp `]´ `=´ exp | Name `=´ exp | exp
            Field.Rule = "[" + Expr + "]" + "=" + Expr | Name + "=" + Expr | Expr;

            //fieldsep ::= `,´ | `;´
            FieldSep.Rule = ToTerm(",") | ";";

            //binop ::= `+´ | `-´ | `*´ | `/´ | `^´ | `%´ | `..´ |
            //     `<´ | `<=´ | `>´ | `>=´ | `==´ | `~=´ |
            //     and | or
            BinOp.Rule = ToTerm("+") | "-" | "*" | "/" | "^" | "%" | ".." |
                    "<" | "<=" | ">" | ">=" | "==" | "~=" |
                    AND | OR;

            //unop ::= `-´ | not | `#´
            UnOp.Rule = ToTerm("-") | NOT | "#";

            #endregion

            #region Define Keywords and Register Symbols
            this.RegisterBracePair("(", ")");
            this.RegisterBracePair("{", "}");
            this.RegisterBracePair("[", "]");

            this.MarkPunctuation(",", ";");

            this.RegisterOperators(1, OR);
            this.RegisterOperators(2, AND);
            this.RegisterOperators(3, "<",">","<=",">=","~=","==");
            this.RegisterOperators(4, Associativity.Right, "..");
            this.RegisterOperators(5, "+", "-");
            this.RegisterOperators(6, "*", "/", "%");
            this.RegisterOperators(7, NOT); //also -(unary)
            this.RegisterOperators(8, Associativity.Right, "^");

            #endregion

            //yujiang: register lua functions
            //this.LuaRegisterFunctions();
        }
Esempio n. 2
0
        public LuaGrammar() :
            base(true)
        {
            #region Declare Terminals Here
            StringLiteral STRING = CreateLuaString("string");
            NumberLiteral NUMBER = CreateLuaNumber("number");

            LuaLongStringTerminal LONGSTRING = new LuaLongStringTerminal("long-string");

            // This includes both single-line and block comments
            var Comment = new LuaCommentTerminal("block-comment");


            //  Regular Operators

            //  Member Select Operators
            var DOT = Operator(".");
            DOT.EditorInfo = new TokenEditorInfo(TokenType.Operator, TokenColor.Text, TokenTriggers.MemberSelect);

            var COLON = Operator(":");
            COLON.EditorInfo = new TokenEditorInfo(TokenType.Operator, TokenColor.Text, TokenTriggers.MemberSelect);

            //  Standard Operators
            var EQ = Operator("=");

            //yujiang: Ignore comment
            NonGrammarTerminals.Add(Comment);

            #region Keywords
            var LOCAL    = Keyword("local");
            var DO       = Keyword("do");
            var END      = Keyword("end");
            var WHILE    = Keyword("while");
            var REPEAT   = Keyword("repeat");
            var UNTIL    = Keyword("until");
            var IF       = Keyword("if");
            var THEN     = Keyword("then");
            var ELSEIF   = Keyword("elseif");
            var ELSE     = Keyword("else");
            var FOR      = Keyword("for");
            var IN       = Keyword("in");
            var FUNCTION = Keyword("function");
            var RETURN   = Keyword("return");
            var BREAK    = Keyword("break");
            var NIL      = Keyword("nil");
            var FALSE    = Keyword("false");
            var TRUE     = Keyword("true");
            var NOT      = Keyword("not");
            var AND      = Keyword("and");
            var OR       = Keyword("or");
            #endregion
            IdentifierTerminal Name = new IdentifierTerminal("identifier");

            #endregion

            #region Declare NonTerminals Here
            NonTerminal Chunk = new NonTerminal("chunk");
            NonTerminal Block = new NonTerminal("block");

            NonTerminal Statement        = new NonTerminal("statement");
            NonTerminal LastStatement    = new NonTerminal("last statement");
            NonTerminal FuncName         = new NonTerminal("function name");
            NonTerminal VarList          = new NonTerminal("var list");
            NonTerminal Var              = new NonTerminal("var");
            NonTerminal NameList         = new NonTerminal("name list");
            NonTerminal ExprList         = new NonTerminal("expr list");
            NonTerminal Expr             = new NonTerminal("expr");
            NonTerminal PrefixExpr       = new NonTerminal("prefix expr");
            NonTerminal FunctionCall     = new NonTerminal("function call");
            NonTerminal Args             = new NonTerminal("args");
            NonTerminal NamedFunction    = new NonTerminal("named function");
            NonTerminal NamelessFunction = new NonTerminal("nameless function");
            NonTerminal FuncBody         = new NonTerminal("function body");
            NonTerminal ParList          = new NonTerminal("parlist");
            NonTerminal TableConstructor = new NonTerminal("table constructor");
            NonTerminal FieldList        = new NonTerminal("field list");
            NonTerminal Field            = new NonTerminal("field");
            NonTerminal FieldSep         = new NonTerminal("field seperator");
            NonTerminal BinOp            = new NonTerminal("binop");
            NonTerminal UnOp             = new NonTerminal("unop");


            #endregion

            #region Place Rules Here
            //Using Lua 5.1 grammar as defined in
            //http://www.lua.org/manual/5.1/manual.html#8
            this.Root = Chunk;

            //chunk ::= {stat [`;´]} [laststat [`;´]]
            Chunk.Rule = (Statement + ToTerm(";").Q()).Star() + (LastStatement + ToTerm(";").Q()).Q();

            //block ::= chunk
            Block = Chunk;

            //stat ::=  varlist `=´ explist |
            //     functioncall |
            //     do block end |
            //     while exp do block end |
            //     repeat block until exp |
            //     if exp then block {elseif exp then block} [else block] end |
            //     for Name `=´ exp `,´ exp [`,´ exp] do block end |
            //     for namelist in explist do block end |
            //     function funcname funcbody |
            //     local function Name funcbody |
            //     local namelist [`=´ explist]
            Statement.Rule = VarList + "=" + ExprList |
                             FunctionCall |
                             DO + Block + END |
                             WHILE + Expr + DO + Block + END |
                             REPEAT + Block + UNTIL + Expr |
                             IF + Expr + THEN + Block + (ELSEIF + Expr + THEN + Block).Star() + (ELSE + Block).Q() + END |
                             FOR + Name + "=" + Expr + "," + Expr + ("," + Expr).Q() + DO + Block + END |
                             FOR + NameList + IN + ExprList + DO + Block + END |
                             NamedFunction |
                             LOCAL + NamedFunction |
                             LOCAL + NameList + ("=" + ExprList).Q();

            //laststat ::= return [explist] | break
            LastStatement.Rule = RETURN + ExprList.Q() | BREAK;

            //funcname ::= Name {`.´ Name} [`:´ Name]
            FuncName.Rule = Name + (DOT + Name).Star() + (COLON + Name).Q();

            //NamedFunction = 'function' + FuncName + FuncBody
            NamedFunction.Rule = FUNCTION + FuncName + FuncBody;

            //varlist ::= var {`,´ var}
            VarList.Rule = MakePlusRule(VarList, ToTerm(","), Var);

            //namelist ::= Name {`,´ Name}
            NameList.Rule = MakePlusRule(NameList, ToTerm(","), Name);

            //explist ::= {exp `,´} exp
            ExprList.Rule = MakePlusRule(ExprList, ToTerm(","), Expr);

            //exp ::=  nil | false | true | Number | String | `...´ | function |
            //     prefixexp | tableconstructor | exp binop exp | unop exp
            Expr.Rule = NIL | FALSE | TRUE | NUMBER | STRING | LONGSTRING | "..." | NamelessFunction |
                        PrefixExpr | TableConstructor | Expr + BinOp + Expr | UnOp + Expr;

            //var ::=  Name | prefixexp `[´ exp `]´ | prefixexp `.´ Name
            Var.Rule = Name | PrefixExpr + "[" + Expr + "]" | PrefixExpr + DOT + Name;

            //prefixexp ::= var | functioncall | `(´ exp `)´
            PrefixExpr.Rule = Var | FunctionCall | "(" + Expr + ")";

            //functioncall ::=  prefixexp args | prefixexp `:´ Name args
            FunctionCall.Rule = PrefixExpr + Args | PrefixExpr + COLON + Name + Args;

            //args ::=  `(´ [explist] `)´ | tableconstructor | String
            Args.Rule = "(" + ExprList.Q() + ")" | TableConstructor | STRING | LONGSTRING;

            //function ::= function funcbody
            NamelessFunction.Rule = FUNCTION + FuncBody;

            //funcbody ::= `(´ [parlist] `)´ block end
            FuncBody.Rule = "(" + ParList.Q() + ")" + Block + END;

            //parlist ::= namelist [`,´ `...´] | `...´
            ParList.Rule = NameList + (ToTerm(",") + "...").Q() | "...";

            //tableconstructor ::= `{´ [fieldlist] `}´
            TableConstructor.Rule = "{" + FieldList.Q() + "}";

            //fieldlist ::= field {fieldsep field} [fieldsep]
            FieldList.Rule = Field + (FieldSep + Field).Star() + FieldSep.Q();

            //field ::= `[´ exp `]´ `=´ exp | Name `=´ exp | exp
            Field.Rule = "[" + Expr + "]" + "=" + Expr | Name + "=" + Expr | Expr;

            //fieldsep ::= `,´ | `;´
            FieldSep.Rule = ToTerm(",") | ";";

            //binop ::= `+´ | `-´ | `*´ | `/´ | `^´ | `%´ | `..´ |
            //     `<´ | `<=´ | `>´ | `>=´ | `==´ | `~=´ |
            //     and | or
            BinOp.Rule = ToTerm("+") | "-" | "*" | "/" | "^" | "%" | ".." |
                         "<" | "<=" | ">" | ">=" | "==" | "~=" |
                         AND | OR;

            //unop ::= `-´ | not | `#´
            UnOp.Rule = ToTerm("-") | NOT | "#";



            #endregion

            #region Define Keywords and Register Symbols
            this.RegisterBracePair("(", ")");
            this.RegisterBracePair("{", "}");
            this.RegisterBracePair("[", "]");

            this.MarkPunctuation(",", ";");

            this.RegisterOperators(1, OR);
            this.RegisterOperators(2, AND);
            this.RegisterOperators(3, "<", ">", "<=", ">=", "~=", "==");
            this.RegisterOperators(4, Associativity.Right, "..");
            this.RegisterOperators(5, "+", "-");
            this.RegisterOperators(6, "*", "/", "%");
            this.RegisterOperators(7, NOT); //also -(unary)
            this.RegisterOperators(8, Associativity.Right, "^");

            #endregion

            //yujiang: register lua functions
            //this.LuaRegisterFunctions();
        }