aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2023-01-17 11:07:11 +0800
committerLi Jin <dragon-fly@qq.com>2023-01-17 11:07:11 +0800
commit57aacbf7e79065df03f590a8ad9e8516c202bc54 (patch)
tree7896b98fa4d9eaca550bddadb4036d5b525b2f6c
parent0dfff530f1b0be147e5cf44b9e3786a3f5b35a27 (diff)
downloadyuescript-57aacbf7e79065df03f590a8ad9e8516c202bc54.tar.gz
yuescript-57aacbf7e79065df03f590a8ad9e8516c202bc54.tar.bz2
yuescript-57aacbf7e79065df03f590a8ad9e8516c202bc54.zip
more optimization for parser.
-rw-r--r--src/yuescript/yue_parser.cpp197
-rw-r--r--src/yuescript/yue_parser.h1
2 files changed, 105 insertions, 93 deletions
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp
index e8b47b7..e3d6b07 100644
--- a/src/yuescript/yue_parser.cpp
+++ b/src/yuescript/yue_parser.cpp
@@ -44,17 +44,17 @@ YueParser::YueParser() {
44 MultiLineComment = multi_line_open >> multi_line_content >> multi_line_close; 44 MultiLineComment = multi_line_open >> multi_line_content >> multi_line_close;
45 EscapeNewLine = expr('\\') >> *(set(" \t") | MultiLineComment) >> -Comment >> Break; 45 EscapeNewLine = expr('\\') >> *(set(" \t") | MultiLineComment) >> -Comment >> Break;
46 space_one = set(" \t") | and_(set("-\\")) >> (MultiLineComment | EscapeNewLine); 46 space_one = set(" \t") | and_(set("-\\")) >> (MultiLineComment | EscapeNewLine);
47 Space = *space_one >> -Comment; 47 Space = -(and_(set(" \t-\\")) >> *space_one >> -Comment);
48 SpaceBreak = Space >> Break; 48 SpaceBreak = Space >> Break;
49 White = Space >> *(Break >> Space); 49 White = Space >> *(Break >> Space);
50 EmptyLine = SpaceBreak; 50 EmptyLine = SpaceBreak;
51 AlphaNum = range('a', 'z') | range('A', 'Z') | range('0', '9') | '_'; 51 AlphaNum = sel({range('a', 'z'), range('A', 'Z'), range('0', '9'), expr('_')});
52 Name = (range('a', 'z') | range('A', 'Z') | '_') >> *AlphaNum; 52 Name = sel({range('a', 'z'), range('A', 'Z'), expr('_')}) >> *AlphaNum;
53 num_expo = set("eE") >> -set("+-") >> num_char; 53 num_expo = set("eE") >> -set("+-") >> num_char;
54 num_expo_hex = set("pP") >> -set("+-") >> num_char; 54 num_expo_hex = set("pP") >> -set("+-") >> num_char;
55 lj_num = -set("uU") >> set("lL") >> set("lL"); 55 lj_num = -set("uU") >> set("lL") >> set("lL");
56 num_char = range('0', '9') >> *(range('0', '9') | expr('_') >> and_(range('0', '9'))); 56 num_char = range('0', '9') >> *(range('0', '9') | expr('_') >> and_(range('0', '9')));
57 num_char_hex = range('0', '9') | range('a', 'f') | range('A', 'F'); 57 num_char_hex = sel({range('0', '9'), range('a', 'f'), range('A', 'F')});
58 num_lit = num_char_hex >> *(num_char_hex | expr('_') >> and_(num_char_hex)); 58 num_lit = num_char_hex >> *(num_char_hex | expr('_') >> and_(num_char_hex));
59 Num = sel({ 59 Num = sel({
60 expr("0x") >> ( 60 expr("0x") >> (
@@ -84,16 +84,15 @@ YueParser::YueParser() {
84 return false; 84 return false;
85 }); 85 });
86 86
87 #define sym(str) (Space >> str)
88 #define ensure(patt, finally) ((patt) >> (finally) | (finally) >> Cut) 87 #define ensure(patt, finally) ((patt) >> (finally) | (finally) >> Cut)
89 #define key(str) (str >> not_(AlphaNum)) 88 #define key(str) (str >> not_(AlphaNum))
90 #define disable_do(patt) (DisableDo >> ((patt) >> EnableDo | EnableDo >> Cut)) 89 #define disable_do(patt) (DisableDo >> ((patt) >> EnableDo | EnableDo >> Cut))
91 #define disable_chain(patt) (DisableChain >> ((patt) >> EnableChain | EnableChain >> Cut)) 90 #define disable_chain(patt) (DisableChain >> ((patt) >> EnableChain | EnableChain >> Cut))
92 #define disable_do_chain_arg_table_block(patt) (DisableDoChainArgTableBlock >> ((patt) >> EnableDoChainArgTableBlock | EnableDoChainArgTableBlock >> Cut)) 91 #define disable_do_chain_arg_table_block(patt) (DisableDoChainArgTableBlock >> ((patt) >> EnableDoChainArgTableBlock | EnableDoChainArgTableBlock >> Cut))
93 #define disable_arg_table_block(patt) (DisableArgTableBlock >> ((patt) >> EnableArgTableBlock | EnableArgTableBlock >> Cut)) 92 #define disable_arg_table_block(patt) (DisableArgTableBlock >> ((patt) >> EnableArgTableBlock | EnableArgTableBlock >> Cut))
94 #define body_with(str) (Space >> (key(str) >> Space >> (InBlock | Statement) | InBlock | empty_block_error)) 93 #define body_with(str) (Space >> sel({key(str) >> Space >> (InBlock | Statement), InBlock, empty_block_error}))
95 #define opt_body_with(str) (Space >> (key(str) >> Space >> (InBlock | Statement) | InBlock)) 94 #define opt_body_with(str) (Space >> (key(str) >> Space >> (InBlock | Statement) | InBlock))
96 #define body (Space >> (InBlock | Statement | empty_block_error)) 95 #define body (Space >> sel({InBlock, Statement, empty_block_error}))
97 96
98 Variable = pl::user(Name, [](const item_t& item) { 97 Variable = pl::user(Name, [](const item_t& item) {
99 State* st = reinterpret_cast<State*>(item.user_data); 98 State* st = reinterpret_cast<State*>(item.user_data);
@@ -194,53 +193,53 @@ YueParser::YueParser() {
194 InBlock = Space >> +(plain_space >> Break) >> Advance >> ensure(Block, PopIndent); 193 InBlock = Space >> +(plain_space >> Break) >> Advance >> ensure(Block, PopIndent);
195 194
196 local_flag = expr('*') | expr('^'); 195 local_flag = expr('*') | expr('^');
197 local_values = NameList >> -(sym('=') >> (TableBlock | ExpListLow)); 196 local_values = NameList >> -(Space >> expr('=') >> (TableBlock | ExpListLow));
198 Local = key("local") >> (Space >> local_flag | local_values); 197 Local = key("local") >> (Space >> local_flag | local_values);
199 198
200 const_attrib = key("const"); 199 const_attrib = key("const");
201 close_attrib = key("close"); 200 close_attrib = key("close");
202 local_const_item = (Space >> Variable | simple_table | TableLit); 201 local_const_item = sel({Space >> Variable, simple_table, TableLit});
203 LocalAttrib = ( 202 LocalAttrib = (
204 const_attrib >> Seperator >> local_const_item >> *(sym(',') >> local_const_item) | 203 const_attrib >> Seperator >> local_const_item >> *(Space >> expr(',') >> local_const_item) |
205 close_attrib >> Seperator >> Space >> Variable >> *(sym(',') >> Space >> Variable) 204 close_attrib >> Seperator >> Space >> Variable >> *(Space >> expr(',') >> Space >> Variable)
206 ) >> Assign; 205 ) >> Assign;
207 206
208 colon_import_name = sym('\\') >> Space >> Variable; 207 colon_import_name = Space >> expr('\\') >> Space >> Variable;
209 ImportName = colon_import_name | Space >> Variable; 208 ImportName = colon_import_name | Space >> Variable;
210 ImportNameList = Seperator >> *SpaceBreak >> ImportName >> *((+SpaceBreak | sym(',') >> *SpaceBreak) >> ImportName); 209 ImportNameList = Seperator >> *SpaceBreak >> ImportName >> *((+SpaceBreak | Space >> expr(',') >> *SpaceBreak) >> ImportName);
211 ImportFrom = ImportNameList >> *SpaceBreak >> Space >> key("from") >> Exp; 210 ImportFrom = ImportNameList >> *SpaceBreak >> Space >> key("from") >> Exp;
212 211
213 import_literal_inner = (range('a', 'z') | range('A', 'Z') | set("_-")) >> *(AlphaNum | '-'); 212 import_literal_inner = (range('a', 'z') | range('A', 'Z') | set("_-")) >> *(AlphaNum | '-');
214 import_literal_chain = Seperator >> import_literal_inner >> *(expr('.') >> import_literal_inner); 213 import_literal_chain = Seperator >> import_literal_inner >> *(expr('.') >> import_literal_inner);
215 ImportLiteral = sym('\'') >> import_literal_chain >> expr('\'') | sym('"') >> import_literal_chain >> expr('"'); 214 ImportLiteral = Space >> expr('\'') >> import_literal_chain >> expr('\'') | Space >> expr('"') >> import_literal_chain >> expr('"');
216 215
217 macro_name_pair = Space >> MacroName >> Space >> expr(':') >> Space >> MacroName; 216 macro_name_pair = Space >> MacroName >> Space >> expr(':') >> Space >> MacroName;
218 import_all_macro = expr('$'); 217 import_all_macro = expr('$');
219 ImportTabItem = sel({ 218 ImportTabItem = sel({
220 variable_pair, 219 variable_pair,
221 normal_pair, 220 normal_pair,
222 sym(':') >> MacroName, 221 Space >> expr(':') >> MacroName,
223 macro_name_pair, 222 macro_name_pair,
224 Space >> import_all_macro, 223 Space >> import_all_macro,
225 meta_variable_pair, 224 meta_variable_pair,
226 meta_normal_pair, 225 meta_normal_pair,
227 Exp 226 Exp
228 }); 227 });
229 ImportTabList = ImportTabItem >> *(sym(',') >> ImportTabItem); 228 ImportTabList = ImportTabItem >> *(Space >> expr(',') >> ImportTabItem);
230 ImportTabLine = ( 229 ImportTabLine = (
231 PushIndent >> (ImportTabList >> PopIndent | PopIndent) 230 PushIndent >> (ImportTabList >> PopIndent | PopIndent)
232 ) | Space; 231 ) | Space;
233 import_tab_lines = SpaceBreak >> ImportTabLine >> *(-sym(',') >> SpaceBreak >> ImportTabLine) >> -sym(','); 232 import_tab_lines = SpaceBreak >> ImportTabLine >> *(-(Space >> expr(',')) >> SpaceBreak >> ImportTabLine) >> -(Space >> expr(','));
234 ImportTabLit = seq({ 233 ImportTabLit = seq({
235 Seperator, 234 Seperator,
236 sym('{'), 235 Space, expr('{'),
237 -ImportTabList, 236 -ImportTabList,
238 -sym(','), 237 -(Space >> expr(',')),
239 -import_tab_lines, 238 -import_tab_lines,
240 White, 239 White,
241 sym('}') 240 expr('}')
242 }) | seq({ 241 }) | seq({
243 Seperator, KeyValue, *(sym(',') >> KeyValue) 242 Seperator, KeyValue, *(Space >> expr(',') >> KeyValue)
244 }); 243 });
245 244
246 ImportAs = ImportLiteral >> -(Space >> key("as") >> Space >> (ImportTabLit | Variable | import_all_macro)); 245 ImportAs = ImportLiteral >> -(Space >> key("as") >> Space >> (ImportTabLit | Variable | import_all_macro));
@@ -269,7 +268,10 @@ YueParser::YueParser() {
269 268
270 exp_not_tab = not_(simple_table | TableLit) >> Exp; 269 exp_not_tab = not_(simple_table | TableLit) >> Exp;
271 270
272 SwitchList = Seperator >> (and_(simple_table | TableLit) >> Exp | exp_not_tab >> *(sym(',') >> exp_not_tab)); 271 SwitchList = Seperator >> (
272 and_(simple_table | TableLit) >> Exp |
273 exp_not_tab >> *(Space >> expr(',') >> exp_not_tab)
274 );
273 Switch = Space >> key("switch") >> Exp >> 275 Switch = Space >> key("switch") >> Exp >>
274 Seperator >> ( 276 Seperator >> (
275 SwitchCase >> Space >> ( 277 SwitchCase >> Space >> (
@@ -290,8 +292,8 @@ YueParser::YueParser() {
290 While = WhileType >> disable_do_chain_arg_table_block(Exp) >> opt_body_with("do"); 292 While = WhileType >> disable_do_chain_arg_table_block(Exp) >> opt_body_with("do");
291 Repeat = seq({key("repeat"), Body, Break, *EmptyLine, CheckIndent, Space, key("until"), Exp}); 293 Repeat = seq({key("repeat"), Body, Break, *EmptyLine, CheckIndent, Space, key("until"), Exp});
292 294
293 for_step_value = sym(',') >> Exp; 295 for_step_value = Space >> expr(',') >> Exp;
294 for_args = Space >> Variable >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value; 296 for_args = Space >> Variable >> Space >> expr('=') >> Exp >> Space >> expr(',') >> Exp >> -for_step_value;
295 297
296 For = key("for") >> disable_do_chain_arg_table_block(for_args) >> opt_body_with("do"); 298 For = key("for") >> disable_do_chain_arg_table_block(for_args) >> opt_body_with("do");
297 299
@@ -348,17 +350,17 @@ YueParser::YueParser() {
348 catch_block = Break >> *EmptyLine >> CheckIndent >> Space >> key("catch") >> Space >> Variable >> InBlock; 350 catch_block = Break >> *EmptyLine >> CheckIndent >> Space >> key("catch") >> Space >> Variable >> InBlock;
349 Try = Space >> key("try") >> (InBlock | Exp) >> -catch_block; 351 Try = Space >> key("try") >> (InBlock | Exp) >> -catch_block;
350 352
351 Comprehension = sym('[') >> not_('[') >> Exp >> Space >> CompInner >> sym(']'); 353 Comprehension = Space >> expr('[') >> not_('[') >> Exp >> Space >> CompInner >> Space >> expr(']');
352 comp_value = sym(',') >> Exp; 354 comp_value = Space >> expr(',') >> Exp;
353 TblComprehension = sym('{') >> Exp >> -comp_value >> Space >> CompInner >> sym('}'); 355 TblComprehension = Space >> expr('{') >> Exp >> -comp_value >> Space >> CompInner >> Space >> expr('}');
354 356
355 CompInner = Seperator >> (CompForEach | CompFor) >> *CompClause; 357 CompInner = Seperator >> (CompForEach | CompFor) >> *CompClause;
356 star_exp = sym('*') >> Exp; 358 star_exp = Space >> expr('*') >> Exp;
357 CompForEach = key("for") >> AssignableNameList >> Space >> key("in") >> (star_exp | Exp); 359 CompForEach = key("for") >> AssignableNameList >> Space >> key("in") >> (star_exp | Exp);
358 CompFor = key("for") >> Space >> Variable >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value; 360 CompFor = key("for") >> Space >> Variable >> Space >> expr('=') >> Exp >> Space >> expr(',') >> Exp >> -for_step_value;
359 CompClause = Space >> (CompFor | CompForEach | key("when") >> Exp); 361 CompClause = Space >> sel({CompFor, CompForEach, key("when") >> Exp});
360 362
361 Assign = sym('=') >> Seperator >> sel({ 363 Assign = Space >> expr('=') >> Seperator >> sel({
362 With, If, Switch, TableBlock, 364 With, If, Switch, TableBlock,
363 Exp >> *(Space >> set(",;") >> Exp) 365 Exp >> *(Space >> set(",;") >> Exp)
364 }); 366 });
@@ -376,7 +378,7 @@ YueParser::YueParser() {
376 378
377 Update = Space >> update_op >> expr("=") >> Exp; 379 Update = Space >> update_op >> expr("=") >> Exp;
378 380
379 Assignable = Space >> (AssignableChain | Variable | SelfName); 381 Assignable = Space >> sel({AssignableChain, Variable, SelfName});
380 382
381 unary_value = +(unary_operator >> Space) >> Value; 383 unary_value = +(unary_operator >> Space) >> Value;
382 384
@@ -439,12 +441,12 @@ YueParser::YueParser() {
439 -table_appending_op 441 -table_appending_op
440 }); 442 });
441 443
442 simple_table = seq({Seperator, KeyValue, *(sym(',') >> KeyValue)}); 444 simple_table = seq({Seperator, KeyValue, *(Space >> expr(',') >> KeyValue)});
443 Value = sel({SimpleValue, simple_table, ChainValue, String}); 445 Value = sel({SimpleValue, simple_table, ChainValue, String});
444 446
445 single_string_inner = expr('\\') >> set("'\\") | not_(expr('\'')) >> Any; 447 single_string_inner = expr('\\') >> set("'\\") | not_(expr('\'')) >> Any;
446 SingleString = expr('\'') >> *single_string_inner >> expr('\''); 448 SingleString = expr('\'') >> *single_string_inner >> expr('\'');
447 interp = expr("#{") >> Exp >> sym('}'); 449 interp = expr("#{") >> Exp >> Space >> expr('}');
448 double_string_plain = expr('\\') >> set("\"\\") | not_(expr('"')) >> Any; 450 double_string_plain = expr('\\') >> set("\"\\") | not_(expr('"')) >> Any;
449 double_string_inner = +(not_(interp) >> double_string_plain); 451 double_string_inner = +(not_(interp) >> double_string_plain);
450 double_string_content = double_string_inner | interp; 452 double_string_content = double_string_inner | interp;
@@ -521,8 +523,8 @@ YueParser::YueParser() {
521 Slice, 523 Slice,
522 Index >> -existential_op 524 Index >> -existential_op
523 }); 525 });
524 DotChainItem = expr('.') >> (Name | Metatable | Metamethod); 526 DotChainItem = expr('.') >> sel({Name, Metatable, Metamethod});
525 ColonChainItem = (expr('\\') | expr("::")) >> (LuaKeyword | Name | Metamethod); 527 ColonChainItem = (expr('\\') | expr("::")) >> sel({LuaKeyword, Name, Metamethod});
526 invoke_chain = Invoke >> -existential_op >> -ChainItems; 528 invoke_chain = Invoke >> -existential_op >> -ChainItems;
527 ColonChain = ColonChainItem >> -existential_op >> -invoke_chain; 529 ColonChain = ColonChainItem >> -existential_op >> -invoke_chain;
528 530
@@ -544,7 +546,7 @@ YueParser::YueParser() {
544 and_(expr('{')) >> TableLit 546 and_(expr('{')) >> TableLit
545 }); 547 });
546 548
547 SpreadExp = sym("...") >> Exp; 549 SpreadExp = Space >> expr("...") >> Exp;
548 550
549 TableValue = sel({ 551 TableValue = sel({
550 variable_pair_def, 552 variable_pair_def,
@@ -555,17 +557,17 @@ YueParser::YueParser() {
555 normal_def 557 normal_def
556 }); 558 });
557 559
558 table_lit_lines = SpaceBreak >> TableLitLine >> *(-sym(',') >> SpaceBreak >> TableLitLine) >> -sym(','); 560 table_lit_lines = SpaceBreak >> TableLitLine >> *(-(Space >> expr(',')) >> SpaceBreak >> TableLitLine) >> -(Space >> expr(','));
559 561
560 TableLit = seq({ 562 TableLit = seq({
561 sym('{'), Seperator, 563 Space, expr('{'), Seperator,
562 -TableValueList, 564 -TableValueList,
563 -sym(','), 565 -(Space >> expr(',')),
564 -table_lit_lines, 566 -table_lit_lines,
565 White, sym('}') 567 White, expr('}')
566 }); 568 });
567 569
568 TableValueList = TableValue >> *(sym(',') >> TableValue); 570 TableValueList = TableValue >> *(Space >> expr(',') >> TableValue);
569 571
570 TableLitLine = ( 572 TableLitLine = (
571 PushIndent >> (TableValueList >> PopIndent | PopIndent) 573 PushIndent >> (TableValueList >> PopIndent | PopIndent)
@@ -575,24 +577,27 @@ YueParser::YueParser() {
575 577
576 TableBlockInner = Seperator >> KeyValueLine >> *(+SpaceBreak >> KeyValueLine); 578 TableBlockInner = Seperator >> KeyValueLine >> *(+SpaceBreak >> KeyValueLine);
577 TableBlock = +SpaceBreak >> Advance >> ensure(TableBlockInner, PopIndent); 579 TableBlock = +SpaceBreak >> Advance >> ensure(TableBlockInner, PopIndent);
578 TableBlockIndent = sym('*') >> Seperator >> disable_arg_table_block( 580 TableBlockIndent = Space >> expr('*') >> Seperator >> disable_arg_table_block(
579 KeyValueList >> -sym(',') >> 581 KeyValueList >> -(Space >> expr(',')) >>
580 -(+SpaceBreak >> Advance >> ensure(KeyValueList >> -sym(',') >> *(+SpaceBreak >> KeyValueLine), PopIndent))); 582 -(+SpaceBreak >> Advance >> ensure(KeyValueList >> -(Space >> expr(',')) >> *(+SpaceBreak >> KeyValueLine), PopIndent)));
581 583
582 class_member_list = Seperator >> KeyValue >> *(sym(',') >> KeyValue); 584 class_member_list = Seperator >> KeyValue >> *(Space >> expr(',') >> KeyValue);
583 ClassLine = CheckIndent >> (class_member_list | Space >> Statement) >> -sym(','); 585 ClassLine = CheckIndent >> (class_member_list | Space >> Statement) >> -(Space >> expr(','));
584 ClassBlock = +SpaceBreak >> Advance >> Seperator >> ClassLine >> *(+SpaceBreak >> ClassLine) >> PopIndent; 586 ClassBlock = seq({+SpaceBreak, Advance, Seperator, ClassLine, *(+SpaceBreak >> ClassLine), PopIndent});
585 587
586 ClassDecl = 588 ClassDecl = seq({
587 Space >> key("class") >> not_(expr(':')) >> disable_arg_table_block( 589 Space, key("class"), not_(expr(':')),
588 -Assignable >> 590 disable_arg_table_block(seq({
589 -(Space >> key("extends") >> PreventIndent >> ensure(Exp, PopIndent)) >> 591 -Assignable,
590 -(Space >> key("using") >> PreventIndent >> ensure(ExpList, PopIndent)) 592 -seq({Space, key("extends"), PreventIndent, ensure(Exp, PopIndent)}),
591 ) >> -ClassBlock; 593 -seq({Space, key("using"), PreventIndent, ensure(ExpList, PopIndent)})
592 594 })),
593 global_values = NameList >> -(sym('=') >> (TableBlock | ExpListLow)); 595 -ClassBlock
596 });
597
598 global_values = NameList >> -(Space >> expr('=') >> (TableBlock | ExpListLow));
594 global_op = expr('*') | expr('^'); 599 global_op = expr('*') | expr('^');
595 Global = key("global") >> (ClassDecl | (Space >> global_op) | global_values); 600 Global = key("global") >> sel({ClassDecl, Space >> global_op, global_values});
596 601
597 export_default = key("default"); 602 export_default = key("default");
598 603
@@ -624,29 +629,30 @@ YueParser::YueParser() {
624 return true; 629 return true;
625 })) >> not_(Space >> statement_appendix); 630 })) >> not_(Space >> statement_appendix);
626 631
627 variable_pair = sym(':') >> Variable; 632 variable_pair = Space >> expr(':') >> Variable;
628 633
629 normal_pair = seq({ 634 normal_pair = seq({
630 Space, 635 Space,
631 sel({ 636 sel({
632 KeyName, 637 KeyName,
633 seq({expr('['), not_('['), Exp, sym(']')}), 638 seq({expr('['), not_('['), Exp, Space >> expr(']')}),
634 String 639 String
635 }), 640 }),
636 expr(':'), not_(':'), 641 expr(':'), not_(':'),
637 sel({Exp, TableBlock, +SpaceBreak >> Exp}) 642 sel({Exp, TableBlock, +SpaceBreak >> Exp})
638 }); 643 });
639 644
640 meta_variable_pair = sym(":<") >> Space >> Variable >> sym('>'); 645 meta_variable_pair = Space >> expr(":<") >> Space >> Variable >> Space >> expr('>');
641 646
642 meta_normal_pair = sym('<') >> Space >> -meta_index >> sym(">:") >> 647 meta_normal_pair = Space >> expr('<') >> Space >> -meta_index >> Space >> expr(">:") >>
643 (Exp | TableBlock | +(SpaceBreak) >> Exp); 648 sel({Exp, TableBlock, +(SpaceBreak) >> Exp});
644 649
645 variable_pair_def = variable_pair >> -(sym('=') >> Exp); 650 destruct_def = -seq({Space, expr('='), Exp});
646 normal_pair_def = normal_pair >> -(sym('=') >> Exp); 651 variable_pair_def = variable_pair >> destruct_def;
647 meta_variable_pair_def = meta_variable_pair >> -(sym('=') >> Exp); 652 normal_pair_def = normal_pair >> destruct_def;
648 meta_normal_pair_def = meta_normal_pair >> -(sym('=') >> Exp); 653 meta_variable_pair_def = meta_variable_pair >> destruct_def;
649 normal_def = Exp >> Seperator >> -(sym('=') >> Exp); 654 meta_normal_pair_def = meta_normal_pair >> destruct_def;
655 normal_def = Exp >> Seperator >> destruct_def;
650 656
651 KeyValue = sel({ 657 KeyValue = sel({
652 variable_pair, 658 variable_pair,
@@ -654,16 +660,20 @@ YueParser::YueParser() {
654 meta_variable_pair, 660 meta_variable_pair,
655 meta_normal_pair 661 meta_normal_pair
656 }); 662 });
657 KeyValueList = KeyValue >> *(sym(',') >> KeyValue); 663 KeyValueList = KeyValue >> *(Space >> expr(',') >> KeyValue);
658 KeyValueLine = CheckIndent >> (KeyValueList >> -sym(',') | TableBlockIndent | Space >> expr('*') >> (SpreadExp | Exp | TableBlock)); 664 KeyValueLine = CheckIndent >> sel({
665 KeyValueList >> -(Space >> expr(',')),
666 TableBlockIndent,
667 Space >> expr('*') >> sel({SpreadExp, Exp, TableBlock})
668 });
659 669
660 FnArgDef = (Variable | SelfName >> -existential_op) >> -(sym('=') >> Space >> Exp); 670 FnArgDef = (Variable | SelfName >> -existential_op) >> -(Space >> expr('=') >> Space >> Exp);
661 671
662 FnArgDefList = Space >> Seperator >> ( 672 FnArgDefList = Space >> Seperator >> (
663 seq({ 673 seq({
664 FnArgDef, 674 FnArgDef,
665 *seq({(sym(',') | Break), White, FnArgDef}), 675 *seq({(Space >> expr(',') | Break), White, FnArgDef}),
666 -seq({(sym(',') | Break), White, VarArg}) 676 -seq({(Space >> expr(',') | Break), White, VarArg})
667 }) | 677 }) |
668 VarArg 678 VarArg
669 ); 679 );
@@ -675,14 +685,14 @@ YueParser::YueParser() {
675 FunLit = seq({-FnArgsDef, Space, fn_arrow, -Body}); 685 FunLit = seq({-FnArgsDef, Space, fn_arrow, -Body});
676 686
677 MacroName = expr('$') >> Name; 687 MacroName = expr('$') >> Name;
678 macro_args_def = sym('(') >> White >> -FnArgDefList >> White >> sym(')'); 688 macro_args_def = Space >> expr('(') >> White >> -FnArgDefList >> White >> Space >> expr(')');
679 MacroLit = -macro_args_def >> Space >> expr("->") >> Body; 689 MacroLit = -macro_args_def >> Space >> expr("->") >> Body;
680 Macro = key("macro") >> Space >> Name >> sym('=') >> MacroLit; 690 Macro = key("macro") >> Space >> Name >> Space >> expr('=') >> MacroLit;
681 MacroInPlace = expr('$') >> Space >> expr("->") >> Body; 691 MacroInPlace = expr('$') >> Space >> expr("->") >> Body;
682 692
683 NameList = Seperator >> Space >> Variable >> *(sym(',') >> Space >> Variable); 693 NameList = Seperator >> Space >> Variable >> *(Space >> expr(',') >> Space >> Variable);
684 NameOrDestructure = Space >> Variable | TableLit; 694 NameOrDestructure = Space >> Variable | TableLit;
685 AssignableNameList = Seperator >> NameOrDestructure >> *(sym(',') >> NameOrDestructure); 695 AssignableNameList = Seperator >> NameOrDestructure >> *(Space >> expr(',') >> NameOrDestructure);
686 696
687 fn_arrow_back = expr('<') >> set("-="); 697 fn_arrow_back = expr('<') >> set("-=");
688 Backcall = seq({-FnArgsDef, Space, fn_arrow_back, Space, ChainValue}); 698 Backcall = seq({-FnArgsDef, Space, fn_arrow_back, Space, ChainValue});
@@ -694,11 +704,11 @@ YueParser::YueParser() {
694 *seq({+SpaceBreak, CheckIndent, Space, PipeOperator, unary_exp}) 704 *seq({+SpaceBreak, CheckIndent, Space, PipeOperator, unary_exp})
695 }); 705 });
696 706
697 ExpList = Seperator >> Exp >> *(sym(',') >> Exp); 707 ExpList = Seperator >> Exp >> *(Space >> expr(',') >> Exp);
698 ExpListLow = Seperator >> Exp >> *(Space >> set(",;") >> Exp); 708 ExpListLow = Seperator >> Exp >> *(Space >> set(",;") >> Exp);
699 709
700 ArgLine = CheckIndent >> Exp >> *(sym(',') >> Exp); 710 ArgLine = CheckIndent >> Exp >> *(Space >> expr(',') >> Exp);
701 ArgBlock = ArgLine >> *(sym(',') >> SpaceBreak >> ArgLine) >> PopIndent; 711 ArgBlock = ArgLine >> *(Space >> expr(',') >> SpaceBreak >> ArgLine) >> PopIndent;
702 712
703 arg_table_block = pl::user(true_(), [](const item_t& item) { 713 arg_table_block = pl::user(true_(), [](const item_t& item) {
704 State* st = reinterpret_cast<State*>(item.user_data); 714 State* st = reinterpret_cast<State*>(item.user_data);
@@ -706,23 +716,23 @@ YueParser::YueParser() {
706 }) >> TableBlock; 716 }) >> TableBlock;
707 717
708 invoke_args_with_table = 718 invoke_args_with_table =
709 sym(',') >> ( 719 Space >> expr(',') >> (
710 TableBlock | 720 TableBlock |
711 SpaceBreak >> Advance >> ArgBlock >> -arg_table_block 721 SpaceBreak >> Advance >> ArgBlock >> -arg_table_block
712 ) | arg_table_block; 722 ) | arg_table_block;
713 723
714 leading_spaces_error = pl::user(+space_one >> expr('(') >> Exp >> +(sym(',') >> Exp) >> sym(')'), [](const item_t& item) { 724 leading_spaces_error = pl::user(+space_one >> expr('(') >> Exp >> +(Space >> expr(',') >> Exp) >> Space >> expr(')'), [](const item_t& item) {
715 throw ParserError("write invoke arguments in parentheses without leading spaces or just leading spaces without parentheses", *item.begin, *item.end); 725 throw ParserError("write invoke arguments in parentheses without leading spaces or just leading spaces without parentheses", *item.begin, *item.end);
716 return false; 726 return false;
717 }); 727 });
718 728
719 InvokeArgs = 729 InvokeArgs =
720 not_(set("-~")) >> Seperator >> 730 not_(set("-~")) >> Seperator >>
721 ( 731 sel({
722 (Exp >> *(sym(',') >> Exp) >> -invoke_args_with_table) | 732 Exp >> *(Space >> expr(',') >> Exp) >> -invoke_args_with_table,
723 arg_table_block | 733 arg_table_block,
724 leading_spaces_error 734 leading_spaces_error
725 ); 735 });
726 736
727 const_value = sel({expr("nil"), expr("true"), expr("false")}) >> not_(AlphaNum); 737 const_value = sel({expr("nil"), expr("true"), expr("false")}) >> not_(AlphaNum);
728 738
@@ -744,9 +754,9 @@ YueParser::YueParser() {
744 yue_multiline_comment = multi_line_open >> YueMultilineComment >> multi_line_close; 754 yue_multiline_comment = multi_line_open >> YueMultilineComment >> multi_line_close;
745 yue_comment = check_indent >> (yue_multiline_comment >> *(set(" \t") | yue_multiline_comment) >> -yue_line_comment | yue_line_comment) >> and_(Break); 755 yue_comment = check_indent >> (yue_multiline_comment >> *(set(" \t") | yue_multiline_comment) >> -yue_line_comment | yue_line_comment) >> and_(Break);
746 756
747 ChainAssign = Seperator >> Exp >> +(sym('=') >> Exp >> Space >> and_('=')) >> Assign; 757 ChainAssign = Seperator >> Exp >> +(Space >> expr('=') >> Exp >> Space >> and_('=')) >> Assign;
748 758
749 statement_appendix = (if_line | while_line | CompInner) >> Space; 759 statement_appendix = sel({if_line, while_line, CompInner}) >> Space;
750 statement_sep = and_(seq({ 760 statement_sep = and_(seq({
751 *SpaceBreak, CheckIndent, Space, 761 *SpaceBreak, CheckIndent, Space,
752 sel({ 762 sel({
@@ -778,10 +788,11 @@ YueParser::YueParser() {
778 788
779 Body = InBlock | Space >> Statement; 789 Body = InBlock | Space >> Statement;
780 790
781 empty_line_break = ( 791 empty_line_break = sel({
782 check_indent >> (MultiLineComment >> Space | Comment) | 792 check_indent >> (MultiLineComment >> Space | Comment),
783 advance >> ensure(MultiLineComment >> Space | Comment, PopIndent) | 793 advance >> ensure(MultiLineComment >> Space | Comment, PopIndent),
784 plain_space) >> and_(Break); 794 plain_space
795 }) >> and_(Break);
785 796
786 indentation_error = pl::user(not_(PipeOperator | eof()), [](const item_t& item) { 797 indentation_error = pl::user(not_(PipeOperator | eof()), [](const item_t& item) {
787 throw ParserError("unexpected indent", *item.begin, *item.end); 798 throw ParserError("unexpected indent", *item.begin, *item.end);
diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h
index 1068468..0e87a71 100644
--- a/src/yuescript/yue_parser.h
+++ b/src/yuescript/yue_parser.h
@@ -185,6 +185,7 @@ private:
185 rule lua_string_close; 185 rule lua_string_close;
186 rule FnArgsExpList; 186 rule FnArgsExpList;
187 rule FnArgs; 187 rule FnArgs;
188 rule destruct_def;
188 rule macro_args_def; 189 rule macro_args_def;
189 rule chain_call; 190 rule chain_call;
190 rule chain_call_list; 191 rule chain_call_list;