aboutsummaryrefslogtreecommitdiff
path: root/src/yuescript/yue_parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/yuescript/yue_parser.cpp109
1 files changed, 62 insertions, 47 deletions
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp
index a7feb83..1b72a8c 100644
--- a/src/yuescript/yue_parser.cpp
+++ b/src/yuescript/yue_parser.cpp
@@ -113,7 +113,7 @@ YueParser::YueParser() {
113 }; 113 };
114 114
115 empty_block_error = expect_error( 115 empty_block_error = expect_error(
116 "must be followed by a statement or an indented block"sv 116 "expected a valid statement or indented block"sv
117 ); 117 );
118 export_expression_error = expect_error( 118 export_expression_error = expect_error(
119 "invalid export expression"sv 119 "invalid export expression"sv
@@ -170,7 +170,7 @@ YueParser::YueParser() {
170 "invalid import syntax, expected `import \"X.mod\" as modname` or `import \"X.mod\" as {:name}`"sv 170 "invalid import syntax, expected `import \"X.mod\" as modname` or `import \"X.mod\" as {:name}`"sv
171 ); 171 );
172 expected_expression_error = expect_error( 172 expected_expression_error = expect_error(
173 "expected expression"sv 173 "expected valid expression"sv
174 ); 174 );
175 invalid_from_import_error = expect_error( 175 invalid_from_import_error = expect_error(
176 "invalid import syntax, expected `from \"X.mod\" import name` or `from mod import name`"sv 176 "invalid import syntax, expected `from \"X.mod\" import name` or `from mod import name`"sv
@@ -202,6 +202,9 @@ YueParser::YueParser() {
202 invalid_import_literal_error = expect_error( 202 invalid_import_literal_error = expect_error(
203 "invalid import path literal, expected a dotted path like X.Y.Z"sv 203 "invalid import path literal, expected a dotted path like X.Y.Z"sv
204 ); 204 );
205 expected_indentifier_error = expect_error(
206 "expected valid identifer"sv
207 );
205 208
206 #define ensure(patt, finally) ((patt) >> (finally) | (finally) >> cut) 209 #define ensure(patt, finally) ((patt) >> (finally) | (finally) >> cut)
207 210
@@ -382,22 +385,24 @@ YueParser::YueParser() {
382 local_const_item = Variable | SimpleTable | TableLit | Comprehension; 385 local_const_item = Variable | SimpleTable | TableLit | Comprehension;
383 LocalAttrib = ( 386 LocalAttrib = (
384 ConstAttrib >> Seperator >> space >> local_const_item >> *(space >> ',' >> space >> local_const_item) | 387 ConstAttrib >> Seperator >> space >> local_const_item >> *(space >> ',' >> space >> local_const_item) |
385 CloseAttrib >> Seperator >> space >> Variable >> *(space >> ',' >> space >> Variable) 388 CloseAttrib >> Seperator >> space >> must_variable >> *(space >> ',' >> space >> must_variable)
386 ) >> space >> Assign; 389 ) >> space >> Assign;
387 390
388 ColonImportName = '\\' >> space >> Variable; 391 ColonImportName = '\\' >> must_variable;
389 import_name = ColonImportName | Variable; 392 import_name = not_(key("from")) >> (ColonImportName | must_variable);
390 import_name_list = Seperator >> *space_break >> space >> import_name >> *((+space_break | space >> ',' >> *space_break) >> space >> import_name); 393 import_name_list = Seperator >> *space_break >> space >> import_name >> *(
394 (+space_break | space >> ',' >> *space_break) >> space >> import_name
395 );
391 ImportFrom = import_name_list >> *space_break >> space >> key("from") >> space >> (ImportLiteral | not_(String) >> must_exp); 396 ImportFrom = import_name_list >> *space_break >> space >> key("from") >> space >> (ImportLiteral | not_(String) >> must_exp);
392 from_import_name_list_line = import_name >> *(space >> ',' >> space >> import_name); 397 from_import_name_list_line = import_name >> *(space >> ',' >> space >> not_(line_break) >> import_name);
393 from_import_name_in_block = +space_break >> advance_match >> ensure(space >> from_import_name_list_line >> *(-(space >> ',') >> +space_break >> check_indent_match >> space >> from_import_name_list_line), pop_indent); 398 from_import_name_in_block = +space_break >> advance_match >> ensure(space >> from_import_name_list_line >> *(-(space >> ',') >> +space_break >> check_indent_match >> space >> from_import_name_list_line), pop_indent);
394 FromImport = key("from") >> space >> ( 399 FromImport = key("from") >> space >> (
395 ImportLiteral | not_(String) >> Exp | invalid_from_import_error 400 ImportLiteral | not_(String) >> Exp | invalid_from_import_error
396 ) >> *space_break >> space >> ( 401 ) >> *space_break >> space >> (
397 key("import") | invalid_from_import_error 402 key("import") | invalid_from_import_error
398 ) >> space >> Seperator >> ( 403 ) >> space >> Seperator >> (
399 from_import_name_list_line >> -(space >> ',') >> -from_import_name_in_block |
400 from_import_name_in_block | 404 from_import_name_in_block |
405 from_import_name_list_line >> -(space >> ',') >> -from_import_name_in_block |
401 invalid_from_import_error 406 invalid_from_import_error
402 ); 407 );
403 408
@@ -432,16 +437,18 @@ YueParser::YueParser() {
432 -(space >> ',') >> 437 -(space >> ',') >>
433 -import_tab_lines >> 438 -import_tab_lines >>
434 white >> 439 white >>
435 '}' 440 end_braces_expression
436 ) | ( 441 ) | (
437 Seperator >> import_tab_key_value >> *(space >> ',' >> space >> import_tab_key_value) 442 Seperator >> import_tab_key_value >> *(space >> ',' >> space >> import_tab_key_value)
438 ); 443 );
439 444
440 ImportAs = ImportLiteral >> -(space >> key("as") >> space >> (ImportTabLit | Variable | ImportAllMacro | invalid_import_as_syntax_error)); 445 ImportAs = ImportLiteral >> -(space >> key("as") >> space >> (
446 ImportTabLit | Variable | ImportAllMacro | invalid_import_as_syntax_error
447 ));
441 448
442 ImportGlobal = Seperator >> UnicodeName >> *('.' >> UnicodeName) >> -(space >> key("as") >> space >> Variable); 449 ImportGlobal = Seperator >> UnicodeName >> *('.' >> UnicodeName) >> space >> not_(',' | key("from")) >> -(key("as") >> space >> must_variable);
443 450
444 Import = key("import") >> space >> (ImportAs | ImportFrom | ImportGlobal | invalid_import_syntax_error) | FromImport; 451 Import = key("import") >> space >> (ImportGlobal | ImportAs | ImportFrom | invalid_import_syntax_error) | FromImport;
445 452
446 Label = "::" >> (and_(LuaKeyword >> "::") >> keyword_as_label_error | UnicodeName >> "::"); 453 Label = "::" >> (and_(LuaKeyword >> "::") >> keyword_as_label_error | UnicodeName >> "::");
447 454
@@ -511,13 +518,15 @@ YueParser::YueParser() {
511 ForStepValue = ',' >> space >> must_exp; 518 ForStepValue = ',' >> space >> must_exp;
512 for_args = Variable >> space >> '=' >> space >> must_exp >> space >> ',' >> space >> must_exp >> space >> -ForStepValue; 519 for_args = Variable >> space >> '=' >> space >> must_exp >> space >> ',' >> space >> must_exp >> space >> -ForStepValue;
513 520
514 For = for_key >> space >> disable_do_chain_arg_table_block_rule(for_args) >> space >> opt_body_with("do"); 521 ForNum = disable_do_chain_arg_table_block_rule(for_args) >> space >> opt_body_with("do");
515 522
516 for_in = StarExp | ExpList | expected_expression_error; 523 for_in = StarExp | ExpList | expected_expression_error;
517 524
518 ForEach = for_key >> space >> AssignableNameList >> space >> key("in") >> space >> 525 ForEach = AssignableNameList >> space >> key("in") >> space >>
519 disable_do_chain_arg_table_block_rule(for_in) >> space >> opt_body_with("do"); 526 disable_do_chain_arg_table_block_rule(for_in) >> space >> opt_body_with("do");
520 527
528 For = for_key >> space >> (ForNum | ForEach);
529
521 Do = pl::user(key("do"), [](const item_t& item) { 530 Do = pl::user(key("do"), [](const item_t& item) {
522 State* st = reinterpret_cast<State*>(item.user_data); 531 State* st = reinterpret_cast<State*>(item.user_data);
523 return st->noDoStack.empty() || !st->noDoStack.back(); 532 return st->noDoStack.empty() || !st->noDoStack.back();
@@ -599,7 +608,7 @@ YueParser::YueParser() {
599 return true; 608 return true;
600 }); 609 });
601 610
602 CatchBlock = line_break >> *space_break >> check_indent_match >> space >> key("catch") >> space >> (Variable >> space >> in_block | invalid_try_syntax_error); 611 CatchBlock = line_break >> *space_break >> check_indent_match >> space >> key("catch") >> space >> must_variable >> space >> (in_block | invalid_try_syntax_error);
603 Try = key("try") >> -ExistentialOp >> space >> (in_block | Exp | invalid_try_syntax_error) >> -CatchBlock; 612 Try = key("try") >> -ExistentialOp >> space >> (in_block | Exp | invalid_try_syntax_error) >> -CatchBlock;
604 613
605 list_value = 614 list_value =
@@ -622,24 +631,28 @@ YueParser::YueParser() {
622 631
623 list_lit_lines = +space_break >> list_lit_line >> *(-(space >> ',') >> space_break >> list_lit_line) >> -(space >> ','); 632 list_lit_lines = +space_break >> list_lit_line >> *(-(space >> ',') >> space_break >> list_lit_line) >> -(space >> ',');
624 633
634 end_brackets_expression = ']' | brackets_expression_error;
635
625 Comprehension = '[' >> not_('[') >> 636 Comprehension = '[' >> not_('[') >>
626 Seperator >> space >> ( 637 Seperator >> space >> (
627 disable_for_rule(list_value) >> space >> ( 638 disable_for_rule(list_value) >> space >> (
628 CompInner >> space >> ']' | 639 CompFor >> space >> end_brackets_expression |
629 (list_value_list >> -(space >> ',') | space >> ',') >> -list_lit_lines >> white >> ']' 640 (list_value_list >> -(space >> ',') | space >> ',') >> -list_lit_lines >> white >> end_brackets_expression
630 ) | 641 ) |
631 list_lit_lines >> white >> ']' | 642 list_lit_lines >> white >> end_brackets_expression |
632 white >> ']' >> not_(space >> '=') 643 white >> ']' >> not_(space >> '=')
633 ); 644 );
634 645
635 CompValue = ',' >> space >> Exp; 646 end_braces_expression = '}' | braces_expression_error;
636 TblComprehension = and_('{') >> ('{' >> space >> disable_for_rule(Exp >> space >> -(CompValue >> space)) >> CompInner >> space >> '}' | braces_expression_error);
637 647
638 CompInner = Seperator >> (CompForEach | CompFor) >> *(space >> comp_clause); 648 CompValue = ',' >> space >> must_exp;
649 TblComprehension = '{' >> space >> disable_for_rule(Exp >> space >> -(CompValue >> space)) >> (CompFor | braces_expression_error) >> space >> end_braces_expression;
650
651 CompFor = key("for") >> space >> Seperator >> (CompForNum | CompForEach) >> *(space >> comp_clause);
639 StarExp = '*' >> space >> must_exp; 652 StarExp = '*' >> space >> must_exp;
640 CompForEach = key("for") >> space >> AssignableNameList >> space >> key("in") >> space >> (StarExp | must_exp); 653 CompForEach = AssignableNameList >> space >> key("in") >> space >> (StarExp | must_exp);
641 CompFor = key("for") >> space >> Variable >> space >> '=' >> space >> must_exp >> space >> ',' >> space >> must_exp >> -ForStepValue; 654 CompForNum = Variable >> space >> '=' >> space >> must_exp >> space >> ',' >> space >> must_exp >> -ForStepValue;
642 comp_clause = CompFor | CompForEach | key("when") >> space >> must_exp; 655 comp_clause = key("when") >> space >> must_exp | key("for") >> space >> (CompForNum | CompForEach);
643 656
644 Assign = '=' >> space >> Seperator >> ( 657 Assign = '=' >> space >> Seperator >> (
645 With | If | Switch | TableBlock | 658 With | If | Switch | TableBlock |
@@ -794,7 +807,7 @@ YueParser::YueParser() {
794 Metamethod = '<' >> space >> meta_index >> space >> '>'; 807 Metamethod = '<' >> space >> meta_index >> space >> '>';
795 808
796 ExistentialOp = '?' >> not_('?'); 809 ExistentialOp = '?' >> not_('?');
797 TableAppendingOp = and_('[') >> ("[]" | brackets_expression_error); 810 TableAppendingOp = and_('[') >> "[]";
798 PlainItem = +any_char; 811 PlainItem = +any_char;
799 812
800 chain_call = ( 813 chain_call = (
@@ -819,7 +832,7 @@ YueParser::YueParser() {
819 chain_with_colon = +chain_item >> -colon_chain; 832 chain_with_colon = +chain_item >> -colon_chain;
820 chain_items = chain_with_colon | colon_chain; 833 chain_items = chain_with_colon | colon_chain;
821 834
822 index = '[' >> not_('[') >> space >> (ReversedIndex >> and_(space >> ']') | Exp) >> space >> (']' | brackets_expression_error); 835 index = '[' >> not_('[') >> space >> (ReversedIndex >> and_(space >> ']') | Exp) >> space >> ']';
823 ReversedIndex = '#' >> space >> -('-' >> space >> Exp); 836 ReversedIndex = '#' >> space >> -('-' >> space >> Exp);
824 chain_item = 837 chain_item =
825 Invoke >> -ExistentialOp | 838 Invoke >> -ExistentialOp |
@@ -859,10 +872,8 @@ YueParser::YueParser() {
859 SpreadExp | 872 SpreadExp |
860 NormalDef; 873 NormalDef;
861 874
862 table_value_list = table_value >> *(space >> ',' >> space >> table_value);
863
864 table_lit_line = ( 875 table_lit_line = (
865 push_indent_match >> (space >> table_value_list >> pop_indent | pop_indent) 876 push_indent_match >> (space >> not_(line_break | '}') >> (table_value | expected_expression_error) >> *(space >> ',' >> space >> table_value) >> pop_indent | pop_indent)
866 ) | ( 877 ) | (
867 space 878 space
868 ); 879 );
@@ -871,9 +882,11 @@ YueParser::YueParser() {
871 882
872 TableLit = 883 TableLit =
873 '{' >> Seperator >> 884 '{' >> Seperator >>
874 -(space >> table_value_list >> -(space >> ',')) >> 885 -(space >> table_value >> *(space >> ',' >> space >> table_value) >> -(space >> ',')) >>
875 -table_lit_lines >> 886 (
876 white >> '}'; 887 table_lit_lines >> white >> end_braces_expression |
888 white >> '}'
889 );
877 890
878 table_block_inner = Seperator >> key_value_line >> *(+space_break >> key_value_line); 891 table_block_inner = Seperator >> key_value_line >> *(+space_break >> key_value_line);
879 TableBlock = +space_break >> advance_match >> ensure(table_block_inner, pop_indent); 892 TableBlock = +space_break >> advance_match >> ensure(table_block_inner, pop_indent);
@@ -955,22 +968,20 @@ YueParser::YueParser() {
955 invalid_export_syntax_error 968 invalid_export_syntax_error
956 ) >> not_(space >> StatementAppendix); 969 ) >> not_(space >> StatementAppendix);
957 970
958 check_keyword_as_identifier = and_(LuaKeyword >> not_alpha_num) >> keyword_as_identifier_syntax_error; 971 VariablePair = ':' >> Variable;
959
960 VariablePair = ':' >> (Variable | check_keyword_as_identifier);
961 972
962 NormalPair = 973 NormalPair =
963 ( 974 (
964 KeyName | 975 KeyName |
965 '[' >> not_('[') >> space >> Exp >> space >> ']' | 976 '[' >> not_('[') >> space >> Exp >> space >> ']' |
966 String 977 String
967 ) >> ':' >> not_(':') >> space >> 978 ) >> ':' >> not_(':' | '=' >> not_('>')) >> space >>
968 (Exp | TableBlock | +space_break >> space >> Exp | check_keyword_as_identifier); 979 (Exp | TableBlock | +space_break >> space >> Exp | expected_expression_error);
969 980
970 MetaVariablePair = ":<" >> space >> Variable >> space >> '>'; 981 MetaVariablePair = ":<" >> space >> must_variable >> space >> '>';
971 982
972 MetaNormalPair = '<' >> space >> -meta_index >> space >> ">:" >> space >> 983 MetaNormalPair = '<' >> space >> -meta_index >> space >> ">:" >> space >>
973 (Exp | TableBlock | +space_break >> space >> Exp | check_keyword_as_identifier); 984 (Exp | TableBlock | +space_break >> space >> Exp | expected_expression_error);
974 985
975 destruct_def = -(space >> '=' >> space >> Exp); 986 destruct_def = -(space >> '=' >> space >> Exp);
976 VariablePairDef = VariablePair >> destruct_def; 987 VariablePairDef = VariablePair >> destruct_def;
@@ -1010,7 +1021,7 @@ YueParser::YueParser() {
1010 white >> VarArg >> -(space >> '`' >> space >> Name) >> check_vararg_position 1021 white >> VarArg >> -(space >> '`' >> space >> Name) >> check_vararg_position
1011 ); 1022 );
1012 1023
1013 OuterVarShadow = key("using") >> space >> (NameList | key("nil")); 1024 OuterVarShadow = key("using") >> space >> (key("nil") | NameList);
1014 1025
1015 FnArgsDef = '(' >> *space_break >> -FnArgDefList >> -(white >> OuterVarShadow) >> white >> -(and_(',') >> unexpected_comma_error) >> ')'; 1026 FnArgsDef = '(' >> *space_break >> -FnArgDefList >> -(white >> OuterVarShadow) >> white >> -(and_(',') >> unexpected_comma_error) >> ')';
1016 FnArrow = expr("->") | "=>"; 1027 FnArrow = expr("->") | "=>";
@@ -1028,13 +1039,15 @@ YueParser::YueParser() {
1028 MacroLit = -(macro_args_def >> space) >> "->" >> space >> Body; 1039 MacroLit = -(macro_args_def >> space) >> "->" >> space >> Body;
1029 MacroFunc = MacroName >> (Invoke | InvokeArgs); 1040 MacroFunc = MacroName >> (Invoke | InvokeArgs);
1030 Macro = key("macro") >> space >> ( 1041 Macro = key("macro") >> space >> (
1031 UnicodeName >> space >> '=' >> space >> (MacroLit | MacroFunc) | 1042 UnicodeName >> space >> '=' >> space >> (MacroLit | MacroFunc | expected_expression_error) |
1032 invalid_macro_definition_error 1043 invalid_macro_definition_error
1033 ); 1044 );
1034 MacroInPlace = '$' >> space >> "->" >> space >> Body; 1045 MacroInPlace = '$' >> space >> "->" >> space >> Body;
1035 1046
1036 NameList = Seperator >> Variable >> *(space >> ',' >> space >> Variable); 1047 must_variable = Variable | and_(LuaKeyword >> not_alpha_num) >> keyword_as_identifier_syntax_error | expected_indentifier_error;
1037 NameOrDestructure = Variable | TableLit | Comprehension | SimpleTable; 1048
1049 NameList = Seperator >> must_variable >> *(space >> ',' >> space >> must_variable);
1050 NameOrDestructure = Variable | TableLit | Comprehension | SimpleTable | expected_expression_error;
1038 AssignableNameList = Seperator >> NameOrDestructure >> *(space >> ',' >> space >> NameOrDestructure); 1051 AssignableNameList = Seperator >> NameOrDestructure >> *(space >> ',' >> space >> NameOrDestructure);
1039 1052
1040 FnArrowBack = '<' >> set("-="); 1053 FnArrowBack = '<' >> set("-=");
@@ -1074,7 +1087,7 @@ YueParser::YueParser() {
1074 1087
1075 SimpleValue = 1088 SimpleValue =
1076 TableLit | ConstValue | If | Switch | Try | With | 1089 TableLit | ConstValue | If | Switch | Try | With |
1077 ClassDecl | ForEach | For | While | Repeat | Do | 1090 ClassDecl | For | While | Repeat | Do |
1078 UnaryValue | TblComprehension | Comprehension | 1091 UnaryValue | TblComprehension | Comprehension |
1079 FunLit | Num | VarArg; 1092 FunLit | Num | VarArg;
1080 1093
@@ -1085,10 +1098,10 @@ YueParser::YueParser() {
1085 1098
1086 ChainAssign = Seperator >> Exp >> +(space >> '=' >> space >> Exp >> space >> and_('=')) >> space >> Assign; 1099 ChainAssign = Seperator >> Exp >> +(space >> '=' >> space >> Exp >> space >> and_('=')) >> space >> Assign;
1087 1100
1088 StatementAppendix = (IfLine | WhileLine | CompInner) >> space; 1101 StatementAppendix = (IfLine | WhileLine | CompFor) >> space;
1089 Statement = 1102 Statement =
1090 ( 1103 (
1091 Import | While | Repeat | For | ForEach | 1104 Import | While | Repeat | For |
1092 Return | Local | Global | Export | Macro | 1105 Return | Local | Global | Export | Macro |
1093 MacroInPlace | BreakLoop | Label | Goto | ShortTabAppending | 1106 MacroInPlace | BreakLoop | Label | Goto | ShortTabAppending |
1094 LocalAttrib | Backcall | PipeBody | ExpListAssign | ChainAssign | 1107 LocalAttrib | Backcall | PipeBody | ExpListAssign | ChainAssign |
@@ -1133,7 +1146,9 @@ YueParser::YueParser() {
1133 BlockEnd = Block >> plain_white >> stop; 1146 BlockEnd = Block >> plain_white >> stop;
1134 File = -shebang >> -Block >> plain_white >> stop; 1147 File = -shebang >> -Block >> plain_white >> stop;
1135 1148
1136 lax_line = advance_match >> ensure(*(not_(stop) >> any()), pop_indent) | line >> and_(stop) | check_indent_match >> *(not_(stop) >> any()); 1149 lax_line = advance_match >> ensure(*(not_(stop) >> any()), pop_indent) |
1150 line >> and_(stop) |
1151 check_indent_match >> *(not_(stop) >> any());
1137} 1152}
1138// clang-format on 1153// clang-format on
1139 1154