aboutsummaryrefslogtreecommitdiff
path: root/src/yuescript/yue_parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/yuescript/yue_parser.cpp')
-rw-r--r--src/yuescript/yue_parser.cpp529
1 files changed, 248 insertions, 281 deletions
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp
index e62417c..4532d21 100644
--- a/src/yuescript/yue_parser.cpp
+++ b/src/yuescript/yue_parser.cpp
@@ -36,7 +36,6 @@ YueParser::YueParser() {
36 line_break = nl(-expr('\r') >> '\n'); 36 line_break = nl(-expr('\r') >> '\n');
37 any_char = line_break | any(); 37 any_char = line_break | any();
38 stop = line_break | eof(); 38 stop = line_break | eof();
39 indent = plain_space;
40 comment = "--" >> *(not_(set("\r\n")) >> any_char) >> and_(stop); 39 comment = "--" >> *(not_(set("\r\n")) >> any_char) >> and_(stop);
41 multi_line_open = "--[["; 40 multi_line_open = "--[[";
42 multi_line_close = "]]"; 41 multi_line_close = "]]";
@@ -47,34 +46,33 @@ YueParser::YueParser() {
47 space = -(and_(set(" \t-\\")) >> *space_one >> -comment); 46 space = -(and_(set(" \t-\\")) >> *space_one >> -comment);
48 space_break = space >> line_break; 47 space_break = space >> line_break;
49 white = space >> *(line_break >> space); 48 white = space >> *(line_break >> space);
50 alpha_num = sel({range('a', 'z'), range('A', 'Z'), range('0', '9'), '_'}); 49 alpha_num = range('a', 'z') | range('A', 'Z') | range('0', '9') | '_';
51 not_alpha_num = not_(alpha_num); 50 not_alpha_num = not_(alpha_num);
52 Name = sel({range('a', 'z'), range('A', 'Z'), '_'}) >> *alpha_num; 51 Name = (range('a', 'z') | range('A', 'Z') | '_') >> *alpha_num;
53 num_expo = set("eE") >> -set("+-") >> num_char; 52 num_expo = set("eE") >> -set("+-") >> num_char;
54 num_expo_hex = set("pP") >> -set("+-") >> num_char; 53 num_expo_hex = set("pP") >> -set("+-") >> num_char;
55 lj_num = -set("uU") >> set("lL") >> set("lL"); 54 lj_num = -set("uU") >> set("lL") >> set("lL");
56 num_char = range('0', '9') >> *(range('0', '9') | '_' >> and_(range('0', '9'))); 55 num_char = range('0', '9') >> *(range('0', '9') | '_' >> and_(range('0', '9')));
57 num_char_hex = sel({range('0', '9'), range('a', 'f'), range('A', 'F')}); 56 num_char_hex = range('0', '9') | range('a', 'f') | range('A', 'F');
58 num_lit = num_char_hex >> *(num_char_hex | '_' >> and_(num_char_hex)); 57 num_lit = num_char_hex >> *(num_char_hex | '_' >> and_(num_char_hex));
59 Num = sel({ 58 Num =
60 "0x" >> ( 59 "0x" >> (
61 +num_lit >> sel({ 60 +num_lit >> (
62 seq({'.', +num_lit, -num_expo_hex}), 61 '.' >> +num_lit >> -num_expo_hex |
63 num_expo_hex, 62 num_expo_hex |
64 lj_num, 63 lj_num |
65 true_() 64 true_()
66 }) | seq({ 65 ) | (
67 '.', +num_lit, -num_expo_hex 66 '.' >> +num_lit >> -num_expo_hex
68 }) 67 )
69 ), 68 ) |
70 +num_char >> sel({ 69 +num_char >> (
71 seq({'.', +num_char, -num_expo}), 70 '.' >> +num_char >> -num_expo |
72 num_expo, 71 num_expo |
73 lj_num, 72 lj_num |
74 true_() 73 true_()
75 }), 74 ) |
76 seq({'.', +num_char, -num_expo}) 75 '.' >> +num_char >> -num_expo;
77 });
78 76
79 cut = false_(); 77 cut = false_();
80 Seperator = true_(); 78 Seperator = true_();
@@ -86,7 +84,7 @@ YueParser::YueParser() {
86 84
87 #define ensure(patt, finally) ((patt) >> (finally) | (finally) >> cut) 85 #define ensure(patt, finally) ((patt) >> (finally) | (finally) >> cut)
88 86
89 #define key(str) (str >> not_alpha_num) 87 #define key(str) (expr(str) >> not_alpha_num)
90 88
91 #define disable_do_rule(patt) ( \ 89 #define disable_do_rule(patt) ( \
92 disable_do >> ( \ 90 disable_do >> ( \
@@ -117,11 +115,9 @@ YueParser::YueParser() {
117 ) 115 )
118 116
119 #define body_with(str) ( \ 117 #define body_with(str) ( \
120 sel({ \ 118 key(str) >> space >> (in_block | Statement) | \
121 key(str) >> space >> (in_block | Statement), \ 119 in_block | \
122 in_block, \ 120 empty_block_error \
123 empty_block_error \
124 }) \
125 ) 121 )
126 122
127 #define opt_body_with(str) ( \ 123 #define opt_body_with(str) ( \
@@ -129,7 +125,7 @@ YueParser::YueParser() {
129 in_block \ 125 in_block \
130 ) 126 )
131 127
132 #define body (sel({in_block, Statement, empty_block_error})) 128 #define body (in_block | Statement | empty_block_error)
133 129
134 Variable = pl::user(Name, [](const item_t& item) { 130 Variable = pl::user(Name, [](const item_t& item) {
135 State* st = reinterpret_cast<State*>(item.user_data); 131 State* st = reinterpret_cast<State*>(item.user_data);
@@ -166,11 +162,11 @@ YueParser::YueParser() {
166 SelfClass = "@@"; 162 SelfClass = "@@";
167 SelfClassName = "@@" >> Name; 163 SelfClassName = "@@" >> Name;
168 164
169 SelfItem = sel({SelfClassName, SelfClass, SelfName, Self}); 165 SelfItem = SelfClassName | SelfClass | SelfName | Self;
170 KeyName = SelfItem | Name; 166 KeyName = SelfItem | Name;
171 VarArg = "..."; 167 VarArg = "...";
172 168
173 check_indent = pl::user(indent, [](const item_t& item) { 169 check_indent = pl::user(plain_space, [](const item_t& item) {
174 int indent = 0; 170 int indent = 0;
175 for (input_it i = item.begin->m_it; i != item.end->m_it; ++i) { 171 for (input_it i = item.begin->m_it; i != item.end->m_it; ++i) {
176 switch (*i) { 172 switch (*i) {
@@ -183,7 +179,7 @@ YueParser::YueParser() {
183 }); 179 });
184 check_indent_match = and_(check_indent); 180 check_indent_match = and_(check_indent);
185 181
186 advance = pl::user(indent, [](const item_t& item) { 182 advance = pl::user(plain_space, [](const item_t& item) {
187 int indent = 0; 183 int indent = 0;
188 for (input_it i = item.begin->m_it; i != item.end->m_it; ++i) { 184 for (input_it i = item.begin->m_it; i != item.end->m_it; ++i) {
189 switch (*i) { 185 switch (*i) {
@@ -201,7 +197,7 @@ YueParser::YueParser() {
201 }); 197 });
202 advance_match = and_(advance); 198 advance_match = and_(advance);
203 199
204 push_indent = pl::user(indent, [](const item_t& item) { 200 push_indent = pl::user(plain_space, [](const item_t& item) {
205 int indent = 0; 201 int indent = 0;
206 for (input_it i = item.begin->m_it; i != item.end->m_it; ++i) { 202 for (input_it i = item.begin->m_it; i != item.end->m_it; ++i) {
207 switch (*i) { 203 switch (*i) {
@@ -229,13 +225,13 @@ YueParser::YueParser() {
229 225
230 in_block = +space_break >> advance_match >> ensure(Block, pop_indent); 226 in_block = +space_break >> advance_match >> ensure(Block, pop_indent);
231 227
232 LocalFlag = sel({'*', '^'}); 228 LocalFlag = expr('*') | '^';
233 LocalValues = NameList >> -(space >> '=' >> space >> (TableBlock | ExpListLow)); 229 LocalValues = NameList >> -(space >> '=' >> space >> (TableBlock | ExpListLow));
234 Local = key("local") >> space >> (LocalFlag | LocalValues); 230 Local = key("local") >> space >> (LocalFlag | LocalValues);
235 231
236 ConstAttrib = key("const"); 232 ConstAttrib = key("const");
237 CloseAttrib = key("close"); 233 CloseAttrib = key("close");
238 local_const_item = sel({Variable, SimpleTable, TableLit}); 234 local_const_item = Variable | SimpleTable | TableLit;
239 LocalAttrib = ( 235 LocalAttrib = (
240 ConstAttrib >> Seperator >> space >> local_const_item >> *(space >> ',' >> space >> local_const_item) | 236 ConstAttrib >> Seperator >> space >> local_const_item >> *(space >> ',' >> space >> local_const_item) |
241 CloseAttrib >> Seperator >> space >> Variable >> *(space >> ',' >> space >> Variable) 237 CloseAttrib >> Seperator >> space >> Variable >> *(space >> ',' >> space >> Variable)
@@ -246,42 +242,42 @@ YueParser::YueParser() {
246 import_name_list = Seperator >> *space_break >> space >> import_name >> *((+space_break | space >> ',' >> *space_break) >> space >> import_name); 242 import_name_list = Seperator >> *space_break >> space >> import_name >> *((+space_break | space >> ',' >> *space_break) >> space >> import_name);
247 ImportFrom = import_name_list >> *space_break >> space >> key("from") >> space >> Exp; 243 ImportFrom = import_name_list >> *space_break >> space >> key("from") >> space >> Exp;
248 244
249 ImportLiteralInner = sel({range('a', 'z'), range('A', 'Z'), set("_-")}) >> *(alpha_num | '-'); 245 ImportLiteralInner = (range('a', 'z') | range('A', 'Z') | set("_-")) >> *(alpha_num | '-');
250 import_literal_chain = Seperator >> ImportLiteralInner >> *('.' >> ImportLiteralInner); 246 import_literal_chain = Seperator >> ImportLiteralInner >> *('.' >> ImportLiteralInner);
251 ImportLiteral = sel({ 247 ImportLiteral = (
252 '\'' >> import_literal_chain >> '\'', 248 '\'' >> import_literal_chain >> '\''
253 '"' >> import_literal_chain >> '"' 249 ) | (
254 }); 250 '"' >> import_literal_chain >> '"'
251 );
255 252
256 MacroNamePair = MacroName >> ':' >> space >> MacroName; 253 MacroNamePair = MacroName >> ':' >> space >> MacroName;
257 ImportAllMacro = '$'; 254 ImportAllMacro = '$';
258 import_tab_item = sel({ 255 import_tab_item =
259 VariablePair, 256 VariablePair |
260 NormalPair, 257 NormalPair |
261 ':' >> MacroName, 258 ':' >> MacroName |
262 MacroNamePair, 259 MacroNamePair |
263 ImportAllMacro, 260 ImportAllMacro |
264 MetaVariablePair, 261 MetaVariablePair |
265 MetaNormalPair, 262 MetaNormalPair |
266 Exp 263 Exp;
267 });
268 import_tab_list = import_tab_item >> *(space >> ',' >> space >> import_tab_item); 264 import_tab_list = import_tab_item >> *(space >> ',' >> space >> import_tab_item);
269 import_tab_line = ( 265 import_tab_line = (
270 push_indent_match >> (space >> import_tab_list >> pop_indent | pop_indent) 266 push_indent_match >> (space >> import_tab_list >> pop_indent | pop_indent)
271 ) | space; 267 ) | space;
272 import_tab_lines = space_break >> import_tab_line >> *(-(space >> ',') >> space_break >> import_tab_line) >> -(space >> ','); 268 import_tab_lines = space_break >> import_tab_line >> *(-(space >> ',') >> space_break >> import_tab_line) >> -(space >> ',');
273 ImportTabLit = seq({ 269 ImportTabLit = (
274 '{', Seperator, 270 '{' >> Seperator >>
275 -(space >> import_tab_list), 271 -(space >> import_tab_list) >>
276 -(space >> ','), 272 -(space >> ',') >>
277 -import_tab_lines, 273 -import_tab_lines >>
278 white, 274 white >>
279 '}' 275 '}'
280 }) | seq({ 276 ) | (
281 Seperator, key_value, *(space >> ',' >> space >> key_value) 277 Seperator >> key_value >> *(space >> ',' >> space >> key_value)
282 }); 278 );
283 279
284 ImportAs = ImportLiteral >> -(space >> key("as") >> space >> sel({ImportTabLit, Variable, ImportAllMacro})); 280 ImportAs = ImportLiteral >> -(space >> key("as") >> space >> (ImportTabLit | Variable | ImportAllMacro));
285 281
286 Import = key("import") >> space >> (ImportAs | ImportFrom); 282 Import = key("import") >> space >> (ImportAs | ImportFrom);
287 283
@@ -291,7 +287,7 @@ YueParser::YueParser() {
291 287
292 ShortTabAppending = "[]" >> space >> Assign; 288 ShortTabAppending = "[]" >> space >> Assign;
293 289
294 BreakLoop = sel({"break", "continue"}) >> not_alpha_num; 290 BreakLoop = (expr("break") | "continue") >> not_alpha_num;
295 291
296 Return = key("return") >> -(space >> (TableBlock | ExpListLow)); 292 Return = key("return") >> -(space >> (TableBlock | ExpListLow));
297 293
@@ -324,12 +320,12 @@ YueParser::YueParser() {
324 IfCond = disable_chain_rule(disable_arg_table_block_rule(Assignment | Exp)); 320 IfCond = disable_chain_rule(disable_arg_table_block_rule(Assignment | Exp));
325 if_else_if = -(line_break >> *space_break >> check_indent_match) >> space >> key("elseif") >> space >> IfCond >> space >> body_with("then"); 321 if_else_if = -(line_break >> *space_break >> check_indent_match) >> space >> key("elseif") >> space >> IfCond >> space >> body_with("then");
326 if_else = -(line_break >> *space_break >> check_indent_match) >> space >> key("else") >> space >> body; 322 if_else = -(line_break >> *space_break >> check_indent_match) >> space >> key("else") >> space >> body;
327 IfType = sel({"if", "unless"}) >> not_alpha_num; 323 IfType = (expr("if") | "unless") >> not_alpha_num;
328 If = seq({IfType, space, IfCond, space, opt_body_with("then"), *if_else_if, -if_else}); 324 If = IfType >> space >> IfCond >> space >> opt_body_with("then") >> *if_else_if >> -if_else;
329 325
330 WhileType = sel({"while", "until"}) >> not_alpha_num; 326 WhileType = (expr("while") | "until") >> not_alpha_num;
331 While = WhileType >> space >> disable_do_chain_arg_table_block_rule(Exp) >> space >> opt_body_with("do"); 327 While = WhileType >> space >> disable_do_chain_arg_table_block_rule(Exp) >> space >> opt_body_with("do");
332 Repeat = seq({key("repeat"), space, Body, line_break, *space_break, check_indent_match, space, key("until"), space, Exp}); 328 Repeat = key("repeat") >> space >> Body >> line_break >> *space_break >> check_indent_match >> space >> key("until") >> space >> Exp;
333 329
334 ForStepValue = ',' >> space >> Exp; 330 ForStepValue = ',' >> space >> Exp;
335 for_args = Variable >> space >> '=' >> space >> Exp >> space >> ',' >> space >> Exp >> space >> -ForStepValue; 331 for_args = Variable >> space >> '=' >> space >> Exp >> space >> ',' >> space >> Exp >> space >> -ForStepValue;
@@ -397,50 +393,48 @@ YueParser::YueParser() {
397 StarExp = '*' >> space >> Exp; 393 StarExp = '*' >> space >> Exp;
398 CompForEach = key("for") >> space >> AssignableNameList >> space >> key("in") >> space >> (StarExp | Exp); 394 CompForEach = key("for") >> space >> AssignableNameList >> space >> key("in") >> space >> (StarExp | Exp);
399 CompFor = key("for") >> space >> Variable >> space >> '=' >> space >> Exp >> space >> ',' >> space >> Exp >> -ForStepValue; 395 CompFor = key("for") >> space >> Variable >> space >> '=' >> space >> Exp >> space >> ',' >> space >> Exp >> -ForStepValue;
400 comp_clause = sel({CompFor, CompForEach, key("when") >> space >> Exp}); 396 comp_clause = CompFor | CompForEach | key("when") >> space >> Exp;
401 397
402 Assign = '=' >> space >> Seperator >> sel({ 398 Assign = '=' >> space >> Seperator >> (
403 With, If, Switch, TableBlock, 399 With | If | Switch | TableBlock |
404 Exp >> *(space >> set(",;") >> space >> Exp) 400 Exp >> *(space >> set(",;") >> space >> Exp)
405 }); 401 );
406 402
407 UpdateOp = sel({ 403 UpdateOp =
408 "..", "//", "or", "and", 404 expr("..") | "//" | "or" | "and" |
409 ">>", "<<", "??", 405 ">>" | "<<" | "??" |
410 set("+-*/%&|") 406 set("+-*/%&|");
411 });
412 407
413 Update = UpdateOp >> '=' >> space >> Exp; 408 Update = UpdateOp >> '=' >> space >> Exp;
414 409
415 Assignable = sel({AssignableChain, Variable, SelfItem}); 410 Assignable = AssignableChain | Variable | SelfItem;
416 411
417 UnaryValue = +(UnaryOperator >> space) >> Value; 412 UnaryValue = +(UnaryOperator >> space) >> Value;
418 413
419 exponential_operator = '^'; 414 exponential_operator = '^';
420 expo_value = seq({exponential_operator, *space_break, space, Value}); 415 expo_value = exponential_operator >> *space_break >> space >> Value;
421 expo_exp = Value >> *(space >> expo_value); 416 expo_exp = Value >> *(space >> expo_value);
422 417
423 UnaryOperator = sel({ 418 UnaryOperator =
424 '-' >> not_(set(">=") | space_one), 419 '-' >> not_(set(">=") | space_one) |
425 '#', 420 '#' |
426 '~' >> not_('=' | space_one), 421 '~' >> not_('=' | space_one) |
427 "not" >> not_alpha_num 422 key("not");
428 });
429 UnaryExp = *(UnaryOperator >> space) >> expo_exp; 423 UnaryExp = *(UnaryOperator >> space) >> expo_exp;
430 424
431 pipe_operator = "|>"; 425 pipe_operator = "|>";
432 pipe_value = seq({pipe_operator, *space_break, space, UnaryExp}); 426 pipe_value = pipe_operator >> *space_break >> space >> UnaryExp;
433 pipe_exp = UnaryExp >> *(space >> pipe_value); 427 pipe_exp = UnaryExp >> *(space >> pipe_value);
434 428
435 BinaryOperator = sel({ 429 BinaryOperator =
436 "or" >> not_alpha_num, 430 key("or") |
437 "and" >> not_alpha_num, 431 key("and") |
438 "<=", ">=", "~=", "!=", "==", 432 "<=" | ">=" | "~=" | "!=" | "==" |
439 "..", "<<", ">>", "//", 433 ".." | "<<" | ">>" | "//" |
440 set("+-*/%><|&~") 434 set("+-*/%><|&~");
441 }); 435
442 ExpOpValue = seq({BinaryOperator, *space_break, space, pipe_exp}); 436 ExpOpValue = BinaryOperator >> *space_break >> space >> pipe_exp;
443 Exp = seq({Seperator, pipe_exp, *(space >> ExpOpValue), -(space >> "??" >> space >> Exp)}); 437 Exp = Seperator >> pipe_exp >> *(space >> ExpOpValue) >> -(space >> "??" >> space >> Exp);
444 438
445 disable_chain = pl::user(true_(), [](const item_t& item) { 439 disable_chain = pl::user(true_(), [](const item_t& item) {
446 State* st = reinterpret_cast<State*>(item.user_data); 440 State* st = reinterpret_cast<State*>(item.user_data);
@@ -454,22 +448,21 @@ YueParser::YueParser() {
454 return true; 448 return true;
455 }); 449 });
456 450
457 chain_line = seq({check_indent_match, space, chain_dot_chain | colon_chain, -InvokeArgs}); 451 chain_line = check_indent_match >> space >> (chain_dot_chain | colon_chain) >> -InvokeArgs;
458 chain_block = pl::user(true_(), [](const item_t& item) { 452 chain_block = pl::user(true_(), [](const item_t& item) {
459 State* st = reinterpret_cast<State*>(item.user_data); 453 State* st = reinterpret_cast<State*>(item.user_data);
460 return st->noChainBlockStack.empty() || !st->noChainBlockStack.top(); 454 return st->noChainBlockStack.empty() || !st->noChainBlockStack.top();
461 }) >> +space_break >> advance_match >> ensure( 455 }) >> +space_break >> advance_match >> ensure(
462 chain_line >> *(+space_break >> chain_line), pop_indent); 456 chain_line >> *(+space_break >> chain_line), pop_indent);
463 ChainValue = seq({ 457 ChainValue =
464 Seperator, 458 Seperator >>
465 chain, 459 chain >>
466 -ExistentialOp, 460 -ExistentialOp >>
467 -(InvokeArgs | chain_block), 461 -(InvokeArgs | chain_block) >>
468 -TableAppendingOp 462 -TableAppendingOp;
469 });
470 463
471 SimpleTable = seq({Seperator, key_value, *(space >> ',' >> space >> key_value)}); 464 SimpleTable = Seperator >> key_value >> *(space >> ',' >> space >> key_value);
472 Value = sel({SimpleValue, SimpleTable, ChainValue, String}); 465 Value = SimpleValue | SimpleTable | ChainValue | String;
473 466
474 single_string_inner = '\\' >> set("'\\") | not_('\'') >> any_char; 467 single_string_inner = '\\' >> set("'\\") | not_('\'') >> any_char;
475 SingleString = '\'' >> *single_string_inner >> '\''; 468 SingleString = '\'' >> *single_string_inner >> '\'';
@@ -479,7 +472,7 @@ YueParser::YueParser() {
479 DoubleStringInner = +(not_(interp) >> double_string_plain); 472 DoubleStringInner = +(not_(interp) >> double_string_plain);
480 DoubleStringContent = DoubleStringInner | interp; 473 DoubleStringContent = DoubleStringInner | interp;
481 DoubleString = '"' >> Seperator >> *DoubleStringContent >> '"'; 474 DoubleString = '"' >> Seperator >> *DoubleStringContent >> '"';
482 String = sel({DoubleString, SingleString, LuaString}); 475 String = DoubleString | SingleString | LuaString;
483 476
484 lua_string_open = '[' >> *expr('=') >> '['; 477 lua_string_open = '[' >> *expr('=') >> '[';
485 lua_string_close = ']' >> *expr('=') >> ']'; 478 lua_string_close = ']' >> *expr('=') >> ']';
@@ -501,101 +494,90 @@ YueParser::YueParser() {
501 494
502 LuaString = LuaStringOpen >> -line_break >> LuaStringContent >> LuaStringClose; 495 LuaString = LuaStringOpen >> -line_break >> LuaStringContent >> LuaStringClose;
503 496
504 Parens = seq({'(', *space_break, space, Exp, *space_break, space, ')'}); 497 Parens = '(' >> *space_break >> space >> Exp >> *space_break >> space >> ')';
505 Callable = sel({Variable, SelfItem, MacroName, VarArg, Parens}); 498 Callable = Variable | SelfItem | MacroName | VarArg | Parens;
506 fn_args_exp_list = space >> Exp >> space >> *seq({line_break | ',', white, Exp}); 499 fn_args_exp_list = space >> Exp >> space >> *((line_break | ',') >> white >> Exp);
507 500
508 fn_args = sel({ 501 fn_args =
509 seq({'(', *space_break, -fn_args_exp_list, *space_break, space, ')'}), 502 '(' >> *space_break >> -fn_args_exp_list >> *space_break >> space >> ')' |
510 seq({space, '!', not_('=')}) 503 space >> '!' >> not_('=');
511 });
512 504
513 meta_index = sel({Name, index, String}); 505 meta_index = Name | index | String;
514 Metatable = '<' >> space >> '>'; 506 Metatable = '<' >> space >> '>';
515 Metamethod = '<' >> space >> meta_index >> space >> '>'; 507 Metamethod = '<' >> space >> meta_index >> space >> '>';
516 508
517 ExistentialOp = '?' >> not_('?'); 509 ExistentialOp = '?' >> not_('?');
518 TableAppendingOp = "[]"; 510 TableAppendingOp = "[]";
519 chain_call = seq({ 511 chain_call = (
520 Callable, 512 Callable >> -ExistentialOp >> -chain_items
521 -ExistentialOp, 513 ) | (
522 -chain_items 514 String >> chain_items
523 }) | seq({ 515 );
524 String, 516 chain_index_chain = index >> -ExistentialOp >> -chain_items;
525 chain_items 517 chain_dot_chain = DotChainItem >> -ExistentialOp >> -chain_items;
526 }); 518
527 chain_index_chain = seq({index, -ExistentialOp, -chain_items}); 519 chain = chain_call | chain_dot_chain | colon_chain | chain_index_chain;
528 chain_dot_chain = seq({DotChainItem, -ExistentialOp, -chain_items}); 520
529 521 chain_call_list = (
530 chain = sel({chain_call, chain_dot_chain, colon_chain, chain_index_chain}); 522 Callable >> -ExistentialOp >> chain_items
531 523 ) | (
532 chain_call_list = seq({ 524 String >> chain_items
533 Callable, 525 );
534 -ExistentialOp, 526 chain_list = chain_call_list | chain_dot_chain | colon_chain | chain_index_chain;
535 chain_items
536 }) | seq({
537 String,
538 chain_items
539 });
540 chain_list = sel({chain_call_list, chain_dot_chain, colon_chain, chain_index_chain});
541 527
542 AssignableChain = Seperator >> chain_list; 528 AssignableChain = Seperator >> chain_list;
543 529
544 chain_with_colon = +chain_item >> -colon_chain; 530 chain_with_colon = +chain_item >> -colon_chain;
545 chain_items = chain_with_colon | colon_chain; 531 chain_items = chain_with_colon | colon_chain;
546 532
547 index = seq({'[', not_('['), space, Exp, space, ']'}); 533 index = '[' >> not_('[') >> space >> Exp >> space >> ']';
548 chain_item = sel({ 534 chain_item =
549 Invoke >> -ExistentialOp, 535 Invoke >> -ExistentialOp |
550 DotChainItem >> -ExistentialOp, 536 DotChainItem >> -ExistentialOp |
551 Slice, 537 Slice |
552 index >> -ExistentialOp 538 index >> -ExistentialOp;
553 }); 539 DotChainItem = '.' >> (Name | Metatable | Metamethod);
554 DotChainItem = '.' >> sel({Name, Metatable, Metamethod}); 540 ColonChainItem = (expr('\\') | "::") >> (LuaKeyword | Name | Metamethod);
555 ColonChainItem = sel({'\\', "::"}) >> sel({LuaKeyword, Name, Metamethod});
556 invoke_chain = Invoke >> -ExistentialOp >> -chain_items; 541 invoke_chain = Invoke >> -ExistentialOp >> -chain_items;
557 colon_chain = ColonChainItem >> -ExistentialOp >> -invoke_chain; 542 colon_chain = ColonChainItem >> -ExistentialOp >> -invoke_chain;
558 543
559 DefaultValue = true_(); 544 DefaultValue = true_();
560 Slice = seq({ 545 Slice =
561 '[', not_('['), 546 '[' >> not_('[') >>
562 space, Exp | DefaultValue, 547 space >> (Exp | DefaultValue) >>
563 space, ',', 548 space >> ',' >>
564 space, Exp | DefaultValue, 549 space >> (Exp | DefaultValue) >>
565 space, ',' >> space >> Exp | DefaultValue, 550 space >> (',' >> space >> Exp | DefaultValue) >>
566 space, ']' 551 space >> ']';
567 }); 552
568 553 Invoke = Seperator >> (
569 Invoke = Seperator >> sel({ 554 fn_args |
570 fn_args, 555 SingleString |
571 SingleString, 556 DoubleString |
572 DoubleString, 557 and_('[') >> LuaString |
573 and_('[') >> LuaString,
574 and_('{') >> TableLit 558 and_('{') >> TableLit
575 }); 559 );
576 560
577 SpreadExp = "..." >> space >> Exp; 561 SpreadExp = "..." >> space >> Exp;
578 562
579 table_value = sel({ 563 table_value =
580 VariablePairDef, 564 VariablePairDef |
581 NormalPairDef, 565 NormalPairDef |
582 MetaVariablePairDef, 566 MetaVariablePairDef |
583 MetaNormalPairDef, 567 MetaNormalPairDef |
584 SpreadExp, 568 SpreadExp |
585 NormalDef 569 NormalDef;
586 });
587 570
588 table_lit_lines = space_break >> table_lit_line >> *(-(space >> ',') >> space_break >> table_lit_line) >> -(space >> ','); 571 table_lit_lines = space_break >> table_lit_line >> *(-(space >> ',') >> space_break >> table_lit_line) >> -(space >> ',');
589 572
590 TableLit = seq({ 573 TableLit =
591 space, '{', Seperator, 574 space >> '{' >> Seperator >>
592 -(space >> table_value_list), 575 -(space >> table_value_list) >>
593 -(space >> ','), 576 -(space >> ',') >>
594 -table_lit_lines, 577 -table_lit_lines >>
595 white, '}' 578 white >> '}';
596 });
597 579
598 table_value_list = table_value >> *seq({space, ',', space, table_value}); 580 table_value_list = table_value >> *(space >> ',' >> space >> table_value);
599 581
600 table_lit_line = ( 582 table_lit_line = (
601 push_indent_match >> (space >> table_value_list >> pop_indent | pop_indent) 583 push_indent_match >> (space >> table_value_list >> pop_indent | pop_indent)
@@ -611,21 +593,22 @@ YueParser::YueParser() {
611 593
612 ClassMemberList = Seperator >> key_value >> *(space >> ',' >> space >> key_value); 594 ClassMemberList = Seperator >> key_value >> *(space >> ',' >> space >> key_value);
613 class_line = check_indent_match >> space >> (ClassMemberList | Statement) >> -(space >> ','); 595 class_line = check_indent_match >> space >> (ClassMemberList | Statement) >> -(space >> ',');
614 ClassBlock = seq({+space_break, advance_match, Seperator, class_line, *(+space_break >> class_line), pop_indent}); 596 ClassBlock =
615 597 +space_break >>
616 ClassDecl = seq({ 598 advance_match >> Seperator >>
617 key("class"), not_(':'), 599 class_line >> *(+space_break >> class_line) >>
618 disable_arg_table_block_rule(seq({ 600 pop_indent;
619 -(space >> Assignable), 601
620 -seq({space, key("extends"), prevent_indent, space, ensure(Exp, pop_indent)}), 602 ClassDecl =
621 -seq({space, key("using"), prevent_indent, space, ensure(ExpList, pop_indent)}) 603 key("class") >> not_(':') >> disable_arg_table_block_rule(
622 })), 604 -(space >> Assignable) >>
623 -ClassBlock 605 -(space >> key("extends") >> prevent_indent >> space >> ensure(Exp, pop_indent)) >>
624 }); 606 -(space >> key("using") >> prevent_indent >> space >> ensure(ExpList, pop_indent))
607 ) >> -ClassBlock;
625 608
626 GlobalValues = NameList >> -(space >> '=' >> space >> (TableBlock | ExpListLow)); 609 GlobalValues = NameList >> -(space >> '=' >> space >> (TableBlock | ExpListLow));
627 GlobalOp = sel({'*', '^'}); 610 GlobalOp = expr('*') | '^';
628 Global = key("global") >> space >> sel({ClassDecl, GlobalOp, GlobalValues}); 611 Global = key("global") >> space >> (ClassDecl | GlobalOp | GlobalValues);
629 612
630 ExportDefault = key("default"); 613 ExportDefault = key("default");
631 614
@@ -659,57 +642,51 @@ YueParser::YueParser() {
659 642
660 VariablePair = ':' >> Variable; 643 VariablePair = ':' >> Variable;
661 644
662 NormalPair = seq({ 645 NormalPair =
663 sel({ 646 (
664 KeyName, 647 KeyName |
665 seq({'[', not_('['), space, Exp, space, ']'}), 648 '[' >> not_('[') >> space >> Exp >> space >> ']' |
666 String 649 String
667 }), 650 ) >> ':' >> not_(':') >> space >>
668 ':', not_(':'), space, 651 (Exp | TableBlock | +space_break >> space >> Exp);
669 sel({Exp, TableBlock, +space_break >> space >> Exp})
670 });
671 652
672 MetaVariablePair = ":<" >> space >> Variable >> space >> '>'; 653 MetaVariablePair = ":<" >> space >> Variable >> space >> '>';
673 654
674 MetaNormalPair = '<' >> space >> -meta_index >> space >> ">:" >> space >> 655 MetaNormalPair = '<' >> space >> -meta_index >> space >> ">:" >> space >>
675 sel({Exp, TableBlock, +space_break >> space >> Exp}); 656 (Exp | TableBlock | +space_break >> space >> Exp);
676 657
677 destruct_def = -seq({space, '=', space, Exp}); 658 destruct_def = -(space >> '=' >> space >> Exp);
678 VariablePairDef = VariablePair >> destruct_def; 659 VariablePairDef = VariablePair >> destruct_def;
679 NormalPairDef = NormalPair >> destruct_def; 660 NormalPairDef = NormalPair >> destruct_def;
680 MetaVariablePairDef = MetaVariablePair >> destruct_def; 661 MetaVariablePairDef = MetaVariablePair >> destruct_def;
681 MetaNormalPairDef = MetaNormalPair >> destruct_def; 662 MetaNormalPairDef = MetaNormalPair >> destruct_def;
682 NormalDef = Exp >> Seperator >> destruct_def; 663 NormalDef = Exp >> Seperator >> destruct_def;
683 664
684 key_value = sel({ 665 key_value =
685 VariablePair, 666 VariablePair |
686 NormalPair, 667 NormalPair |
687 MetaVariablePair, 668 MetaVariablePair |
688 MetaNormalPair 669 MetaNormalPair;
689 });
690 key_value_list = key_value >> *(space >> ',' >> space >> key_value); 670 key_value_list = key_value >> *(space >> ',' >> space >> key_value);
691 key_value_line = check_indent_match >> space >> sel({ 671 key_value_line = check_indent_match >> space >> (
692 key_value_list >> -(space >> ','), 672 key_value_list >> -(space >> ',') |
693 TableBlockIndent, 673 TableBlockIndent |
694 '*' >> space >> sel({SpreadExp, Exp, TableBlock}) 674 '*' >> space >> (SpreadExp | Exp | TableBlock)
695 }); 675 );
696 676
697 FnArgDef = (Variable | SelfItem >> -ExistentialOp) >> -(space >> '=' >> space >> Exp); 677 FnArgDef = (Variable | SelfItem >> -ExistentialOp) >> -(space >> '=' >> space >> Exp);
698 678
699 FnArgDefList = Seperator >> ( 679 FnArgDefList = Seperator >> ((
700 seq({ 680 FnArgDef >>
701 FnArgDef, 681 *(space >> (',' | line_break) >> white >> FnArgDef) >>
702 *seq({space, ',' | line_break, white, FnArgDef}), 682 -(space >> (',' | line_break) >> white >> VarArg)
703 -seq({space, ',' | line_break, white, VarArg}) 683 ) | VarArg);
704 }) |
705 VarArg
706 );
707 684
708 OuterVarShadow = key("using") >> space >> (NameList | key("nil")); 685 OuterVarShadow = key("using") >> space >> (NameList | key("nil"));
709 686
710 FnArgsDef = seq({'(', white, -FnArgDefList, -(space >> OuterVarShadow), white, ')'}); 687 FnArgsDef = '(' >> white >> -FnArgDefList >> -(space >> OuterVarShadow) >> white >> ')';
711 FnArrow = sel({"->", "=>"}); 688 FnArrow = expr("->") | "=>";
712 FunLit = seq({-FnArgsDef, space, FnArrow, -(space >> Body)}); 689 FunLit = -FnArgsDef >> space >> FnArrow >> -(space >> Body);
713 690
714 MacroName = '$' >> Name; 691 MacroName = '$' >> Name;
715 macro_args_def = '(' >> white >> -FnArgDefList >> white >> ')'; 692 macro_args_def = '(' >> white >> -FnArgDefList >> white >> ')';
@@ -722,15 +699,11 @@ YueParser::YueParser() {
722 AssignableNameList = Seperator >> NameOrDestructure >> *(space >> ',' >> space >> NameOrDestructure); 699 AssignableNameList = Seperator >> NameOrDestructure >> *(space >> ',' >> space >> NameOrDestructure);
723 700
724 FnArrowBack = '<' >> set("-="); 701 FnArrowBack = '<' >> set("-=");
725 Backcall = seq({-(FnArgsDef >> space), FnArrowBack, space, ChainValue}); 702 Backcall = -(FnArgsDef >> space) >> FnArrowBack >> space >> ChainValue;
726 703
727 PipeBody = seq({ 704 PipeBody = Seperator >>
728 Seperator, 705 pipe_operator >> space >> UnaryExp >>
729 pipe_operator, 706 *(+space_break >> check_indent_match >> space >> pipe_operator >> space >> UnaryExp);
730 space,
731 UnaryExp,
732 *seq({+space_break, check_indent_match, space, pipe_operator, space, UnaryExp})
733 });
734 707
735 ExpList = Seperator >> Exp >> *(space >> ',' >> space >> Exp); 708 ExpList = Seperator >> Exp >> *(space >> ',' >> space >> Exp);
736 ExpListLow = Seperator >> Exp >> *(space >> set(",;") >> space >> Exp); 709 ExpListLow = Seperator >> Exp >> *(space >> set(",;") >> space >> Exp);
@@ -755,21 +728,19 @@ YueParser::YueParser() {
755 }); 728 });
756 729
757 InvokeArgs = 730 InvokeArgs =
758 not_(set("-~")) >> space >> Seperator >> 731 not_(set("-~")) >> space >> Seperator >> (
759 sel({ 732 Exp >> *(space >> ',' >> space >> Exp) >> -(space >> invoke_args_with_table) |
760 Exp >> *(space >> ',' >> space >> Exp) >> -(space >> invoke_args_with_table), 733 arg_table_block |
761 arg_table_block,
762 leading_spaces_error 734 leading_spaces_error
763 }); 735 );
764 736
765 ConstValue = sel({"nil", "true", "false"}) >> not_alpha_num; 737 ConstValue = (expr("nil") | "true" | "false") >> not_alpha_num;
766 738
767 SimpleValue = sel({ 739 SimpleValue =
768 TableLit, ConstValue, If, Switch, Try, With, 740 TableLit | ConstValue | If | Switch | Try | With |
769 ClassDecl, ForEach, For, While, Do, 741 ClassDecl | ForEach | For | While | Do |
770 UnaryValue, TblComprehension, Comprehension, 742 UnaryValue | TblComprehension | Comprehension |
771 FunLit, Num 743 FunLit | Num;
772 });
773 744
774 ExpListAssign = ExpList >> -(space >> (Update | Assign)) >> not_(space >> '='); 745 ExpListAssign = ExpList >> -(space >> (Update | Assign)) >> not_(space >> '=');
775 746
@@ -780,70 +751,66 @@ YueParser::YueParser() {
780 yue_line_comment = "--" >> YueLineComment >> and_(stop); 751 yue_line_comment = "--" >> YueLineComment >> and_(stop);
781 YueMultilineComment = multi_line_content; 752 YueMultilineComment = multi_line_content;
782 yue_multiline_comment = multi_line_open >> YueMultilineComment >> multi_line_close; 753 yue_multiline_comment = multi_line_open >> YueMultilineComment >> multi_line_close;
783 yue_comment = check_indent >> sel({ 754 yue_comment = check_indent >> (
784 seq({ 755 (
785 yue_multiline_comment, 756 yue_multiline_comment >>
786 *(set(" \t") | yue_multiline_comment), 757 *(set(" \t") | yue_multiline_comment) >>
787 -yue_line_comment 758 -yue_line_comment
788 }), 759 ) | yue_line_comment
789 yue_line_comment 760 ) >> and_(line_break);
790 }) >> and_(line_break);
791 761
792 ChainAssign = Seperator >> Exp >> +(space >> '=' >> space >> Exp >> space >> and_('=')) >> space >> Assign; 762 ChainAssign = Seperator >> Exp >> +(space >> '=' >> space >> Exp >> space >> and_('=')) >> space >> Assign;
793 763
794 StatementAppendix = sel({IfLine, WhileLine, CompInner}) >> space; 764 StatementAppendix = (IfLine | WhileLine | CompInner) >> space;
795 StatementSep = and_(seq({ 765 StatementSep = and_(
796 *space_break, check_indent_match, space, 766 *space_break >> check_indent_match >> space >> (
797 sel({ 767 set("($'\"") |
798 set("($'\""), 768 "[[" |
799 "[[",
800 "[=" 769 "[="
801 }) 770 )
802 })); 771 );
803 Statement = seq({ 772 Statement =
804 Seperator, 773 Seperator >>
805 -seq({ 774 -(
806 yue_comment, 775 yue_comment >>
807 *(line_break >> yue_comment), 776 *(line_break >> yue_comment) >>
808 line_break, 777 line_break >>
809 check_indent_match 778 check_indent_match
810 }), 779 ) >>
811 space, 780 space >> (
812 sel({ 781 Import | While | Repeat | For | ForEach |
813 Import, While, Repeat, For, ForEach, 782 Return | Local | Global | Export | Macro |
814 Return, Local, Global, Export, Macro, 783 MacroInPlace | BreakLoop | Label | Goto | ShortTabAppending |
815 MacroInPlace, BreakLoop, Label, Goto, ShortTabAppending, 784 LocalAttrib | Backcall | PipeBody | ExpListAssign | ChainAssign |
816 LocalAttrib, Backcall, PipeBody, ExpListAssign, ChainAssign,
817 StatementAppendix >> empty_block_error 785 StatementAppendix >> empty_block_error
818 }), 786 ) >>
819 space, 787 space >>
820 -StatementAppendix, 788 -StatementAppendix >>
821 -StatementSep 789 -StatementSep;
822 });
823 790
824 Body = in_block | Statement; 791 Body = in_block | Statement;
825 792
826 empty_line_break = sel({ 793 empty_line_break = (
827 check_indent >> (multi_line_comment >> space | comment), 794 check_indent >> (multi_line_comment >> space | comment) |
828 advance >> ensure(multi_line_comment >> space | comment, pop_indent), 795 advance >> ensure(multi_line_comment >> space | comment, pop_indent) |
829 plain_space 796 plain_space
830 }) >> and_(line_break); 797 ) >> and_(line_break);
831 798
832 indentation_error = pl::user(not_(pipe_operator | eof()), [](const item_t& item) { 799 indentation_error = pl::user(not_(pipe_operator | eof()), [](const item_t& item) {
833 throw ParserError("unexpected indent", *item.begin, *item.end); 800 throw ParserError("unexpected indent", *item.begin, *item.end);
834 return false; 801 return false;
835 }); 802 });
836 803
837 line = sel({ 804 line = (
838 check_indent_match >> Statement, 805 check_indent_match >> Statement |
839 empty_line_break, 806 empty_line_break |
840 advance_match >> ensure(space >> (indentation_error | Statement), pop_indent) 807 advance_match >> ensure(space >> (indentation_error | Statement), pop_indent)
841 }); 808 );
842 Block = seq({Seperator, line, *(+line_break >> line)}); 809 Block = Seperator >> line >> *(+line_break >> line);
843 810
844 shebang = "#!" >> *(not_(stop) >> any_char); 811 shebang = "#!" >> *(not_(stop) >> any_char);
845 BlockEnd = seq({Block, white, stop}); 812 BlockEnd = Block >> white >> stop;
846 File = seq({-shebang, -Block, white, stop}); 813 File = -shebang >> -Block >> white >> stop;
847} 814}
848// clang-format on 815// clang-format on
849 816