Advertisement
Guest User

Untitled

a guest
Jun 24th, 2015
260
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 36.01 KB | None | 0 0
  1. /*
  2. * NonTerminals have capital names with no prefixes
  3. * to match the official BNF specification for AngelScript.
  4. *
  5. * If a NonTerminal makes use of a PlusList it will have a suffix of "S" to denote 1..n.
  6. * If a NonTerminal makes use of a StarList it will have a suffix of "S_OPT" to denote 0..n.
  7. */
  8.  
  9. using Irony.Parsing;
  10. using System;
  11. using System.Collections.Generic;
  12. using System.Linq;
  13. using System.Text;
  14. using System.Threading.Tasks;
  15.  
  16. using System.Diagnostics; // added for Debug.Print
  17.  
  18.  
  19. namespace AngelScript
  20. {
  21. [Language("Angel Script", "1.0", "Angel Script Programming Language")]
  22. public class AngelScriptGrammar : Irony.Parsing.Grammar
  23. {
  24. public AngelScriptGrammar()
  25. {
  26. // Comments
  27. var singleLineComment = new CommentTerminal("SingleLineComment", "//", "\r", "\n", "\u2085", "\u2028", "\u2029");
  28. var delimitedComment = new CommentTerminal("DelimitedComment", "/*", "*/");
  29. NonGrammarTerminals.Add(singleLineComment);
  30. NonGrammarTerminals.Add(delimitedComment);
  31.  
  32.  
  33. // Symbols / Operators
  34. #region Operators
  35. var op_ASSIGN = Operator("=", "op_assign");
  36. var op_PLUS_ASSIGN = Operator("+=", "plus_assign");
  37. var op_MINUS_ASSIGN = Operator("-=", "minus_assign");
  38. var op_STAR_ASSIGN = Operator("*=", "star_assign");
  39. var op_STAR_STAR_ASSIGN = Operator("**=", "star_star_assign");
  40. var op_SLASH_ASSIGN = Operator("/=", "slash_assign");
  41. var op_AMP_ASSIGN = Operator("&=", "amp_assign");
  42. var op_BAR_ASSIGN = Operator("|=", "bar_assign");
  43. var op_CARET_ASSIGN = Operator("^=", "caret_assign");
  44. var op_PERCENT_ASSIGN = Operator("%=", "percent_assign");
  45. var op_SHL_ASSIGN = Operator("<<=", "shl_assign");
  46. var op_SHR_ASSIGN = Operator(">>=", "shr_assign");
  47. var op_USHR_ASSIGN = Operator(">>>=", "ushr_assign");
  48.  
  49. var op_AMP = Operator("&", "amp");
  50. var op_AT = Operator("@", "at");
  51. var op_BAR = Operator("|", "bar");
  52. var op_CARET = Operator("^", "caret");
  53. var op_COMMA = Operator(",", "comma");
  54. var op_DOT = Operator(".", "dot");
  55. var op_EMARK = Operator("!", "emark");
  56. var op_MINUS = Operator("-", "minus");
  57. var op_PERCENT = Operator("%", "percent");
  58. var op_PLUS = Operator("+", "plus");
  59. var op_QMARK = Operator("?", "qmark");
  60. var op_STAR = Operator("*", "star");
  61. var op_SLASH = Operator("/", "slash");
  62. var op_TILDE = Operator("~", "tilde");
  63.  
  64. var op_AMP_AMP = Operator("&&", "amp_amp");
  65. var op_BAR_BAR = Operator("||", "bar_bar");
  66. var op_CARET_CARET = Operator("^^", "caret_caret");
  67. var op_MINUS_MINUS = Operator("--", "minus");
  68. var op_PLUS_PLUS = Operator("++", "plus_plus");
  69. var op_SHL = Operator("<<", "shl");
  70. var op_SHR = Operator(">>", "shr");
  71. var op_STAR_STAR = Operator("**", "star_star");
  72. var op_USHR = Operator(">>>", "ushr");
  73.  
  74. var op_L_BKT = Operator("[", "l_bkt");
  75. var op_R_BKT = Operator("]", "r_bkt");
  76. var op_L_BRC = Operator("{", "l_brc");
  77. var op_R_BRC = Operator("}", "r_brc");
  78. var op_L_PAR = Operator("(", "l_par");
  79. var op_R_PAR = Operator(")", "r_par");
  80. var op_COLON = Operator(":", "colon");
  81. var op_COLON_COLON = Operator("::", "colon_colon");
  82. var op_SEMI = Operator(";", "semi");
  83.  
  84. var op_EQ = Operator("==", "eq");
  85. var op_NEQ = Operator("!=", "neq");
  86. var op_GT = Operator(">", "gt");
  87. var op_GTEQ = Operator(">=", "gteq");
  88. var op_LT = Operator("<", "lt");
  89. var op_LTEQ = Operator("<=", "lteq");
  90.  
  91. var op_AND = Operator("and", "and");
  92. var op_IS = Operator("is", "is");
  93. var op_IS_NOT = Operator("!is", "is_not");
  94. var op_NOT = Operator("not", "not");
  95. var op_OR = Operator("or", "or");
  96. var op_XOR = Operator("xor", "xor");
  97. #endregion
  98.  
  99.  
  100. // Keywords
  101. #region Keywords
  102. KeyTerm k_AND = Keyword("and");
  103. KeyTerm k_ABSTRACT = Keyword("abstract");
  104. KeyTerm k_AUTO = Keyword("auto");
  105. KeyTerm k_BOOL = Keyword("bool");
  106. KeyTerm k_BREAK = Keyword("break");
  107. KeyTerm k_CASE = Keyword("case");
  108. KeyTerm k_CAST = Keyword("cast");
  109. KeyTerm k_CLASS = Keyword("class");
  110. KeyTerm k_CONST = Keyword("const");
  111. KeyTerm k_CONTINUE = Keyword("continue");
  112. KeyTerm k_DEFAULT = Keyword("default");
  113. KeyTerm k_DO = Keyword("do");
  114. KeyTerm k_DOUBLE = Keyword("double");
  115. KeyTerm k_ELSE = Keyword("else");
  116. KeyTerm k_ENUM = Keyword("enum");
  117. KeyTerm k_FALSE = Keyword("false");
  118. KeyTerm k_FINAL = Keyword("final");
  119. KeyTerm k_FLOAT = Keyword("float");
  120. KeyTerm k_FOR = Keyword("for");
  121. KeyTerm k_FROM = Keyword("from");
  122. KeyTerm k_FUNCDEF = Keyword("funcdef");
  123. KeyTerm k_GET = Keyword("get");
  124. KeyTerm k_IF = Keyword("if");
  125. KeyTerm k_IMPORT = Keyword("import");
  126. KeyTerm k_IN = Keyword("in");
  127. KeyTerm k_INOUT = Keyword("inout");
  128. KeyTerm k_INT = Keyword("int");
  129. KeyTerm k_INTERFACE = Keyword("interface");
  130. KeyTerm k_INT8 = Keyword("int8");
  131. KeyTerm k_INT16 = Keyword("int16");
  132. KeyTerm k_INT32 = Keyword("int32");
  133. KeyTerm k_INT64 = Keyword("int64");
  134. KeyTerm k_IS = Keyword("is");
  135. KeyTerm k_MIXIN = Keyword("mixin");
  136. KeyTerm k_NAMESPACE = Keyword("namespace");
  137. KeyTerm k_NOT = Keyword("not");
  138. KeyTerm k_NULL = Keyword("null");
  139. KeyTerm k_OR = Keyword("or");
  140. KeyTerm k_OUT = Keyword("out");
  141. KeyTerm k_OVERRIDE = Keyword("override");
  142. KeyTerm k_PRIVATE = Keyword("private");
  143. KeyTerm k_PROTECTED = Keyword("protected");
  144. KeyTerm k_RETURN = Keyword("return");
  145. KeyTerm k_SET = Keyword("set");
  146. KeyTerm k_SHARED = Keyword("shared");
  147. KeyTerm k_SUPER = Keyword("super");
  148. KeyTerm k_SWITCH = Keyword("switch");
  149. KeyTerm k_THIS = Keyword("this");
  150. KeyTerm k_TRUE = Keyword("true");
  151. KeyTerm k_TYPEDEF = Keyword("typedef");
  152. KeyTerm k_UINT = Keyword("uint");
  153. KeyTerm k_UINT8 = Keyword("uint8");
  154. KeyTerm k_UINT16 = Keyword("uint16");
  155. KeyTerm k_UINT32 = Keyword("uint32");
  156. KeyTerm k_UINT64 = Keyword("uint64");
  157. KeyTerm k_VOID = Keyword("void");
  158. KeyTerm k_WHILE = Keyword("while");
  159. KeyTerm k_XOR = Keyword("xor");
  160. #endregion
  161.  
  162.  
  163. var IDENTIFIER = new IdentifierTerminal("identifier");
  164. var NUMBER = CreateAngelScriptNumber("number");
  165. var STRING = new StringLiteral("string", "\"");
  166.  
  167.  
  168. // NonTerminals
  169. NonTerminal ARGLIST = new NonTerminal("arglist");
  170. NonTerminal ASSIGN = new NonTerminal("assign");
  171. NonTerminal ASSIGNOP = new NonTerminal("assignop");
  172. NonTerminal BITOP = new NonTerminal("bitop");
  173. NonTerminal BREAK = new NonTerminal("break");
  174. NonTerminal CASE = new NonTerminal("case");
  175. NonTerminal CASES_OPT = new NonTerminal("case_opt");
  176. NonTerminal CAST = new NonTerminal("cast");
  177. NonTerminal CLASS = new NonTerminal("class");
  178. NonTerminal COMPOP = new NonTerminal("compop");
  179. NonTerminal CONDITION = new NonTerminal("condition");
  180. NonTerminal CONSTRUCTCALL = new NonTerminal("constructcall");
  181. NonTerminal CONTINUE = new NonTerminal("continue");
  182. NonTerminal DOWHILE = new NonTerminal("dowhile");
  183. NonTerminal DATATYPE = new NonTerminal("datatype");
  184. NonTerminal ENUM = new NonTerminal("enum");
  185. NonTerminal ENUM_ITEM = new NonTerminal("enum_item");
  186. NonTerminal ENUM_ITEMS = new NonTerminal("enum_items");
  187. NonTerminal EXPR = new NonTerminal("expr");
  188. NonTerminal EXPR_OP = new NonTerminal("expr_op");
  189. NonTerminal EXPR_OP_TERM = new NonTerminal("expr_op_term");
  190. NonTerminal EXPR_POSTOP = new NonTerminal("expr_postop");
  191. NonTerminal EXPR_POSTOPS_OPT = new NonTerminal("expr_postops_opt");
  192. NonTerminal EXPR_PREOP = new NonTerminal("expr_preop");
  193. NonTerminal EXPR_PREOPS_OPT = new NonTerminal("expr_preops_opt");
  194. NonTerminal EXPR_STAT = new NonTerminal("expr_stat");
  195. NonTerminal EXPR_TERM = new NonTerminal("expr_term");
  196. NonTerminal EXPR_VALUE = new NonTerminal("expr_value");
  197. NonTerminal FOR = new NonTerminal("for");
  198. NonTerminal FUNC = new NonTerminal("func");
  199. NonTerminal FUNC_MOD2 = new NonTerminal("func_mod2");
  200. NonTerminal FUNCCALL = new NonTerminal("funccall");
  201. NonTerminal FUNCDEF = new NonTerminal("funcdef");
  202. NonTerminal IF = new NonTerminal("if");
  203. NonTerminal IF_ELSE = new NonTerminal("if_else");
  204. NonTerminal IMPORT = new NonTerminal("import");
  205. NonTerminal INITLIST = new NonTerminal("initlist");
  206. NonTerminal INITLIST_OR_ASSIGN = new NonTerminal("initlist_or_assign");
  207. NonTerminal INITLIST_OR_ASSIGNS_OPT = new NonTerminal("initlist_or_assigns_opt");
  208. NonTerminal INTERFACE = new NonTerminal("interface");
  209. // NonTerminal INTFMTHD = new NonTerminal("intfmthd");
  210. NonTerminal LITERAL = new NonTerminal("literal");
  211. NonTerminal LOGICOP = new NonTerminal("logicop");
  212. NonTerminal MATHOP = new NonTerminal("mathop");
  213. NonTerminal MIXIN = new NonTerminal("mixin");
  214. NonTerminal NAMESPACE = new NonTerminal("namespace");
  215. NonTerminal PARAMLIST = new NonTerminal("paramlist");
  216. NonTerminal PRIMTYPE = new NonTerminal("primtype");
  217. NonTerminal RETURN = new NonTerminal("return");
  218. NonTerminal SCOPE_DATATYPE = new NonTerminal("scope_datatype");
  219. NonTerminal SCRIPT = new NonTerminal("script");
  220. NonTerminal SCRIPT_ITEM = new NonTerminal("script_item");
  221. NonTerminal STATBLOCK = new NonTerminal("statblock");
  222. NonTerminal STATEMENT = new NonTerminal("statement");
  223. NonTerminal STATEMENTS_OTP = new NonTerminal("statements_opt");
  224. NonTerminal SWITCH = new NonTerminal("switch");
  225. NonTerminal TYPE = new NonTerminal("type");
  226. NonTerminal TYPES = new NonTerminal("types");
  227. NonTerminal TYPEDEF = new NonTerminal("typedef");
  228. NonTerminal TYPEMOD = new NonTerminal("typemod");
  229. NonTerminal VAR = new NonTerminal("var");
  230. NonTerminal VAR_ID = new NonTerminal("var_id");
  231. NonTerminal VAR_IDS = new NonTerminal("var_ids");
  232. // NonTerminal VARACCESS = new NonTerminal("varaccess");
  233. NonTerminal VIRTPROP = new NonTerminal("virtprop");
  234. NonTerminal VIRTPROP_ITEM = new NonTerminal("virtprop_item");
  235. NonTerminal VIRTPROP_ITEMS_OPT = new NonTerminal("virtprop_items_opt");
  236. NonTerminal WHILE = new NonTerminal("while");
  237.  
  238.  
  239.  
  240.  
  241. NonTerminal ASSIGNS_OPT = new NonTerminal("assigns_opt");
  242. ASSIGNS_OPT.Rule = MakeStarRule(ASSIGNS_OPT, ToTerm(","), ASSIGN);
  243.  
  244. NonTerminal CONST_OPT = new NonTerminal("const_opt");
  245. CONST_OPT.Rule = Empty | "const";
  246.  
  247. NonTerminal IDENTIFIERS_OPT = new NonTerminal("identifiers_opt");
  248. IDENTIFIERS_OPT.Rule = MakeStarRule(IDENTIFIERS_OPT, ToTerm(","), IDENTIFIER);
  249.  
  250. NonTerminal IDENTIFIER_CA = new NonTerminal("identifier_ca");
  251. IDENTIFIER_CA.Rule = ASSIGN | PreferShiftHere() + IDENTIFIER + ":" + ASSIGN;
  252. NonTerminal IDENTIFIER_CAS = new NonTerminal("identifier_cas");
  253. IDENTIFIER_CAS.Rule = MakePlusRule(IDENTIFIER_CAS, ToTerm(","), IDENTIFIER_CA);
  254.  
  255. NonTerminal MODIFIER = new NonTerminal("modifier");
  256. MODIFIER.Rule = ToTerm("private") | "protected" | "shared" | "abstract" | "final" | "override";
  257. NonTerminal MODIFIERS_OPT = new NonTerminal("modifiers_opt");
  258. //MODIFIERS_OPT.Rule = MakeStarRule(MODIFIERS_OPT, MODIFIER);
  259. MODIFIERS_OPT.Rule = Empty | MODIFIER + MODIFIERS_OPT | MODIFIER + ReduceHere();
  260.  
  261. NonTerminal TYPE_AMP_OPT = new NonTerminal("type_amp_opt");
  262. // TYPE_AMP_OPT.Rule = TYPE | TYPE + "&";
  263. TYPE_AMP_OPT.Rule = TYPE;
  264.  
  265. NonTerminal VFV = new NonTerminal("vfv");
  266. NonTerminal FUNC_MOD2_ID = new NonTerminal("func_mod2_id");
  267. NonTerminal VFV_TYPES_OPT = new NonTerminal("vfv_types_opt");
  268. // FUNC_MOD2_ID.Rule = IDENTIFIER | TYPE + IDENTIFIER | TYPE + "&" + IDENTIFIER | "~" + IDENTIFIER;
  269. // FUNC_MOD2_ID.Rule = Empty | TYPE | "~" | TYPE + IDENTIFIER | TYPE + IDENTIFIER + IDENTIFIER;
  270. VFV_TYPES_OPT.Rule = Empty | TYPE + VFV_TYPES_OPT;
  271. FUNC_MOD2_ID.Rule = VFV_TYPES_OPT | "~";
  272. // VFV.Rule = VIRTPROP | FUNC | VAR;
  273. // VFV.Rule = MODIFIERS_OPT + TYPE_AMP_OPT + IDENTIFIER + "{" + VIRTPROP_ITEMS_OPT + "}"
  274. // | MODIFIERS_OPT + FUNC_MOD2 + IDENTIFIER + PARAMLIST + CONST_OPT + MODIFIERS_OPT + STATBLOCK
  275. // | MODIFIERS_OPT + TYPE + IDENTIFIER + VAR_IDS + ";";
  276. NonTerminal VFV_VAR_ID = new NonTerminal("vfv_var_id");
  277. VFV_VAR_ID.Rule = Empty
  278. | "=" + INITLIST
  279. | "=" + EXPR;
  280. NonTerminal VFV_VAR_IDS = new NonTerminal("vfv_var_ids");
  281. VFV_VAR_IDS.Rule = VFV_VAR_ID | VFV_VAR_ID + "," + IDENTIFIER;
  282.  
  283. NonTerminal VFV_END = new NonTerminal("vfv_end");
  284. VFV_END.Rule = "{" + VIRTPROP_ITEMS_OPT + "}"
  285. | PARAMLIST + CONST_OPT + MODIFIERS_OPT + STATBLOCK
  286. | VFV_VAR_IDS + ";";
  287.  
  288. VFV.Rule = MODIFIERS_OPT + FUNC_MOD2_ID + VFV_END;
  289.  
  290. NonTerminal VFVS_OPT = new NonTerminal("vfvs_otp");
  291. VFVS_OPT.Rule = MakeStarRule(VFVS_OPT, VFV);
  292.  
  293. NonTerminal VS = new NonTerminal("vs");
  294. VS.Rule = VAR | STATEMENT;
  295. NonTerminal VSS_OPT = new NonTerminal("vss_otp");
  296. VSS_OPT.Rule = MakeStarRule(VSS_OPT, VS);
  297.  
  298.  
  299.  
  300.  
  301. // Rules
  302. this.Root = SCRIPT;
  303.  
  304. // ARGLIST ::= '(' [IDENTIFIER ':'] ASSIGN {',' [IDENTIFIER ':'] ASSIGN} ')'
  305. ARGLIST.Rule = ToTerm("(") + IDENTIFIER_CAS + ")";
  306.  
  307. // ASSIGN ::= CONDITION [ ASSIGNOP ASSIGN ]
  308. ASSIGN.Rule = CONDITION | CONDITION + ASSIGNOP + ASSIGN;
  309.  
  310. // ASSIGNOP ::= '=' | '+=' | '-=' | '*=' | '/=' | '|=' | '&=' | '^=' | '%=' | '**=' | '<<=' | '>>=' | '>>>='
  311. 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;
  312.  
  313. // BITOP ::= '&' | '|' | '^' | '<<' | '>>' | '>>>'
  314. BITOP.Rule = op_AMP | op_BAR | op_CARET | op_SHL | op_SHR | op_USHR;
  315.  
  316. // BITS ::= single token: binary 0b or 0B, "octal 0o or 0O, "decimal 0d or 0D, "hexadecimal 0x or 0X
  317. // This is treated the same as NUMBER
  318.  
  319. // BREAK ::= 'break' ';'
  320. BREAK.Rule = k_BREAK + op_SEMI;
  321.  
  322. // CASE ::= (('case' EXPR) | 'default') ':' {STATEMENT}
  323. CASE.Rule = k_CASE + EXPR + ":" + STATEMENTS_OTP
  324. | k_DEFAULT + ":" + STATEMENTS_OTP;
  325. CASES_OPT.Rule = MakeStarRule(CASES_OPT, CASE);
  326.  
  327. // CAST ::= 'cast' '<' TYPE '>' '(' ASSIGN ')'
  328. CAST.Rule = k_CAST + "<" + TYPE + ">" + "(" + ASSIGN + ")";
  329.  
  330. // CLASS ::= {'shared' | 'abstract' | 'final'} 'class' IDENTIFIER [':' IDENTIFIER {',' IDENTIFIER}] '{' {VIRTPROP | FUNC | VAR} '}'
  331. CLASS.Rule = MODIFIERS_OPT + k_CLASS + IDENTIFIER + "{" + VFVS_OPT + "}"
  332. | MODIFIERS_OPT + k_CLASS + IDENTIFIER + ":" + IDENTIFIERS_OPT + "{" + VFVS_OPT + "}";
  333.  
  334. // COMPOP ::= '==' | '!=' | '<' | '<=' | '>' | '>=' | 'is' | '!is'
  335. COMPOP.Rule = op_EQ | op_NEQ | op_LT | op_LTEQ | op_GT | op_GTEQ | op_IS | op_IS_NOT;
  336.  
  337. // CONDITION ::= EXPR ['?' ASSIGN ':' ASSIGN]
  338. CONDITION.Rule = EXPR | EXPR + "?" + ASSIGN + ":" + ASSIGN;
  339.  
  340. // CONSTRUCTCALL::= TYPE ARGLIST
  341. CONSTRUCTCALL.Rule = TYPE + ARGLIST;
  342.  
  343. // CONTINUE ::= 'continue' ';'
  344. CONTINUE.Rule = k_CONTINUE + op_SEMI;
  345.  
  346. // DATATYPE ::= (IDENTIFIER | PRIMTYPE | '?' | 'auto')
  347. DATATYPE.Rule = IDENTIFIER | PRIMTYPE | op_QMARK | k_AUTO;
  348.  
  349. // DOWHILE ::= 'do' STATEMENT 'while' '(' ASSIGN ')' ';'
  350. DOWHILE.Rule = k_DO + STATEMENT + k_WHILE + "(" + ASSIGN + ")" + ";";
  351.  
  352. // ENUM ::= ['shared'] 'enum' IDENTIFIER '{' IDENTIFIER ['=' EXPR] {',' IDENTIFIER ['=' EXPR]} '}'
  353. ENUM_ITEM.Rule = IDENTIFIER | IDENTIFIER + "=" + EXPR;
  354. ENUM_ITEMS.Rule = MakeStarRule(ENUM_ITEMS, ToTerm(","), ENUM_ITEM);
  355. ENUM.Rule = MODIFIERS_OPT + "enum" + IDENTIFIER + "{" + ENUM_ITEMS + "}";
  356.  
  357.  
  358.  
  359.  
  360. // EXPR ::= (TYPE '=' INITLIST) | (EXPR_TERM {EXPR_OP EXPR_TERM})
  361. // (TYPE '=' INITLIST) gets rolled into VOID_CONSTRUCTCALL_FUNCCALL_VARACCESS.
  362. // And VOID_CONSTRUCTCALL_FUNCCALL_VARACCESS can be reached via EXPR2.
  363. // So it doesn't have to be included here.
  364. // EXPR_OP_TERM.Rule = Empty | EXPR_OP + EXPR_TERM | EXPR_OP + EXPR_TERM + EXPR_OP_TERM;
  365. // EXPR.Rule = EXPR_TERM + EXPR_OP_TERM;
  366. // EXPR.Rule = EXPR_TERM | EXPR_TERM + EXPR_OP + EXPR;
  367. EXPR.Rule = EXPR_PREOPS_OPT + EXPR_VALUE + EXPR_POSTOPS_OPT + ReduceHere()
  368. | EXPR_PREOPS_OPT + EXPR_VALUE + EXPR_POSTOPS_OPT + PreferShiftHere() + EXPR_OP + EXPR + ReduceHere();
  369.  
  370. // EXPR_OP ::= MATHOP | COMPOP | LOGICOP | BITOP
  371. EXPR_OP.Rule = MATHOP | COMPOP | LOGICOP | BITOP;
  372.  
  373. // EXPR_POSTOP ::= ('.' (FUNCCALL | IDENTIFIER))
  374. // | ('[' [IDENTIFIER ':'] ASSIGN {',' [IDENTIFIER ':'] ASSIGN} ']')
  375. // | ARGLIST | '++' | '--'
  376. // We simply this by realising that it is only used in from EXPR_POSTOPS_OPT.
  377. // So we can remove ('.' FUNCCALL) and replace ('.' IDENTIFIER) with ('.' SCOPE_DATATYPE).
  378. EXPR_POSTOP.Rule = op_DOT + SCOPE_DATATYPE + ReduceHere()
  379. // TODO: uncomment this and try adding it in only where it is used
  380. | ToTerm("[") + IDENTIFIER_CAS + "]" + ReduceHere()
  381. | ARGLIST // ToTerm("(") + IDENTIFIER_CAS + ")"
  382. | op_PLUS_PLUS
  383. | op_MINUS_MINUS;
  384. EXPR_POSTOPS_OPT.Rule = MakeStarRule(EXPR_POSTOPS_OPT, EXPR_POSTOP);
  385.  
  386. // EXPR_PREOP ::= '-' | '+' | '!' | '++' | '--' | '~' | '@'
  387. EXPR_PREOP.Rule = op_MINUS | op_PLUS | op_EMARK | op_PLUS_PLUS | op_MINUS_MINUS | op_TILDE | op_AT;
  388. EXPR_PREOPS_OPT.Rule = MakeStarRule(EXPR_PREOPS_OPT, EXPR_PREOP);
  389.  
  390. // EXPR_STAT ::= [ASSIGN] ';'
  391. EXPR_STAT.Rule = ASSIGN + ";" | ";";
  392.  
  393. // EXPR_TERM ::= {EXPR_PREOP} EXPR_VALUE {EXPR_POSTOP}
  394. // EXPR_TERM.Rule = EXPR_PREOPS_OPT + EXPR_VALUE + EXPR_POSTOPS_OPT;
  395.  
  396. // Original Rule: EXPR_VALUE ::= 'void' | CONSTRUCTCALL | FUNCCALL | VARACCESS | CAST | LITERAL | '(' ASSIGN ')'
  397. // VOID_CONSTRUCTCALL_FUNCCALL_VARACCESS ::= TYPE [ARGLIST]
  398. NonTerminal VOID_CONSTRUCTCALL_FUNCCALL_VARACCESS = new NonTerminal("void_constructcall_funccall_varaccess");
  399. // We remove the ARGLIST from the rule below because is can be reached by EXPR_POSTOP
  400. VOID_CONSTRUCTCALL_FUNCCALL_VARACCESS.Rule = TYPE
  401. | TYPE + "=" + INITLIST;
  402. // We combine CONSTRUCTCALL and FUNCCALL and VARACCESS into one state since they are so similar.
  403. // We also combine k_VOID into it since it can be made from TYPE.
  404. // We also combine EXPR1 into it by adding an optional ("+" + INITLIST) at the end
  405. EXPR_VALUE.Rule = VOID_CONSTRUCTCALL_FUNCCALL_VARACCESS | CAST | LITERAL | "(" + ASSIGN + ")";
  406.  
  407. // FOR ::= 'for' '(' (VAR | EXPR_STAT) EXPR_STAT [ASSIGN {',' ASSIGN}] ')' STATEMENT
  408. FOR.Rule = k_FOR + "(" + VAR + EXPR_STAT + ASSIGNS_OPT + ")" + STATEMENT
  409. | k_FOR + "(" + EXPR_STAT + EXPR_STAT + ASSIGNS_OPT + ")" + STATEMENT;
  410.  
  411. // FUNC ::= ['private' | 'protected' | 'shared'] [((TYPE ['&']) | '~')] IDENTIFIER PARAMLIST ['const'] {'override' | 'final'} STATBLOCK
  412. FUNC_MOD2.Rule = Empty | TYPE_AMP_OPT | "~";
  413. FUNC.Rule = MODIFIERS_OPT + FUNC_MOD2 + IDENTIFIER + PARAMLIST + CONST_OPT + MODIFIERS_OPT + STATBLOCK;
  414.  
  415. // FUNCCALL ::= SCOPE IDENTIFIER ARGLIST
  416. FUNCCALL.Rule = SCOPE_DATATYPE + ARGLIST;
  417.  
  418. // FUNCDEF ::= 'funcdef' TYPE ['&'] IDENTIFIER PARAMLIST ';'
  419. FUNCDEF.Rule = k_FUNCDEF + TYPE_AMP_OPT + IDENTIFIER + PARAMLIST + op_SEMI;
  420.  
  421. // IDENTIFIER ::= single token: starts with letter or _, can include any letter and digit, same as in C++
  422. // No need to set a Rule because it is type: IdentifierTerminal
  423.  
  424. // IF ::= 'if' '(' ASSIGN ')' STATEMENT ['else' STATEMENT]
  425. IF_ELSE.Rule = Empty | PreferShiftHere() + k_ELSE + STATEMENT;
  426. IF.Rule = k_IF + "(" + ASSIGN + ")" + STATEMENT + IF_ELSE;
  427.  
  428. // IMPORT ::= 'import' TYPE ['&'] IDENTIFIER PARAMLIST 'from' STRING ';'
  429. IMPORT.Rule = "import" + TYPE_AMP_OPT + IDENTIFIER + PARAMLIST + "from" + STRING + op_SEMI;
  430.  
  431. // INITLIST ::= '{' [ASSIGN | INITLIST] {',' [ASSIGN | INITLIST]} '}'
  432. INITLIST_OR_ASSIGN.Rule = ASSIGN | INITLIST;
  433. INITLIST_OR_ASSIGNS_OPT.Rule = MakeStarRule(INITLIST_OR_ASSIGNS_OPT, ToTerm(","), INITLIST_OR_ASSIGN);
  434. INITLIST.Rule = ToTerm("{") + INITLIST_OR_ASSIGNS_OPT + "}";
  435.  
  436. // INTERFACE ::= ['shared'] 'interface' IDENTIFIER [':' IDENTIFIER {',' IDENTIFIER}] '{' {VIRTPROP | INTFMTHD} '}'
  437. NonTerminal INTERFACE_IV = new NonTerminal("interface_iv");
  438. INTERFACE_IV.Rule = MODIFIERS_OPT + TYPE_AMP_OPT + IDENTIFIER + PARAMLIST + CONST_OPT + ";"
  439. | MODIFIERS_OPT + TYPE_AMP_OPT + IDENTIFIER + "{" + VIRTPROP_ITEMS_OPT + "}";
  440. // INTERFACE_IV.Rule = INTFMTHD | VIRTPROP;
  441. NonTerminal INTERFACE_IVS_OPT = new NonTerminal("interface_ivs_opt");
  442. INTERFACE_IVS_OPT.Rule = MakeStarRule(INTERFACE_IVS_OPT, INTERFACE_IV);
  443. INTERFACE.Rule = MODIFIERS_OPT + k_INTERFACE + IDENTIFIER + "{" + INTERFACE_IVS_OPT + "}"
  444. | MODIFIERS_OPT + k_INTERFACE + IDENTIFIER + ":" + IDENTIFIERS_OPT + "{" + INTERFACE_IVS_OPT + "}";
  445.  
  446. // INTFMTHD ::= TYPE ['&'] IDENTIFIER PARAMLIST ['const'] ';'
  447. // INTFMTHD.Rule = TYPE_AMP_OPT + IDENTIFIER + PARAMLIST + CONST_OPT + ";";
  448.  
  449. // LITERAL ::= NUMBER | STRING | BITS | 'true' | 'false' | 'null'
  450. LITERAL.Rule = NUMBER | STRING | k_TRUE | k_FALSE | k_NULL;
  451.  
  452. // LOGICOP ::= '&&' | '||' | '^^' | 'and' | 'or' | 'xor'
  453. LOGICOP.Rule = op_AMP_AMP | op_BAR_BAR | op_CARET_CARET | op_AND | op_OR | op_XOR;
  454.  
  455. // MATHOP ::= '+' | '-' | '*' | '/' | '%' | '**'
  456. MATHOP.Rule = op_PLUS | op_MINUS | op_STAR | op_SLASH | op_PERCENT | op_STAR_STAR;
  457.  
  458. // MIXIN ::= 'mixin' CLASS
  459. MIXIN.Rule = "mixin" + CLASS;
  460.  
  461. // NAMESPACE ::= 'namespace' IDENTIFIER '{' SCRIPT '}'
  462. NAMESPACE.Rule = k_NAMESPACE + IDENTIFIER + "{" + SCRIPT + "}";
  463.  
  464. // NUMBER ::= single token: includes integers and real numbers, same as C++
  465. // No need to set a Rule because it is type: CreateAngelScriptNumber
  466.  
  467. // PARAMLIST ::= '(' ('void' | (TYPE TYPEMOD [IDENTIFIER] ['=' EXPR] {',' TYPE TYPEMOD [IDENTIFIER] ['=' EXPR]})) ')'
  468. // Note: Void is not explicitly included because it can be reached via: PARAMLIST_TYPE -> TYPE
  469. NonTerminal PARAMLIST_TYPE = new NonTerminal("paramlist_type");
  470. PARAMLIST_TYPE.Rule = TYPE + TYPEMOD
  471. | TYPE + TYPEMOD + "=" + EXPR
  472. | TYPE + TYPEMOD + IDENTIFIER
  473. | TYPE + TYPEMOD + IDENTIFIER + "=" + EXPR;
  474. NonTerminal PARAMLIST_TYPES = new NonTerminal("paramlist_types");
  475. PARAMLIST_TYPES.Rule = MakePlusRule(PARAMLIST_TYPES, ToTerm(","), PARAMLIST_TYPE);
  476. PARAMLIST.Rule = ToTerm("(") + PARAMLIST_TYPES + ")";
  477.  
  478. // PRIMTYPE ::= 'void' | 'int' | 'int8' | 'int16' | 'int32' | 'int64' | 'uint' | 'uint8' | 'uint16' | 'uint32' | 'uint64' | 'float' | 'double' | 'bool'
  479. 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;
  480.  
  481. // RETURN ::= 'return' [ASSIGN] ';'
  482. RETURN.Rule = k_RETURN + ";" | k_RETURN + ASSIGN + ";";
  483.  
  484. var SCOPEDDATATYPE = new NonTerminal("scopeddatatype");
  485. var SCOPEDIDENTIFIERLIST = new NonTerminal("scopedidentifierlist");
  486. var SCOPEDIDENTIFIER = new NonTerminal("scopedidentifier");
  487.  
  488. // SCOPE ::= [[IDENTIFIER] '::' {IDENTIFIER '::'}]
  489. SCOPE_DATATYPE.Rule = SCOPEDDATATYPE;// | "::" + SCOPE_DATATYPE | IDENTIFIER + "::" + SCOPE_DATATYPE;
  490.  
  491. // SCOPEDIDENTIFIER - Used in place of "SCOPE IDENTIFIER"
  492. // SCOPEDDATATYPE - Used in place of "SCOPE DATATYPE", it's DATATYPE with the option to have a scoped identifier
  493. SCOPEDIDENTIFIERLIST.Rule = MakeListRule(SCOPEDIDENTIFIERLIST, op_COLON_COLON, IDENTIFIER, TermListOptions.AddPreferShiftHint);
  494. SCOPEDIDENTIFIER.Rule = op_COLON_COLON + SCOPEDIDENTIFIERLIST | SCOPEDIDENTIFIERLIST;
  495. SCOPEDDATATYPE.Rule = PRIMTYPE | op_QMARK | k_AUTO | SCOPEDIDENTIFIER;
  496.  
  497. // SCRIPT ::= {IMPORT | ENUM | TYPEDEF | CLASS | MIXIN | INTERFACE | FUNCDEF | VIRTPROP | VAR | FUNC | NAMESPACE | ';'}
  498. NonTerminal FUNC_VAR = new NonTerminal("func_var");
  499. FUNC_VAR.Rule = MODIFIERS_OPT + FUNC_MOD2 + IDENTIFIER + PARAMLIST + CONST_OPT + MODIFIERS_OPT + STATBLOCK
  500. | MODIFIERS_OPT + TYPE + IDENTIFIER + VAR_IDS + ";";
  501. // SCRIPT_ITEM.Rule = IMPORT | ENUM | TYPEDEF | CLASS | MIXIN | INTERFACE | FUNCDEF | VAR | VIRTPROP | FUNC | NAMESPACE | op_SEMI;
  502. SCRIPT_ITEM.Rule = IMPORT | ENUM | TYPEDEF | CLASS | MIXIN | INTERFACE | FUNCDEF | VFV | NAMESPACE | PreferShiftHere() + op_SEMI;
  503. // SCRIPT_ITEM.Rule = VFV | PreferShiftHere() + op_SEMI;
  504. SCRIPT.Rule = MakeStarRule(SCRIPT, SCRIPT_ITEM);
  505.  
  506. // STATBLOCK ::= '{' {VAR | STATEMENT} '}'
  507. STATBLOCK.Rule = ToTerm("{") + VSS_OPT + "}";
  508.  
  509. // STATEMENT ::= (IF | FOR | WHILE | RETURN | STATBLOCK | BREAK | CONTINUE | DOWHILE | SWITCH | EXPR_STAT)
  510. STATEMENT.Rule = IF | FOR | WHILE | RETURN | STATBLOCK | BREAK | CONTINUE | DOWHILE | SWITCH | EXPR_STAT;
  511. STATEMENTS_OTP.Rule = MakeStarRule(STATEMENTS_OTP, STATEMENT);
  512.  
  513. // STRING ::= single token: single quoted ', "double quoted ", "or heredoc multi-line string """
  514. // No need to set a Rule because it is type: StringLiteral
  515.  
  516. // SWITCH ::= 'switch' '(' ASSIGN ')' '{' {CASE} '}'
  517. SWITCH.Rule = k_SWITCH + "(" + ASSIGN + ")" + "{" + CASES_OPT + "}";
  518.  
  519. // TYPE ::= ['const'] SCOPE DATATYPE ['<' TYPE {',' TYPE} '>'] { ('[' ']') | '@' }
  520. // NonTerminal TYPE_END = new NonTerminal("type_end");
  521. // TYPE_END.Rule = /*CustomActionHere(CheckIfLeftThenRightBracket) +*/ ToTerm("[") + "]" | "@";
  522. // NonTerminal TYPE_ENDS_OPT = new NonTerminal("type_ends_opt");
  523. // TYPE_ENDS_OPT.Rule = MakeStarRule(TYPE_ENDS_OPT, TYPE_END);
  524. NonTerminal TYPE_ENDS_OPT = new NonTerminal("type_ends_opt");
  525. //TYPE_ENDS_OPT.Rule = Empty | ToTerm("[") + "]" + TYPE_ENDS_OPT | "@" + TYPE_ENDS_OPT | "&";
  526. //TYPE.Rule = CONST_OPT + SCOPE_DATATYPE + "<" + TYPES + ">" + TYPE_ENDS_OPT
  527. // | CONST_OPT + SCOPE_DATATYPE + TYPE_ENDS_OPT;
  528. //TYPES.Rule = MakePlusRule(TYPES, ToTerm(","), TYPE);
  529. TYPE_ENDS_OPT.Rule = Empty | TYPE_ENDS_OPT + PreferShiftHere() + ToTerm("[") + "]" | TYPE_ENDS_OPT + PreferShiftHere() + "@";
  530. TYPES.Rule = TYPE | TYPES + "," + TYPE;
  531. TYPE.Rule = CONST_OPT + SCOPE_DATATYPE + "<" + TYPES + ">" + TYPE_ENDS_OPT
  532. | CONST_OPT + SCOPE_DATATYPE + TYPE_ENDS_OPT;
  533.  
  534.  
  535.  
  536. // TYPEDEF ::= 'typedef' PRIMTYPE IDENTIFIER ';'
  537. TYPEDEF.Rule = k_TYPEDEF + PRIMTYPE + IDENTIFIER + ";";
  538.  
  539. // TYPEMOD ::= ['&' ['in' | 'out' | 'inout']]
  540. TYPEMOD.Rule = Empty | "&" | ToTerm("&") + "in" | ToTerm("&") + "out" | ToTerm("&") + "inout";
  541.  
  542.  
  543.  
  544. // VAR ::= ['private'|'protected'] TYPE IDENTIFIER [( '=' (INITLIST | EXPR)) | ARGLIST] {',' IDENTIFIER [( '=' (INITLIST | EXPR)) | ARGLIST]} ';'
  545. VAR_ID.Rule = IDENTIFIER
  546. | IDENTIFIER + "=" + INITLIST
  547. | IDENTIFIER + "=" + EXPR;
  548. VAR_IDS.Rule = MakePlusRule(VAR_IDS, ToTerm(","), VAR_ID);
  549. VAR.Rule = MODIFIERS_OPT + TYPE + IDENTIFIER + VAR_IDS + ";";
  550.  
  551. // VARACCESS ::= SCOPE IDENTIFIER
  552. // VARACCESS.Rule = SCOPE_DATATYPE;
  553.  
  554. // VIRTPROP ::= ['private' | 'protected'] TYPE ['&'] IDENTIFIER '{' {('get' | 'set') ['const'] [('override' | 'final')] (STATBLOCK | ';')} '}'
  555. VIRTPROP_ITEM.Rule = "get" + CONST_OPT + MODIFIERS_OPT + STATBLOCK
  556. | "set" + CONST_OPT + MODIFIERS_OPT + STATBLOCK
  557. | "get" + CONST_OPT + MODIFIERS_OPT + ";"
  558. | "set" + CONST_OPT + MODIFIERS_OPT + ";";
  559. VIRTPROP_ITEMS_OPT.Rule = MakeStarRule(VIRTPROP_ITEMS_OPT, VIRTPROP_ITEM);
  560. VIRTPROP.Rule = MODIFIERS_OPT + TYPE_AMP_OPT + IDENTIFIER + "{" + VIRTPROP_ITEMS_OPT + "}";
  561.  
  562. // WHILE ::= 'while' '(' ASSIGN ')' STATEMENT
  563. // Note this matches the IF rule
  564. WHILE.Rule = k_WHILE + "(" + ASSIGN + ")" + STATEMENT;
  565.  
  566.  
  567.  
  568.  
  569.  
  570.  
  571.  
  572. this.RegisterBracePair("[", "]");
  573. this.RegisterBracePair("<", ">");
  574. this.RegisterBracePair("(", ")");
  575. this.RegisterBracePair("{", "}");
  576.  
  577. this.MarkPunctuation(",", ";", "(", ")", "{", "}", "[", "]");
  578.  
  579. // This was taken from: http://www.angelcode.com/angelscript/sdk/docs/manual/doc_operator_precedence.html
  580. // However it doesn't include some operators (TODO: list them here...)
  581. 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);
  582. RegisterOperators(2, Associativity.Right, op_QMARK, op_COLON);
  583. RegisterOperators(3, Associativity.Left, op_OR, op_BAR_BAR);
  584. RegisterOperators(4, Associativity.Left, op_AND, op_AMP_AMP);
  585. RegisterOperators(5, Associativity.Left, op_EQ, op_NEQ, op_IS, op_IS_NOT, op_XOR, op_CARET_CARET);
  586. RegisterOperators(6, Associativity.Left, op_LTEQ, op_LT, op_GTEQ, op_GT);
  587. RegisterOperators(7, Associativity.Left, op_BAR);
  588. RegisterOperators(8, Associativity.Left, op_CARET);
  589. RegisterOperators(9, Associativity.Left, op_AMP);
  590. RegisterOperators(10, Associativity.Left, op_SHL, op_SHR, op_USHR);
  591. RegisterOperators(11, Associativity.Left, op_PLUS, op_MINUS);
  592. RegisterOperators(12, Associativity.Left, op_STAR, op_SLASH, op_PERCENT);
  593. RegisterOperators(13, Associativity.Left, op_STAR_STAR);
  594. RegisterOperators(14, Associativity.Left, op_AT);
  595. RegisterOperators(15, Associativity.Right, op_TILDE);
  596. RegisterOperators(16, Associativity.Right, op_NOT, op_EMARK);
  597. RegisterOperators(17, Associativity.Left, op_DOT);
  598. RegisterOperators(18, Associativity.Right, op_PLUS_PLUS, op_MINUS_MINUS);
  599. RegisterOperators(19, Associativity.Neutral, op_R_BKT);
  600. RegisterOperators(20, Associativity.Right, op_COLON_COLON);
  601. }
  602.  
  603.  
  604. public KeyTerm Keyword(string keyword)
  605. {
  606. var term = ToTerm(keyword, keyword);
  607. // term.SetOption(TermOptions.IsKeyword, true);
  608. // term.SetOption(TermOptions.IsReservedWord, true);
  609.  
  610. this.MarkReservedWords(keyword);
  611. term.EditorInfo = new TokenEditorInfo(TokenType.Keyword, TokenColor.Keyword, TokenTriggers.None);
  612.  
  613. return term;
  614. }
  615.  
  616. public KeyTerm Operator(string text, string name)
  617. {
  618. //string opCased = this.CaseSensitive ? op : op.ToLower();
  619. //var term = new KeyTerm(opCased, op);
  620. //term.SetOption(TermOptions.IsOperator, true);
  621. //term.EditorInfo = new TokenEditorInfo(TokenType.Operator, TokenColor.Keyword, TokenTriggers.None);
  622.  
  623. var term = ToTerm(text, name);
  624. return term;
  625. }
  626.  
  627. public static NumberLiteral CreateAngelScriptNumber(string name)
  628. {
  629. NumberLiteral term = new NumberLiteral(name, NumberOptions.AllowStartEndDot);
  630. //default int types are Integer (32bit) -> LongInteger (BigInt); Try Int64 before BigInt: Better performance?
  631. term.DefaultIntTypes = new TypeCode[] { TypeCode.Int32, TypeCode.Int64 };
  632. term.DefaultFloatType = TypeCode.Double; // it is default
  633. term.AddPrefix("0b", NumberOptions.Binary);
  634. term.AddPrefix("0o", NumberOptions.Octal);
  635. term.AddPrefix("0d", NumberOptions.IntOnly);
  636. term.AddPrefix("0x", NumberOptions.Hex);
  637. term.AddSuffix("f", TypeCode.Double);
  638.  
  639. return term;
  640. }
  641. } // class
  642. } // namespace
  643.  
  644.  
  645.  
  646.  
  647. /*
  648. Shift
  649. Accept the basic symbol as the corresponding terminal, push a new state onto
  650. the stack, and examine the next basic symbol.
  651.  
  652. Reduce
  653. Note that a specific phrase has been recognized, remove a number of states
  654. equal to the number of symbols in the sequence of the corresponding production
  655. from the stack, push a new state onto the stack, and examine the current
  656. basic symbol again.
  657.  
  658.  
  659. A Shift step advances in the input stream by one symbol.
  660. That shifted symbol becomes a new single-node parse tree.
  661.  
  662. A Reduce step applies a completed grammar rule to some of the recent parse trees,
  663. joining them together as one tree with a new root symbol.
  664. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement