diff options
author | Li Jin <dragon-fly@qq.com> | 2023-01-17 11:07:11 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2023-01-17 11:07:11 +0800 |
commit | 57aacbf7e79065df03f590a8ad9e8516c202bc54 (patch) | |
tree | 7896b98fa4d9eaca550bddadb4036d5b525b2f6c | |
parent | 0dfff530f1b0be147e5cf44b9e3786a3f5b35a27 (diff) | |
download | yuescript-57aacbf7e79065df03f590a8ad9e8516c202bc54.tar.gz yuescript-57aacbf7e79065df03f590a8ad9e8516c202bc54.tar.bz2 yuescript-57aacbf7e79065df03f590a8ad9e8516c202bc54.zip |
more optimization for parser.
-rw-r--r-- | src/yuescript/yue_parser.cpp | 197 | ||||
-rw-r--r-- | src/yuescript/yue_parser.h | 1 |
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; |