diff options
Diffstat (limited to '')
| -rw-r--r-- | src/yuescript/yue_parser.cpp | 64 |
1 files changed, 54 insertions, 10 deletions
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index 2fc1333..5bb4817 100644 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp | |||
| @@ -114,6 +114,13 @@ YueParser::YueParser() { | |||
| 114 | ) \ | 114 | ) \ |
| 115 | ) | 115 | ) |
| 116 | 116 | ||
| 117 | #define disable_for_rule(patt) ( \ | ||
| 118 | disable_for >> ( \ | ||
| 119 | (patt) >> enable_for | \ | ||
| 120 | enable_for >> cut \ | ||
| 121 | ) \ | ||
| 122 | ) | ||
| 123 | |||
| 117 | #define body_with(str) ( \ | 124 | #define body_with(str) ( \ |
| 118 | key(str) >> space >> (in_block | Statement) | \ | 125 | key(str) >> space >> (in_block | Statement) | \ |
| 119 | in_block | \ | 126 | in_block | \ |
| @@ -327,14 +334,18 @@ YueParser::YueParser() { | |||
| 327 | While = WhileType >> space >> disable_do_chain_arg_table_block_rule(Exp) >> space >> opt_body_with("do"); | 334 | While = WhileType >> space >> disable_do_chain_arg_table_block_rule(Exp) >> space >> opt_body_with("do"); |
| 328 | Repeat = key("repeat") >> space >> Body >> line_break >> *space_break >> check_indent_match >> space >> key("until") >> space >> Exp; | 335 | Repeat = key("repeat") >> space >> Body >> line_break >> *space_break >> check_indent_match >> space >> key("until") >> space >> Exp; |
| 329 | 336 | ||
| 337 | for_key = pl::user(key("for"), [](const item_t& item) { | ||
| 338 | State* st = reinterpret_cast<State*>(item.user_data); | ||
| 339 | return st->noForStack.empty() || !st->noForStack.top(); | ||
| 340 | }); | ||
| 330 | ForStepValue = ',' >> space >> Exp; | 341 | ForStepValue = ',' >> space >> Exp; |
| 331 | for_args = Variable >> space >> '=' >> space >> Exp >> space >> ',' >> space >> Exp >> space >> -ForStepValue; | 342 | for_args = Variable >> space >> '=' >> space >> Exp >> space >> ',' >> space >> Exp >> space >> -ForStepValue; |
| 332 | 343 | ||
| 333 | For = key("for") >> space >> disable_do_chain_arg_table_block_rule(for_args) >> space >> opt_body_with("do"); | 344 | For = for_key >> space >> disable_do_chain_arg_table_block_rule(for_args) >> space >> opt_body_with("do"); |
| 334 | 345 | ||
| 335 | for_in = StarExp | ExpList; | 346 | for_in = StarExp | ExpList; |
| 336 | 347 | ||
| 337 | ForEach = key("for") >> space >> AssignableNameList >> space >> key("in") >> space >> | 348 | ForEach = for_key >> space >> AssignableNameList >> space >> key("in") >> space >> |
| 338 | disable_do_chain_arg_table_block_rule(for_in) >> space >> opt_body_with("do"); | 349 | disable_do_chain_arg_table_block_rule(for_in) >> space >> opt_body_with("do"); |
| 339 | 350 | ||
| 340 | Do = pl::user(key("do"), [](const item_t& item) { | 351 | Do = pl::user(key("do"), [](const item_t& item) { |
| @@ -382,12 +393,24 @@ YueParser::YueParser() { | |||
| 382 | return true; | 393 | return true; |
| 383 | }); | 394 | }); |
| 384 | 395 | ||
| 396 | disable_for = pl::user(true_(), [](const item_t& item) { | ||
| 397 | State* st = reinterpret_cast<State*>(item.user_data); | ||
| 398 | st->noForStack.push(true); | ||
| 399 | return true; | ||
| 400 | }); | ||
| 401 | |||
| 402 | enable_for = pl::user(true_(), [](const item_t& item) { | ||
| 403 | State* st = reinterpret_cast<State*>(item.user_data); | ||
| 404 | st->noForStack.pop(); | ||
| 405 | return true; | ||
| 406 | }); | ||
| 407 | |||
| 385 | CatchBlock = line_break >> *space_break >> check_indent_match >> space >> key("catch") >> space >> Variable >> space >> in_block; | 408 | CatchBlock = line_break >> *space_break >> check_indent_match >> space >> key("catch") >> space >> Variable >> space >> in_block; |
| 386 | Try = key("try") >> space >> (in_block | Exp) >> -CatchBlock; | 409 | Try = key("try") >> space >> (in_block | Exp) >> -CatchBlock; |
| 387 | 410 | ||
| 388 | Comprehension = '[' >> not_('[') >> space >> Exp >> space >> CompInner >> space >> ']'; | 411 | Comprehension = '[' >> not_('[') >> space >> disable_for_rule(Exp) >> space >> CompInner >> space >> ']'; |
| 389 | CompValue = ',' >> space >> Exp; | 412 | CompValue = ',' >> space >> Exp; |
| 390 | TblComprehension = '{' >> (space >> Exp >> space >> -(CompValue >> space) >> CompInner >> space >> '}' | braces_expression_error); | 413 | TblComprehension = and_('{') >> ('{' >> space >> disable_for_rule(Exp >> space >> -(CompValue >> space)) >> CompInner >> space >> '}' | braces_expression_error); |
| 391 | 414 | ||
| 392 | CompInner = Seperator >> (CompForEach | CompFor) >> *(space >> comp_clause); | 415 | CompInner = Seperator >> (CompForEach | CompFor) >> *(space >> comp_clause); |
| 393 | StarExp = '*' >> space >> Exp; | 416 | StarExp = '*' >> space >> Exp; |
| @@ -461,8 +484,24 @@ YueParser::YueParser() { | |||
| 461 | -(InvokeArgs | chain_block) >> | 484 | -(InvokeArgs | chain_block) >> |
| 462 | -TableAppendingOp; | 485 | -TableAppendingOp; |
| 463 | 486 | ||
| 487 | inc_exp_level = pl::user(true_(), [](const item_t& item) { | ||
| 488 | State* st = reinterpret_cast<State*>(item.user_data); | ||
| 489 | st->expLevel++; | ||
| 490 | const int max_exp_level = 100; | ||
| 491 | if (st->expLevel > max_exp_level) { | ||
| 492 | throw ParserError("nesting expressions exceeds 100 levels", *item.begin, *item.end); | ||
| 493 | } | ||
| 494 | return true; | ||
| 495 | }); | ||
| 496 | |||
| 497 | dec_exp_level = pl::user(true_(), [](const item_t& item) { | ||
| 498 | State* st = reinterpret_cast<State*>(item.user_data); | ||
| 499 | st->expLevel--; | ||
| 500 | return true; | ||
| 501 | }); | ||
| 502 | |||
| 464 | SimpleTable = Seperator >> key_value >> *(space >> ',' >> space >> key_value); | 503 | SimpleTable = Seperator >> key_value >> *(space >> ',' >> space >> key_value); |
| 465 | Value = SimpleValue | SimpleTable | ChainValue | String; | 504 | Value = inc_exp_level >> ensure(SimpleValue | SimpleTable | ChainValue | String, dec_exp_level); |
| 466 | 505 | ||
| 467 | single_string_inner = '\\' >> set("'\\") | not_('\'') >> any_char; | 506 | single_string_inner = '\\' >> set("'\\") | not_('\'') >> any_char; |
| 468 | SingleString = '\'' >> *single_string_inner >> '\''; | 507 | SingleString = '\'' >> *single_string_inner >> '\''; |
| @@ -495,7 +534,7 @@ YueParser::YueParser() { | |||
| 495 | LuaString = LuaStringOpen >> -line_break >> LuaStringContent >> LuaStringClose; | 534 | LuaString = LuaStringOpen >> -line_break >> LuaStringContent >> LuaStringClose; |
| 496 | 535 | ||
| 497 | Parens = '(' >> *space_break >> space >> Exp >> *space_break >> space >> ')'; | 536 | Parens = '(' >> *space_break >> space >> Exp >> *space_break >> space >> ')'; |
| 498 | Callable = Variable | SelfItem | MacroName | VarArg | Parens; | 537 | Callable = Variable | SelfItem | MacroName | Parens; |
| 499 | fn_args_exp_list = space >> Exp >> space >> *((line_break | ',') >> white >> Exp); | 538 | fn_args_exp_list = space >> Exp >> space >> *((line_break | ',') >> white >> Exp); |
| 500 | 539 | ||
| 501 | fn_args = | 540 | fn_args = |
| @@ -507,7 +546,7 @@ YueParser::YueParser() { | |||
| 507 | Metamethod = '<' >> space >> meta_index >> space >> '>'; | 546 | Metamethod = '<' >> space >> meta_index >> space >> '>'; |
| 508 | 547 | ||
| 509 | ExistentialOp = '?' >> not_('?'); | 548 | ExistentialOp = '?' >> not_('?'); |
| 510 | TableAppendingOp = "[]"; | 549 | TableAppendingOp = and_('[') >> ("[]" | brackets_expression_error); |
| 511 | chain_call = ( | 550 | chain_call = ( |
| 512 | Callable >> -ExistentialOp >> -chain_items | 551 | Callable >> -ExistentialOp >> -chain_items |
| 513 | ) | ( | 552 | ) | ( |
| @@ -736,8 +775,13 @@ YueParser::YueParser() { | |||
| 736 | 775 | ||
| 737 | ConstValue = (expr("nil") | "true" | "false") >> not_alpha_num; | 776 | ConstValue = (expr("nil") | "true" | "false") >> not_alpha_num; |
| 738 | 777 | ||
| 739 | braces_expression_error = pl::user("{", [](const item_t& item) { | 778 | braces_expression_error = pl::user(true_(), [](const item_t& item) { |
| 740 | throw ParserError("invalid brace expression", *item.begin, *item.end); | 779 | throw ParserError("syntax error in brace expression", *item.begin, *item.end); |
| 780 | return false; | ||
| 781 | }); | ||
| 782 | |||
| 783 | brackets_expression_error = pl::user(true_(), [](const item_t& item) { | ||
| 784 | throw ParserError("syntax error in bracket expression", *item.begin, *item.end); | ||
| 741 | return false; | 785 | return false; |
| 742 | }); | 786 | }); |
| 743 | 787 | ||
| @@ -745,7 +789,7 @@ YueParser::YueParser() { | |||
| 745 | TableLit | ConstValue | If | Switch | Try | With | | 789 | TableLit | ConstValue | If | Switch | Try | With | |
| 746 | ClassDecl | ForEach | For | While | Do | | 790 | ClassDecl | ForEach | For | While | Do | |
| 747 | UnaryValue | TblComprehension | Comprehension | | 791 | UnaryValue | TblComprehension | Comprehension | |
| 748 | FunLit | Num; | 792 | FunLit | Num | VarArg; |
| 749 | 793 | ||
| 750 | ExpListAssign = ExpList >> -(space >> (Update | Assign)) >> not_(space >> '='); | 794 | ExpListAssign = ExpList >> -(space >> (Update | Assign)) >> not_(space >> '='); |
| 751 | 795 | ||
