Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * NonTerminals have capital names with no prefixes
- * to match the official BNF specification for AngelScript.
- *
- * If a NonTerminal makes use of a PlusList it will have a suffix of "S" to denote 1..n.
- * If a NonTerminal makes use of a StarList it will have a suffix of "S_OPT" to denote 0..n.
- */
- using Irony.Parsing;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Diagnostics; // added for Debug.Print
- namespace AngelScript
- {
- [Language("Angel Script", "1.0", "Angel Script Programming Language")]
- public class AngelScriptGrammar : Irony.Parsing.Grammar
- {
- public AngelScriptGrammar()
- {
- // Comments
- var singleLineComment = new CommentTerminal("SingleLineComment", "//", "\r", "\n", "\u2085", "\u2028", "\u2029");
- var delimitedComment = new CommentTerminal("DelimitedComment", "/*", "*/");
- NonGrammarTerminals.Add(singleLineComment);
- NonGrammarTerminals.Add(delimitedComment);
- // Symbols / Operators
- #region Operators
- var op_ASSIGN = Operator("=", "op_assign");
- var op_PLUS_ASSIGN = Operator("+=", "plus_assign");
- var op_MINUS_ASSIGN = Operator("-=", "minus_assign");
- var op_STAR_ASSIGN = Operator("*=", "star_assign");
- var op_STAR_STAR_ASSIGN = Operator("**=", "star_star_assign");
- var op_SLASH_ASSIGN = Operator("/=", "slash_assign");
- var op_AMP_ASSIGN = Operator("&=", "amp_assign");
- var op_BAR_ASSIGN = Operator("|=", "bar_assign");
- var op_CARET_ASSIGN = Operator("^=", "caret_assign");
- var op_PERCENT_ASSIGN = Operator("%=", "percent_assign");
- var op_SHL_ASSIGN = Operator("<<=", "shl_assign");
- var op_SHR_ASSIGN = Operator(">>=", "shr_assign");
- var op_USHR_ASSIGN = Operator(">>>=", "ushr_assign");
- var op_AMP = Operator("&", "amp");
- var op_AT = Operator("@", "at");
- var op_BAR = Operator("|", "bar");
- var op_CARET = Operator("^", "caret");
- var op_COMMA = Operator(",", "comma");
- var op_DOT = Operator(".", "dot");
- var op_EMARK = Operator("!", "emark");
- var op_MINUS = Operator("-", "minus");
- var op_PERCENT = Operator("%", "percent");
- var op_PLUS = Operator("+", "plus");
- var op_QMARK = Operator("?", "qmark");
- var op_STAR = Operator("*", "star");
- var op_SLASH = Operator("/", "slash");
- var op_TILDE = Operator("~", "tilde");
- var op_AMP_AMP = Operator("&&", "amp_amp");
- var op_BAR_BAR = Operator("||", "bar_bar");
- var op_CARET_CARET = Operator("^^", "caret_caret");
- var op_MINUS_MINUS = Operator("--", "minus");
- var op_PLUS_PLUS = Operator("++", "plus_plus");
- var op_SHL = Operator("<<", "shl");
- var op_SHR = Operator(">>", "shr");
- var op_STAR_STAR = Operator("**", "star_star");
- var op_USHR = Operator(">>>", "ushr");
- var op_L_BKT = Operator("[", "l_bkt");
- var op_R_BKT = Operator("]", "r_bkt");
- var op_L_BRC = Operator("{", "l_brc");
- var op_R_BRC = Operator("}", "r_brc");
- var op_L_PAR = Operator("(", "l_par");
- var op_R_PAR = Operator(")", "r_par");
- var op_COLON = Operator(":", "colon");
- var op_COLON_COLON = Operator("::", "colon_colon");
- var op_SEMI = Operator(";", "semi");
- var op_EQ = Operator("==", "eq");
- var op_NEQ = Operator("!=", "neq");
- var op_GT = Operator(">", "gt");
- var op_GTEQ = Operator(">=", "gteq");
- var op_LT = Operator("<", "lt");
- var op_LTEQ = Operator("<=", "lteq");
- var op_AND = Operator("and", "and");
- var op_IS = Operator("is", "is");
- var op_IS_NOT = Operator("!is", "is_not");
- var op_NOT = Operator("not", "not");
- var op_OR = Operator("or", "or");
- var op_XOR = Operator("xor", "xor");
- #endregion
- // Keywords
- #region Keywords
- KeyTerm k_AND = Keyword("and");
- KeyTerm k_ABSTRACT = Keyword("abstract");
- KeyTerm k_AUTO = Keyword("auto");
- KeyTerm k_BOOL = Keyword("bool");
- KeyTerm k_BREAK = Keyword("break");
- KeyTerm k_CASE = Keyword("case");
- KeyTerm k_CAST = Keyword("cast");
- KeyTerm k_CLASS = Keyword("class");
- KeyTerm k_CONST = Keyword("const");
- KeyTerm k_CONTINUE = Keyword("continue");
- KeyTerm k_DEFAULT = Keyword("default");
- KeyTerm k_DO = Keyword("do");
- KeyTerm k_DOUBLE = Keyword("double");
- KeyTerm k_ELSE = Keyword("else");
- KeyTerm k_ENUM = Keyword("enum");
- KeyTerm k_FALSE = Keyword("false");
- KeyTerm k_FINAL = Keyword("final");
- KeyTerm k_FLOAT = Keyword("float");
- KeyTerm k_FOR = Keyword("for");
- KeyTerm k_FROM = Keyword("from");
- KeyTerm k_FUNCDEF = Keyword("funcdef");
- KeyTerm k_GET = Keyword("get");
- KeyTerm k_IF = Keyword("if");
- KeyTerm k_IMPORT = Keyword("import");
- KeyTerm k_IN = Keyword("in");
- KeyTerm k_INOUT = Keyword("inout");
- KeyTerm k_INT = Keyword("int");
- KeyTerm k_INTERFACE = Keyword("interface");
- KeyTerm k_INT8 = Keyword("int8");
- KeyTerm k_INT16 = Keyword("int16");
- KeyTerm k_INT32 = Keyword("int32");
- KeyTerm k_INT64 = Keyword("int64");
- KeyTerm k_IS = Keyword("is");
- KeyTerm k_MIXIN = Keyword("mixin");
- KeyTerm k_NAMESPACE = Keyword("namespace");
- KeyTerm k_NOT = Keyword("not");
- KeyTerm k_NULL = Keyword("null");
- KeyTerm k_OR = Keyword("or");
- KeyTerm k_OUT = Keyword("out");
- KeyTerm k_OVERRIDE = Keyword("override");
- KeyTerm k_PRIVATE = Keyword("private");
- KeyTerm k_PROTECTED = Keyword("protected");
- KeyTerm k_RETURN = Keyword("return");
- KeyTerm k_SET = Keyword("set");
- KeyTerm k_SHARED = Keyword("shared");
- KeyTerm k_SUPER = Keyword("super");
- KeyTerm k_SWITCH = Keyword("switch");
- KeyTerm k_THIS = Keyword("this");
- KeyTerm k_TRUE = Keyword("true");
- KeyTerm k_TYPEDEF = Keyword("typedef");
- KeyTerm k_UINT = Keyword("uint");
- KeyTerm k_UINT8 = Keyword("uint8");
- KeyTerm k_UINT16 = Keyword("uint16");
- KeyTerm k_UINT32 = Keyword("uint32");
- KeyTerm k_UINT64 = Keyword("uint64");
- KeyTerm k_VOID = Keyword("void");
- KeyTerm k_WHILE = Keyword("while");
- KeyTerm k_XOR = Keyword("xor");
- #endregion
- var IDENTIFIER = new IdentifierTerminal("identifier");
- var NUMBER = CreateAngelScriptNumber("number");
- var STRING = new StringLiteral("string", "\"");
- // NonTerminals
- NonTerminal ARGLIST = new NonTerminal("arglist");
- NonTerminal ASSIGN = new NonTerminal("assign");
- NonTerminal ASSIGNOP = new NonTerminal("assignop");
- NonTerminal BITOP = new NonTerminal("bitop");
- NonTerminal BREAK = new NonTerminal("break");
- NonTerminal CASE = new NonTerminal("case");
- NonTerminal CASES_OPT = new NonTerminal("case_opt");
- NonTerminal CAST = new NonTerminal("cast");
- NonTerminal CLASS = new NonTerminal("class");
- NonTerminal COMPOP = new NonTerminal("compop");
- NonTerminal CONDITION = new NonTerminal("condition");
- NonTerminal CONSTRUCTCALL = new NonTerminal("constructcall");
- NonTerminal CONTINUE = new NonTerminal("continue");
- NonTerminal DOWHILE = new NonTerminal("dowhile");
- NonTerminal DATATYPE = new NonTerminal("datatype");
- NonTerminal ENUM = new NonTerminal("enum");
- NonTerminal ENUM_ITEM = new NonTerminal("enum_item");
- NonTerminal ENUM_ITEMS = new NonTerminal("enum_items");
- NonTerminal EXPR = new NonTerminal("expr");
- NonTerminal EXPR_OP = new NonTerminal("expr_op");
- NonTerminal EXPR_OP_TERM = new NonTerminal("expr_op_term");
- NonTerminal EXPR_POSTOP = new NonTerminal("expr_postop");
- NonTerminal EXPR_POSTOPS_OPT = new NonTerminal("expr_postops_opt");
- NonTerminal EXPR_PREOP = new NonTerminal("expr_preop");
- NonTerminal EXPR_PREOPS_OPT = new NonTerminal("expr_preops_opt");
- NonTerminal EXPR_STAT = new NonTerminal("expr_stat");
- NonTerminal EXPR_TERM = new NonTerminal("expr_term");
- NonTerminal EXPR_VALUE = new NonTerminal("expr_value");
- NonTerminal FOR = new NonTerminal("for");
- NonTerminal FUNC = new NonTerminal("func");
- NonTerminal FUNC_MOD2 = new NonTerminal("func_mod2");
- NonTerminal FUNCCALL = new NonTerminal("funccall");
- NonTerminal FUNCDEF = new NonTerminal("funcdef");
- NonTerminal IF = new NonTerminal("if");
- NonTerminal IF_ELSE = new NonTerminal("if_else");
- NonTerminal IMPORT = new NonTerminal("import");
- NonTerminal INITLIST = new NonTerminal("initlist");
- NonTerminal INITLIST_OR_ASSIGN = new NonTerminal("initlist_or_assign");
- NonTerminal INITLIST_OR_ASSIGNS_OPT = new NonTerminal("initlist_or_assigns_opt");
- NonTerminal INTERFACE = new NonTerminal("interface");
- // NonTerminal INTFMTHD = new NonTerminal("intfmthd");
- NonTerminal LITERAL = new NonTerminal("literal");
- NonTerminal LOGICOP = new NonTerminal("logicop");
- NonTerminal MATHOP = new NonTerminal("mathop");
- NonTerminal MIXIN = new NonTerminal("mixin");
- NonTerminal NAMESPACE = new NonTerminal("namespace");
- NonTerminal PARAMLIST = new NonTerminal("paramlist");
- NonTerminal PRIMTYPE = new NonTerminal("primtype");
- NonTerminal RETURN = new NonTerminal("return");
- NonTerminal SCOPE_DATATYPE = new NonTerminal("scope_datatype");
- NonTerminal SCRIPT = new NonTerminal("script");
- NonTerminal SCRIPT_ITEM = new NonTerminal("script_item");
- NonTerminal STATBLOCK = new NonTerminal("statblock");
- NonTerminal STATEMENT = new NonTerminal("statement");
- NonTerminal STATEMENTS_OTP = new NonTerminal("statements_opt");
- NonTerminal SWITCH = new NonTerminal("switch");
- NonTerminal TYPE = new NonTerminal("type");
- NonTerminal TYPES = new NonTerminal("types");
- NonTerminal TYPEDEF = new NonTerminal("typedef");
- NonTerminal TYPEMOD = new NonTerminal("typemod");
- NonTerminal VAR = new NonTerminal("var");
- NonTerminal VAR_ID = new NonTerminal("var_id");
- NonTerminal VAR_IDS = new NonTerminal("var_ids");
- // NonTerminal VARACCESS = new NonTerminal("varaccess");
- NonTerminal VIRTPROP = new NonTerminal("virtprop");
- NonTerminal VIRTPROP_ITEM = new NonTerminal("virtprop_item");
- NonTerminal VIRTPROP_ITEMS_OPT = new NonTerminal("virtprop_items_opt");
- NonTerminal WHILE = new NonTerminal("while");
- NonTerminal ASSIGNS_OPT = new NonTerminal("assigns_opt");
- ASSIGNS_OPT.Rule = MakeStarRule(ASSIGNS_OPT, ToTerm(","), ASSIGN);
- NonTerminal CONST_OPT = new NonTerminal("const_opt");
- CONST_OPT.Rule = Empty | "const";
- NonTerminal IDENTIFIERS_OPT = new NonTerminal("identifiers_opt");
- IDENTIFIERS_OPT.Rule = MakeStarRule(IDENTIFIERS_OPT, ToTerm(","), IDENTIFIER);
- NonTerminal IDENTIFIER_CA = new NonTerminal("identifier_ca");
- IDENTIFIER_CA.Rule = ASSIGN | PreferShiftHere() + IDENTIFIER + ":" + ASSIGN;
- NonTerminal IDENTIFIER_CAS = new NonTerminal("identifier_cas");
- IDENTIFIER_CAS.Rule = MakePlusRule(IDENTIFIER_CAS, ToTerm(","), IDENTIFIER_CA);
- NonTerminal MODIFIER = new NonTerminal("modifier");
- MODIFIER.Rule = ToTerm("private") | "protected" | "shared" | "abstract" | "final" | "override";
- NonTerminal MODIFIERS_OPT = new NonTerminal("modifiers_opt");
- //MODIFIERS_OPT.Rule = MakeStarRule(MODIFIERS_OPT, MODIFIER);
- MODIFIERS_OPT.Rule = Empty | MODIFIER + MODIFIERS_OPT | MODIFIER + ReduceHere();
- NonTerminal TYPE_AMP_OPT = new NonTerminal("type_amp_opt");
- // TYPE_AMP_OPT.Rule = TYPE | TYPE + "&";
- TYPE_AMP_OPT.Rule = TYPE;
- NonTerminal VFV = new NonTerminal("vfv");
- NonTerminal FUNC_MOD2_ID = new NonTerminal("func_mod2_id");
- NonTerminal VFV_TYPES_OPT = new NonTerminal("vfv_types_opt");
- // FUNC_MOD2_ID.Rule = IDENTIFIER | TYPE + IDENTIFIER | TYPE + "&" + IDENTIFIER | "~" + IDENTIFIER;
- // FUNC_MOD2_ID.Rule = Empty | TYPE | "~" | TYPE + IDENTIFIER | TYPE + IDENTIFIER + IDENTIFIER;
- VFV_TYPES_OPT.Rule = Empty | TYPE + VFV_TYPES_OPT;
- FUNC_MOD2_ID.Rule = VFV_TYPES_OPT | "~";
- // VFV.Rule = VIRTPROP | FUNC | VAR;
- // VFV.Rule = MODIFIERS_OPT + TYPE_AMP_OPT + IDENTIFIER + "{" + VIRTPROP_ITEMS_OPT + "}"
- // | MODIFIERS_OPT + FUNC_MOD2 + IDENTIFIER + PARAMLIST + CONST_OPT + MODIFIERS_OPT + STATBLOCK
- // | MODIFIERS_OPT + TYPE + IDENTIFIER + VAR_IDS + ";";
- NonTerminal VFV_VAR_ID = new NonTerminal("vfv_var_id");
- VFV_VAR_ID.Rule = Empty
- | "=" + INITLIST
- | "=" + EXPR;
- NonTerminal VFV_VAR_IDS = new NonTerminal("vfv_var_ids");
- VFV_VAR_IDS.Rule = VFV_VAR_ID | VFV_VAR_ID + "," + IDENTIFIER;
- NonTerminal VFV_END = new NonTerminal("vfv_end");
- VFV_END.Rule = "{" + VIRTPROP_ITEMS_OPT + "}"
- | PARAMLIST + CONST_OPT + MODIFIERS_OPT + STATBLOCK
- | VFV_VAR_IDS + ";";
- VFV.Rule = MODIFIERS_OPT + FUNC_MOD2_ID + VFV_END;
- NonTerminal VFVS_OPT = new NonTerminal("vfvs_otp");
- VFVS_OPT.Rule = MakeStarRule(VFVS_OPT, VFV);
- NonTerminal VS = new NonTerminal("vs");
- VS.Rule = VAR | STATEMENT;
- NonTerminal VSS_OPT = new NonTerminal("vss_otp");
- VSS_OPT.Rule = MakeStarRule(VSS_OPT, VS);
- // Rules
- this.Root = SCRIPT;
- // ARGLIST ::= '(' [IDENTIFIER ':'] ASSIGN {',' [IDENTIFIER ':'] ASSIGN} ')'
- ARGLIST.Rule = ToTerm("(") + IDENTIFIER_CAS + ")";
- // ASSIGN ::= CONDITION [ ASSIGNOP ASSIGN ]
- ASSIGN.Rule = CONDITION | CONDITION + ASSIGNOP + ASSIGN;
- // ASSIGNOP ::= '=' | '+=' | '-=' | '*=' | '/=' | '|=' | '&=' | '^=' | '%=' | '**=' | '<<=' | '>>=' | '>>>='
- ASSIGNOP.Rule = op_ASSIGN | op_PLUS_ASSIGN | op_MINUS_ASSIGN | op_STAR_ASSIGN | op_SLASH_ASSIGN | op_BAR_ASSIGN | op_AMP_ASSIGN | op_CARET_ASSIGN | op_PERCENT_ASSIGN | op_STAR_STAR_ASSIGN | op_SHL_ASSIGN | op_SHR_ASSIGN | op_USHR_ASSIGN;
- // BITOP ::= '&' | '|' | '^' | '<<' | '>>' | '>>>'
- BITOP.Rule = op_AMP | op_BAR | op_CARET | op_SHL | op_SHR | op_USHR;
- // BITS ::= single token: binary 0b or 0B, "octal 0o or 0O, "decimal 0d or 0D, "hexadecimal 0x or 0X
- // This is treated the same as NUMBER
- // BREAK ::= 'break' ';'
- BREAK.Rule = k_BREAK + op_SEMI;
- // CASE ::= (('case' EXPR) | 'default') ':' {STATEMENT}
- CASE.Rule = k_CASE + EXPR + ":" + STATEMENTS_OTP
- | k_DEFAULT + ":" + STATEMENTS_OTP;
- CASES_OPT.Rule = MakeStarRule(CASES_OPT, CASE);
- // CAST ::= 'cast' '<' TYPE '>' '(' ASSIGN ')'
- CAST.Rule = k_CAST + "<" + TYPE + ">" + "(" + ASSIGN + ")";
- // CLASS ::= {'shared' | 'abstract' | 'final'} 'class' IDENTIFIER [':' IDENTIFIER {',' IDENTIFIER}] '{' {VIRTPROP | FUNC | VAR} '}'
- CLASS.Rule = MODIFIERS_OPT + k_CLASS + IDENTIFIER + "{" + VFVS_OPT + "}"
- | MODIFIERS_OPT + k_CLASS + IDENTIFIER + ":" + IDENTIFIERS_OPT + "{" + VFVS_OPT + "}";
- // COMPOP ::= '==' | '!=' | '<' | '<=' | '>' | '>=' | 'is' | '!is'
- COMPOP.Rule = op_EQ | op_NEQ | op_LT | op_LTEQ | op_GT | op_GTEQ | op_IS | op_IS_NOT;
- // CONDITION ::= EXPR ['?' ASSIGN ':' ASSIGN]
- CONDITION.Rule = EXPR | EXPR + "?" + ASSIGN + ":" + ASSIGN;
- // CONSTRUCTCALL::= TYPE ARGLIST
- CONSTRUCTCALL.Rule = TYPE + ARGLIST;
- // CONTINUE ::= 'continue' ';'
- CONTINUE.Rule = k_CONTINUE + op_SEMI;
- // DATATYPE ::= (IDENTIFIER | PRIMTYPE | '?' | 'auto')
- DATATYPE.Rule = IDENTIFIER | PRIMTYPE | op_QMARK | k_AUTO;
- // DOWHILE ::= 'do' STATEMENT 'while' '(' ASSIGN ')' ';'
- DOWHILE.Rule = k_DO + STATEMENT + k_WHILE + "(" + ASSIGN + ")" + ";";
- // ENUM ::= ['shared'] 'enum' IDENTIFIER '{' IDENTIFIER ['=' EXPR] {',' IDENTIFIER ['=' EXPR]} '}'
- ENUM_ITEM.Rule = IDENTIFIER | IDENTIFIER + "=" + EXPR;
- ENUM_ITEMS.Rule = MakeStarRule(ENUM_ITEMS, ToTerm(","), ENUM_ITEM);
- ENUM.Rule = MODIFIERS_OPT + "enum" + IDENTIFIER + "{" + ENUM_ITEMS + "}";
- // EXPR ::= (TYPE '=' INITLIST) | (EXPR_TERM {EXPR_OP EXPR_TERM})
- // (TYPE '=' INITLIST) gets rolled into VOID_CONSTRUCTCALL_FUNCCALL_VARACCESS.
- // And VOID_CONSTRUCTCALL_FUNCCALL_VARACCESS can be reached via EXPR2.
- // So it doesn't have to be included here.
- // EXPR_OP_TERM.Rule = Empty | EXPR_OP + EXPR_TERM | EXPR_OP + EXPR_TERM + EXPR_OP_TERM;
- // EXPR.Rule = EXPR_TERM + EXPR_OP_TERM;
- // EXPR.Rule = EXPR_TERM | EXPR_TERM + EXPR_OP + EXPR;
- EXPR.Rule = EXPR_PREOPS_OPT + EXPR_VALUE + EXPR_POSTOPS_OPT + ReduceHere()
- | EXPR_PREOPS_OPT + EXPR_VALUE + EXPR_POSTOPS_OPT + PreferShiftHere() + EXPR_OP + EXPR + ReduceHere();
- // EXPR_OP ::= MATHOP | COMPOP | LOGICOP | BITOP
- EXPR_OP.Rule = MATHOP | COMPOP | LOGICOP | BITOP;
- // EXPR_POSTOP ::= ('.' (FUNCCALL | IDENTIFIER))
- // | ('[' [IDENTIFIER ':'] ASSIGN {',' [IDENTIFIER ':'] ASSIGN} ']')
- // | ARGLIST | '++' | '--'
- // We simply this by realising that it is only used in from EXPR_POSTOPS_OPT.
- // So we can remove ('.' FUNCCALL) and replace ('.' IDENTIFIER) with ('.' SCOPE_DATATYPE).
- EXPR_POSTOP.Rule = op_DOT + SCOPE_DATATYPE + ReduceHere()
- // TODO: uncomment this and try adding it in only where it is used
- | ToTerm("[") + IDENTIFIER_CAS + "]" + ReduceHere()
- | ARGLIST // ToTerm("(") + IDENTIFIER_CAS + ")"
- | op_PLUS_PLUS
- | op_MINUS_MINUS;
- EXPR_POSTOPS_OPT.Rule = MakeStarRule(EXPR_POSTOPS_OPT, EXPR_POSTOP);
- // EXPR_PREOP ::= '-' | '+' | '!' | '++' | '--' | '~' | '@'
- EXPR_PREOP.Rule = op_MINUS | op_PLUS | op_EMARK | op_PLUS_PLUS | op_MINUS_MINUS | op_TILDE | op_AT;
- EXPR_PREOPS_OPT.Rule = MakeStarRule(EXPR_PREOPS_OPT, EXPR_PREOP);
- // EXPR_STAT ::= [ASSIGN] ';'
- EXPR_STAT.Rule = ASSIGN + ";" | ";";
- // EXPR_TERM ::= {EXPR_PREOP} EXPR_VALUE {EXPR_POSTOP}
- // EXPR_TERM.Rule = EXPR_PREOPS_OPT + EXPR_VALUE + EXPR_POSTOPS_OPT;
- // Original Rule: EXPR_VALUE ::= 'void' | CONSTRUCTCALL | FUNCCALL | VARACCESS | CAST | LITERAL | '(' ASSIGN ')'
- // VOID_CONSTRUCTCALL_FUNCCALL_VARACCESS ::= TYPE [ARGLIST]
- NonTerminal VOID_CONSTRUCTCALL_FUNCCALL_VARACCESS = new NonTerminal("void_constructcall_funccall_varaccess");
- // We remove the ARGLIST from the rule below because is can be reached by EXPR_POSTOP
- VOID_CONSTRUCTCALL_FUNCCALL_VARACCESS.Rule = TYPE
- | TYPE + "=" + INITLIST;
- // We combine CONSTRUCTCALL and FUNCCALL and VARACCESS into one state since they are so similar.
- // We also combine k_VOID into it since it can be made from TYPE.
- // We also combine EXPR1 into it by adding an optional ("+" + INITLIST) at the end
- EXPR_VALUE.Rule = VOID_CONSTRUCTCALL_FUNCCALL_VARACCESS | CAST | LITERAL | "(" + ASSIGN + ")";
- // FOR ::= 'for' '(' (VAR | EXPR_STAT) EXPR_STAT [ASSIGN {',' ASSIGN}] ')' STATEMENT
- FOR.Rule = k_FOR + "(" + VAR + EXPR_STAT + ASSIGNS_OPT + ")" + STATEMENT
- | k_FOR + "(" + EXPR_STAT + EXPR_STAT + ASSIGNS_OPT + ")" + STATEMENT;
- // FUNC ::= ['private' | 'protected' | 'shared'] [((TYPE ['&']) | '~')] IDENTIFIER PARAMLIST ['const'] {'override' | 'final'} STATBLOCK
- FUNC_MOD2.Rule = Empty | TYPE_AMP_OPT | "~";
- FUNC.Rule = MODIFIERS_OPT + FUNC_MOD2 + IDENTIFIER + PARAMLIST + CONST_OPT + MODIFIERS_OPT + STATBLOCK;
- // FUNCCALL ::= SCOPE IDENTIFIER ARGLIST
- FUNCCALL.Rule = SCOPE_DATATYPE + ARGLIST;
- // FUNCDEF ::= 'funcdef' TYPE ['&'] IDENTIFIER PARAMLIST ';'
- FUNCDEF.Rule = k_FUNCDEF + TYPE_AMP_OPT + IDENTIFIER + PARAMLIST + op_SEMI;
- // IDENTIFIER ::= single token: starts with letter or _, can include any letter and digit, same as in C++
- // No need to set a Rule because it is type: IdentifierTerminal
- // IF ::= 'if' '(' ASSIGN ')' STATEMENT ['else' STATEMENT]
- IF_ELSE.Rule = Empty | PreferShiftHere() + k_ELSE + STATEMENT;
- IF.Rule = k_IF + "(" + ASSIGN + ")" + STATEMENT + IF_ELSE;
- // IMPORT ::= 'import' TYPE ['&'] IDENTIFIER PARAMLIST 'from' STRING ';'
- IMPORT.Rule = "import" + TYPE_AMP_OPT + IDENTIFIER + PARAMLIST + "from" + STRING + op_SEMI;
- // INITLIST ::= '{' [ASSIGN | INITLIST] {',' [ASSIGN | INITLIST]} '}'
- INITLIST_OR_ASSIGN.Rule = ASSIGN | INITLIST;
- INITLIST_OR_ASSIGNS_OPT.Rule = MakeStarRule(INITLIST_OR_ASSIGNS_OPT, ToTerm(","), INITLIST_OR_ASSIGN);
- INITLIST.Rule = ToTerm("{") + INITLIST_OR_ASSIGNS_OPT + "}";
- // INTERFACE ::= ['shared'] 'interface' IDENTIFIER [':' IDENTIFIER {',' IDENTIFIER}] '{' {VIRTPROP | INTFMTHD} '}'
- NonTerminal INTERFACE_IV = new NonTerminal("interface_iv");
- INTERFACE_IV.Rule = MODIFIERS_OPT + TYPE_AMP_OPT + IDENTIFIER + PARAMLIST + CONST_OPT + ";"
- | MODIFIERS_OPT + TYPE_AMP_OPT + IDENTIFIER + "{" + VIRTPROP_ITEMS_OPT + "}";
- // INTERFACE_IV.Rule = INTFMTHD | VIRTPROP;
- NonTerminal INTERFACE_IVS_OPT = new NonTerminal("interface_ivs_opt");
- INTERFACE_IVS_OPT.Rule = MakeStarRule(INTERFACE_IVS_OPT, INTERFACE_IV);
- INTERFACE.Rule = MODIFIERS_OPT + k_INTERFACE + IDENTIFIER + "{" + INTERFACE_IVS_OPT + "}"
- | MODIFIERS_OPT + k_INTERFACE + IDENTIFIER + ":" + IDENTIFIERS_OPT + "{" + INTERFACE_IVS_OPT + "}";
- // INTFMTHD ::= TYPE ['&'] IDENTIFIER PARAMLIST ['const'] ';'
- // INTFMTHD.Rule = TYPE_AMP_OPT + IDENTIFIER + PARAMLIST + CONST_OPT + ";";
- // LITERAL ::= NUMBER | STRING | BITS | 'true' | 'false' | 'null'
- LITERAL.Rule = NUMBER | STRING | k_TRUE | k_FALSE | k_NULL;
- // LOGICOP ::= '&&' | '||' | '^^' | 'and' | 'or' | 'xor'
- LOGICOP.Rule = op_AMP_AMP | op_BAR_BAR | op_CARET_CARET | op_AND | op_OR | op_XOR;
- // MATHOP ::= '+' | '-' | '*' | '/' | '%' | '**'
- MATHOP.Rule = op_PLUS | op_MINUS | op_STAR | op_SLASH | op_PERCENT | op_STAR_STAR;
- // MIXIN ::= 'mixin' CLASS
- MIXIN.Rule = "mixin" + CLASS;
- // NAMESPACE ::= 'namespace' IDENTIFIER '{' SCRIPT '}'
- NAMESPACE.Rule = k_NAMESPACE + IDENTIFIER + "{" + SCRIPT + "}";
- // NUMBER ::= single token: includes integers and real numbers, same as C++
- // No need to set a Rule because it is type: CreateAngelScriptNumber
- // PARAMLIST ::= '(' ('void' | (TYPE TYPEMOD [IDENTIFIER] ['=' EXPR] {',' TYPE TYPEMOD [IDENTIFIER] ['=' EXPR]})) ')'
- // Note: Void is not explicitly included because it can be reached via: PARAMLIST_TYPE -> TYPE
- NonTerminal PARAMLIST_TYPE = new NonTerminal("paramlist_type");
- PARAMLIST_TYPE.Rule = TYPE + TYPEMOD
- | TYPE + TYPEMOD + "=" + EXPR
- | TYPE + TYPEMOD + IDENTIFIER
- | TYPE + TYPEMOD + IDENTIFIER + "=" + EXPR;
- NonTerminal PARAMLIST_TYPES = new NonTerminal("paramlist_types");
- PARAMLIST_TYPES.Rule = MakePlusRule(PARAMLIST_TYPES, ToTerm(","), PARAMLIST_TYPE);
- PARAMLIST.Rule = ToTerm("(") + PARAMLIST_TYPES + ")";
- // PRIMTYPE ::= 'void' | 'int' | 'int8' | 'int16' | 'int32' | 'int64' | 'uint' | 'uint8' | 'uint16' | 'uint32' | 'uint64' | 'float' | 'double' | 'bool'
- PRIMTYPE.Rule = k_VOID | k_INT8 | k_INT16 | k_INT32 | k_INT64 | k_INT | k_UINT8 | k_UINT16 | k_UINT32 | k_UINT64 | k_UINT | k_FLOAT | k_DOUBLE | k_BOOL;
- // RETURN ::= 'return' [ASSIGN] ';'
- RETURN.Rule = k_RETURN + ";" | k_RETURN + ASSIGN + ";";
- var SCOPEDDATATYPE = new NonTerminal("scopeddatatype");
- var SCOPEDIDENTIFIERLIST = new NonTerminal("scopedidentifierlist");
- var SCOPEDIDENTIFIER = new NonTerminal("scopedidentifier");
- // SCOPE ::= [[IDENTIFIER] '::' {IDENTIFIER '::'}]
- SCOPE_DATATYPE.Rule = SCOPEDDATATYPE;// | "::" + SCOPE_DATATYPE | IDENTIFIER + "::" + SCOPE_DATATYPE;
- // SCOPEDIDENTIFIER - Used in place of "SCOPE IDENTIFIER"
- // SCOPEDDATATYPE - Used in place of "SCOPE DATATYPE", it's DATATYPE with the option to have a scoped identifier
- SCOPEDIDENTIFIERLIST.Rule = MakeListRule(SCOPEDIDENTIFIERLIST, op_COLON_COLON, IDENTIFIER, TermListOptions.AddPreferShiftHint);
- SCOPEDIDENTIFIER.Rule = op_COLON_COLON + SCOPEDIDENTIFIERLIST | SCOPEDIDENTIFIERLIST;
- SCOPEDDATATYPE.Rule = PRIMTYPE | op_QMARK | k_AUTO | SCOPEDIDENTIFIER;
- // SCRIPT ::= {IMPORT | ENUM | TYPEDEF | CLASS | MIXIN | INTERFACE | FUNCDEF | VIRTPROP | VAR | FUNC | NAMESPACE | ';'}
- NonTerminal FUNC_VAR = new NonTerminal("func_var");
- FUNC_VAR.Rule = MODIFIERS_OPT + FUNC_MOD2 + IDENTIFIER + PARAMLIST + CONST_OPT + MODIFIERS_OPT + STATBLOCK
- | MODIFIERS_OPT + TYPE + IDENTIFIER + VAR_IDS + ";";
- // SCRIPT_ITEM.Rule = IMPORT | ENUM | TYPEDEF | CLASS | MIXIN | INTERFACE | FUNCDEF | VAR | VIRTPROP | FUNC | NAMESPACE | op_SEMI;
- SCRIPT_ITEM.Rule = IMPORT | ENUM | TYPEDEF | CLASS | MIXIN | INTERFACE | FUNCDEF | VFV | NAMESPACE | PreferShiftHere() + op_SEMI;
- // SCRIPT_ITEM.Rule = VFV | PreferShiftHere() + op_SEMI;
- SCRIPT.Rule = MakeStarRule(SCRIPT, SCRIPT_ITEM);
- // STATBLOCK ::= '{' {VAR | STATEMENT} '}'
- STATBLOCK.Rule = ToTerm("{") + VSS_OPT + "}";
- // STATEMENT ::= (IF | FOR | WHILE | RETURN | STATBLOCK | BREAK | CONTINUE | DOWHILE | SWITCH | EXPR_STAT)
- STATEMENT.Rule = IF | FOR | WHILE | RETURN | STATBLOCK | BREAK | CONTINUE | DOWHILE | SWITCH | EXPR_STAT;
- STATEMENTS_OTP.Rule = MakeStarRule(STATEMENTS_OTP, STATEMENT);
- // STRING ::= single token: single quoted ', "double quoted ", "or heredoc multi-line string """
- // No need to set a Rule because it is type: StringLiteral
- // SWITCH ::= 'switch' '(' ASSIGN ')' '{' {CASE} '}'
- SWITCH.Rule = k_SWITCH + "(" + ASSIGN + ")" + "{" + CASES_OPT + "}";
- // TYPE ::= ['const'] SCOPE DATATYPE ['<' TYPE {',' TYPE} '>'] { ('[' ']') | '@' }
- // NonTerminal TYPE_END = new NonTerminal("type_end");
- // TYPE_END.Rule = /*CustomActionHere(CheckIfLeftThenRightBracket) +*/ ToTerm("[") + "]" | "@";
- // NonTerminal TYPE_ENDS_OPT = new NonTerminal("type_ends_opt");
- // TYPE_ENDS_OPT.Rule = MakeStarRule(TYPE_ENDS_OPT, TYPE_END);
- NonTerminal TYPE_ENDS_OPT = new NonTerminal("type_ends_opt");
- //TYPE_ENDS_OPT.Rule = Empty | ToTerm("[") + "]" + TYPE_ENDS_OPT | "@" + TYPE_ENDS_OPT | "&";
- //TYPE.Rule = CONST_OPT + SCOPE_DATATYPE + "<" + TYPES + ">" + TYPE_ENDS_OPT
- // | CONST_OPT + SCOPE_DATATYPE + TYPE_ENDS_OPT;
- //TYPES.Rule = MakePlusRule(TYPES, ToTerm(","), TYPE);
- TYPE_ENDS_OPT.Rule = Empty | TYPE_ENDS_OPT + PreferShiftHere() + ToTerm("[") + "]" | TYPE_ENDS_OPT + PreferShiftHere() + "@";
- TYPES.Rule = TYPE | TYPES + "," + TYPE;
- TYPE.Rule = CONST_OPT + SCOPE_DATATYPE + "<" + TYPES + ">" + TYPE_ENDS_OPT
- | CONST_OPT + SCOPE_DATATYPE + TYPE_ENDS_OPT;
- // TYPEDEF ::= 'typedef' PRIMTYPE IDENTIFIER ';'
- TYPEDEF.Rule = k_TYPEDEF + PRIMTYPE + IDENTIFIER + ";";
- // TYPEMOD ::= ['&' ['in' | 'out' | 'inout']]
- TYPEMOD.Rule = Empty | "&" | ToTerm("&") + "in" | ToTerm("&") + "out" | ToTerm("&") + "inout";
- // VAR ::= ['private'|'protected'] TYPE IDENTIFIER [( '=' (INITLIST | EXPR)) | ARGLIST] {',' IDENTIFIER [( '=' (INITLIST | EXPR)) | ARGLIST]} ';'
- VAR_ID.Rule = IDENTIFIER
- | IDENTIFIER + "=" + INITLIST
- | IDENTIFIER + "=" + EXPR;
- VAR_IDS.Rule = MakePlusRule(VAR_IDS, ToTerm(","), VAR_ID);
- VAR.Rule = MODIFIERS_OPT + TYPE + IDENTIFIER + VAR_IDS + ";";
- // VARACCESS ::= SCOPE IDENTIFIER
- // VARACCESS.Rule = SCOPE_DATATYPE;
- // VIRTPROP ::= ['private' | 'protected'] TYPE ['&'] IDENTIFIER '{' {('get' | 'set') ['const'] [('override' | 'final')] (STATBLOCK | ';')} '}'
- VIRTPROP_ITEM.Rule = "get" + CONST_OPT + MODIFIERS_OPT + STATBLOCK
- | "set" + CONST_OPT + MODIFIERS_OPT + STATBLOCK
- | "get" + CONST_OPT + MODIFIERS_OPT + ";"
- | "set" + CONST_OPT + MODIFIERS_OPT + ";";
- VIRTPROP_ITEMS_OPT.Rule = MakeStarRule(VIRTPROP_ITEMS_OPT, VIRTPROP_ITEM);
- VIRTPROP.Rule = MODIFIERS_OPT + TYPE_AMP_OPT + IDENTIFIER + "{" + VIRTPROP_ITEMS_OPT + "}";
- // WHILE ::= 'while' '(' ASSIGN ')' STATEMENT
- // Note this matches the IF rule
- WHILE.Rule = k_WHILE + "(" + ASSIGN + ")" + STATEMENT;
- this.RegisterBracePair("[", "]");
- this.RegisterBracePair("<", ">");
- this.RegisterBracePair("(", ")");
- this.RegisterBracePair("{", "}");
- this.MarkPunctuation(",", ";", "(", ")", "{", "}", "[", "]");
- // This was taken from: http://www.angelcode.com/angelscript/sdk/docs/manual/doc_operator_precedence.html
- // However it doesn't include some operators (TODO: list them here...)
- RegisterOperators(1, Associativity.Right, op_ASSIGN, op_PLUS_ASSIGN, op_MINUS_ASSIGN, op_STAR_ASSIGN, op_SLASH_ASSIGN, op_PERCENT_ASSIGN, op_STAR_STAR_ASSIGN, op_AMP_ASSIGN, op_BAR_ASSIGN, op_CARET_ASSIGN, op_SHL_ASSIGN, op_SHR_ASSIGN, op_USHR_ASSIGN);
- RegisterOperators(2, Associativity.Right, op_QMARK, op_COLON);
- RegisterOperators(3, Associativity.Left, op_OR, op_BAR_BAR);
- RegisterOperators(4, Associativity.Left, op_AND, op_AMP_AMP);
- RegisterOperators(5, Associativity.Left, op_EQ, op_NEQ, op_IS, op_IS_NOT, op_XOR, op_CARET_CARET);
- RegisterOperators(6, Associativity.Left, op_LTEQ, op_LT, op_GTEQ, op_GT);
- RegisterOperators(7, Associativity.Left, op_BAR);
- RegisterOperators(8, Associativity.Left, op_CARET);
- RegisterOperators(9, Associativity.Left, op_AMP);
- RegisterOperators(10, Associativity.Left, op_SHL, op_SHR, op_USHR);
- RegisterOperators(11, Associativity.Left, op_PLUS, op_MINUS);
- RegisterOperators(12, Associativity.Left, op_STAR, op_SLASH, op_PERCENT);
- RegisterOperators(13, Associativity.Left, op_STAR_STAR);
- RegisterOperators(14, Associativity.Left, op_AT);
- RegisterOperators(15, Associativity.Right, op_TILDE);
- RegisterOperators(16, Associativity.Right, op_NOT, op_EMARK);
- RegisterOperators(17, Associativity.Left, op_DOT);
- RegisterOperators(18, Associativity.Right, op_PLUS_PLUS, op_MINUS_MINUS);
- RegisterOperators(19, Associativity.Neutral, op_R_BKT);
- RegisterOperators(20, Associativity.Right, op_COLON_COLON);
- }
- public KeyTerm Keyword(string keyword)
- {
- var term = ToTerm(keyword, keyword);
- // term.SetOption(TermOptions.IsKeyword, true);
- // term.SetOption(TermOptions.IsReservedWord, true);
- this.MarkReservedWords(keyword);
- term.EditorInfo = new TokenEditorInfo(TokenType.Keyword, TokenColor.Keyword, TokenTriggers.None);
- return term;
- }
- public KeyTerm Operator(string text, string name)
- {
- //string opCased = this.CaseSensitive ? op : op.ToLower();
- //var term = new KeyTerm(opCased, op);
- //term.SetOption(TermOptions.IsOperator, true);
- //term.EditorInfo = new TokenEditorInfo(TokenType.Operator, TokenColor.Keyword, TokenTriggers.None);
- var term = ToTerm(text, name);
- return term;
- }
- public static NumberLiteral CreateAngelScriptNumber(string name)
- {
- NumberLiteral term = new NumberLiteral(name, NumberOptions.AllowStartEndDot);
- //default int types are Integer (32bit) -> LongInteger (BigInt); Try Int64 before BigInt: Better performance?
- term.DefaultIntTypes = new TypeCode[] { TypeCode.Int32, TypeCode.Int64 };
- term.DefaultFloatType = TypeCode.Double; // it is default
- term.AddPrefix("0b", NumberOptions.Binary);
- term.AddPrefix("0o", NumberOptions.Octal);
- term.AddPrefix("0d", NumberOptions.IntOnly);
- term.AddPrefix("0x", NumberOptions.Hex);
- term.AddSuffix("f", TypeCode.Double);
- return term;
- }
- } // class
- } // namespace
- /*
- Shift
- Accept the basic symbol as the corresponding terminal, push a new state onto
- the stack, and examine the next basic symbol.
- Reduce
- Note that a specific phrase has been recognized, remove a number of states
- equal to the number of symbols in the sequence of the corresponding production
- from the stack, push a new state onto the stack, and examine the current
- basic symbol again.
- A Shift step advances in the input stream by one symbol.
- That shifted symbol becomes a new single-node parse tree.
- A Reduce step applies a completed grammar rule to some of the recent parse trees,
- joining them together as one tree with a new root symbol.
- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement