diff options
| -rw-r--r-- | src/yuescript/yue_ast.cpp | 3 | ||||
| -rw-r--r-- | src/yuescript/yue_ast.h | 9 | ||||
| -rw-r--r-- | src/yuescript/yue_compiler.cpp | 8 | ||||
| -rw-r--r-- | src/yuescript/yue_parser.cpp | 350 | ||||
| -rw-r--r-- | src/yuescript/yue_parser.h | 28 | ||||
| -rw-r--r-- | src/yuescript/yuescript.cpp | 2 |
6 files changed, 247 insertions, 153 deletions
diff --git a/src/yuescript/yue_ast.cpp b/src/yuescript/yue_ast.cpp index b225acc..278d992 100644 --- a/src/yuescript/yue_ast.cpp +++ b/src/yuescript/yue_ast.cpp | |||
| @@ -210,9 +210,6 @@ std::string MultilineCommentInner_t::to_string(void* ud) const { | |||
| 210 | std::string Variable_t::to_string(void* ud) const { | 210 | std::string Variable_t::to_string(void* ud) const { |
| 211 | return name->to_string(ud); | 211 | return name->to_string(ud); |
| 212 | } | 212 | } |
| 213 | std::string LabelName_t::to_string(void* ud) const { | ||
| 214 | return name->to_string(ud); | ||
| 215 | } | ||
| 216 | std::string LuaKeyword_t::to_string(void* ud) const { | 213 | std::string LuaKeyword_t::to_string(void* ud) const { |
| 217 | return name->to_string(ud); | 214 | return name->to_string(ud); |
| 218 | } | 215 | } |
diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h index 5f04fa0..3aca702 100644 --- a/src/yuescript/yue_ast.h +++ b/src/yuescript/yue_ast.h | |||
| @@ -103,11 +103,6 @@ AST_NODE(Variable) | |||
| 103 | AST_MEMBER(Variable, &name) | 103 | AST_MEMBER(Variable, &name) |
| 104 | AST_END(Variable) | 104 | AST_END(Variable) |
| 105 | 105 | ||
| 106 | AST_NODE(LabelName) | ||
| 107 | ast_ptr<true, UnicodeName_t> name; | ||
| 108 | AST_MEMBER(LabelName, &name) | ||
| 109 | AST_END(LabelName) | ||
| 110 | |||
| 111 | AST_NODE(LuaKeyword) | 106 | AST_NODE(LuaKeyword) |
| 112 | ast_ptr<true, Name_t> name; | 107 | ast_ptr<true, Name_t> name; |
| 113 | AST_MEMBER(LuaKeyword, &name) | 108 | AST_MEMBER(LuaKeyword, &name) |
| @@ -246,12 +241,12 @@ AST_NODE(Import) | |||
| 246 | AST_END(Import) | 241 | AST_END(Import) |
| 247 | 242 | ||
| 248 | AST_NODE(Label) | 243 | AST_NODE(Label) |
| 249 | ast_ptr<true, LabelName_t> label; | 244 | ast_ptr<true, UnicodeName_t> label; |
| 250 | AST_MEMBER(Label, &label) | 245 | AST_MEMBER(Label, &label) |
| 251 | AST_END(Label) | 246 | AST_END(Label) |
| 252 | 247 | ||
| 253 | AST_NODE(Goto) | 248 | AST_NODE(Goto) |
| 254 | ast_ptr<true, LabelName_t> label; | 249 | ast_ptr<true, UnicodeName_t> label; |
| 255 | AST_MEMBER(Goto, &label) | 250 | AST_MEMBER(Goto, &label) |
| 256 | AST_END(Goto) | 251 | AST_END(Goto) |
| 257 | 252 | ||
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index 55ab4ec..84b990f 100644 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp | |||
| @@ -78,7 +78,7 @@ static std::unordered_set<std::string> Metamethods = { | |||
| 78 | "close"s // Lua 5.4 | 78 | "close"s // Lua 5.4 |
| 79 | }; | 79 | }; |
| 80 | 80 | ||
| 81 | const std::string_view version = "0.29.9"sv; | 81 | const std::string_view version = "0.30.0"sv; |
| 82 | const std::string_view extension = "yue"sv; | 82 | const std::string_view extension = "yue"sv; |
| 83 | 83 | ||
| 84 | class CompileError : public std::logic_error { | 84 | class CompileError : public std::logic_error { |
| @@ -9207,7 +9207,7 @@ private: | |||
| 9207 | } | 9207 | } |
| 9208 | if (_config.lintGlobalVariable && !isLocal(name)) { | 9208 | if (_config.lintGlobalVariable && !isLocal(name)) { |
| 9209 | auto key = name + ':' + std::to_string(pair->name->m_begin.m_line) + ':' + std::to_string(pair->name->m_begin.m_col); | 9209 | auto key = name + ':' + std::to_string(pair->name->m_begin.m_line) + ':' + std::to_string(pair->name->m_begin.m_col); |
| 9210 | if (_globals.find(key) != _globals.end()) { | 9210 | if (_globals.find(key) == _globals.end()) { |
| 9211 | _globals[key] = {name, pair->name->m_begin.m_line, pair->name->m_begin.m_col, _funcLevel > 1 ? AccessType::Capture : AccessType::Read, isSolidDefined(name)}; | 9211 | _globals[key] = {name, pair->name->m_begin.m_line, pair->name->m_begin.m_col, _funcLevel > 1 ? AccessType::Capture : AccessType::Read, isSolidDefined(name)}; |
| 9212 | } | 9212 | } |
| 9213 | } | 9213 | } |
| @@ -12054,7 +12054,7 @@ private: | |||
| 12054 | if (getLuaTarget(label) < 502) { | 12054 | if (getLuaTarget(label) < 502) { |
| 12055 | throw CompileError("label statement is not available when not targeting Lua version 5.2 or higher"sv, label); | 12055 | throw CompileError("label statement is not available when not targeting Lua version 5.2 or higher"sv, label); |
| 12056 | } | 12056 | } |
| 12057 | auto labelStr = unicodeVariableFrom(label->label->name); | 12057 | auto labelStr = unicodeVariableFrom(label->label); |
| 12058 | int currentScope = _gotoScopes.top(); | 12058 | int currentScope = _gotoScopes.top(); |
| 12059 | if (static_cast<int>(_labels.size()) <= currentScope) { | 12059 | if (static_cast<int>(_labels.size()) <= currentScope) { |
| 12060 | _labels.resize(currentScope + 1, std::nullopt); | 12060 | _labels.resize(currentScope + 1, std::nullopt); |
| @@ -12075,7 +12075,7 @@ private: | |||
| 12075 | if (getLuaTarget(gotoNode) < 502) { | 12075 | if (getLuaTarget(gotoNode) < 502) { |
| 12076 | throw CompileError("goto statement is not available when not targeting Lua version 5.2 or higher"sv, gotoNode); | 12076 | throw CompileError("goto statement is not available when not targeting Lua version 5.2 or higher"sv, gotoNode); |
| 12077 | } | 12077 | } |
| 12078 | auto labelStr = unicodeVariableFrom(gotoNode->label->name); | 12078 | auto labelStr = unicodeVariableFrom(gotoNode->label); |
| 12079 | gotos.push_back({gotoNode, labelStr, _gotoScopes.top(), static_cast<int>(_scopes.size())}); | 12079 | gotos.push_back({gotoNode, labelStr, _gotoScopes.top(), static_cast<int>(_scopes.size())}); |
| 12080 | out.push_back(indent() + "goto "s + labelStr + nll(gotoNode)); | 12080 | out.push_back(indent() + "goto "s + labelStr + nll(gotoNode)); |
| 12081 | } | 12081 | } |
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index cbba115..5a54690 100644 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp | |||
| @@ -41,6 +41,15 @@ public: | |||
| 41 | int col; | 41 | int col; |
| 42 | }; | 42 | }; |
| 43 | 43 | ||
| 44 | #define RaiseError(msg, item) \ | ||
| 45 | do { \ | ||
| 46 | if (reinterpret_cast<State*>(item.user_data)->lax) { \ | ||
| 47 | return false; \ | ||
| 48 | } else { \ | ||
| 49 | throw ParserError(msg, item.begin); \ | ||
| 50 | } \ | ||
| 51 | } while (false) | ||
| 52 | |||
| 44 | // clang-format off | 53 | // clang-format off |
| 45 | YueParser::YueParser() { | 54 | YueParser::YueParser() { |
| 46 | plain_space = *set(" \t"); | 55 | plain_space = *set(" \t"); |
| @@ -61,14 +70,15 @@ YueParser::YueParser() { | |||
| 61 | not_alpha_num = not_(alpha_num); | 70 | not_alpha_num = not_(alpha_num); |
| 62 | Name = (range('a', 'z') | range('A', 'Z') | '_') >> *alpha_num >> not_(larger(255)); | 71 | Name = (range('a', 'z') | range('A', 'Z') | '_') >> *alpha_num >> not_(larger(255)); |
| 63 | UnicodeName = (range('a', 'z') | range('A', 'Z') | '_' | larger(255)) >> *(larger(255) | alpha_num); | 72 | UnicodeName = (range('a', 'z') | range('A', 'Z') | '_' | larger(255)) >> *(larger(255) | alpha_num); |
| 64 | num_expo = set("eE") >> -set("+-") >> num_char; | 73 | must_num_char = num_char | invalid_number_literal_error; |
| 65 | num_expo_hex = set("pP") >> -set("+-") >> num_char; | 74 | num_expo = set("eE") >> -set("+-") >> must_num_char; |
| 75 | num_expo_hex = set("pP") >> -set("+-") >> must_num_char; | ||
| 66 | lj_num = -set("uU") >> set("lL") >> set("lL"); | 76 | lj_num = -set("uU") >> set("lL") >> set("lL"); |
| 67 | num_char = range('0', '9') >> *(range('0', '9') | '_' >> and_(range('0', '9'))); | 77 | num_char = range('0', '9') >> *(range('0', '9') | '_' >> and_(range('0', '9'))); |
| 68 | num_char_hex = range('0', '9') | range('a', 'f') | range('A', 'F'); | 78 | num_char_hex = range('0', '9') | range('a', 'f') | range('A', 'F'); |
| 69 | num_lit = num_char_hex >> *(num_char_hex | '_' >> and_(num_char_hex)); | 79 | num_lit = num_char_hex >> *(num_char_hex | '_' >> and_(num_char_hex)); |
| 70 | num_bin_lit = set("01") >> *(set("01") | '_' >> and_(set("01"))); | 80 | num_bin_lit = set("01") >> *(set("01") | '_' >> and_(set("01"))); |
| 71 | Num = | 81 | Num = ( |
| 72 | '0' >> ( | 82 | '0' >> ( |
| 73 | set("xX") >> ( | 83 | set("xX") >> ( |
| 74 | num_lit >> ( | 84 | num_lit >> ( |
| @@ -78,50 +88,119 @@ YueParser::YueParser() { | |||
| 78 | true_() | 88 | true_() |
| 79 | ) | ( | 89 | ) | ( |
| 80 | '.' >> num_lit >> -num_expo_hex | 90 | '.' >> num_lit >> -num_expo_hex |
| 81 | ) | 91 | ) | invalid_number_literal_error |
| 82 | ) | | 92 | ) | |
| 83 | set("bB") >> num_bin_lit | 93 | set("bB") >> (num_bin_lit | invalid_number_literal_error) |
| 84 | ) | | 94 | ) | |
| 85 | num_char >> ( | 95 | num_char >> ( |
| 86 | '.' >> num_char >> -num_expo | | 96 | '.' >> must_num_char >> -num_expo | |
| 87 | num_expo | | 97 | num_expo | |
| 88 | lj_num | | 98 | lj_num | |
| 89 | true_() | 99 | true_() |
| 90 | ) | | 100 | ) |
| 91 | '.' >> num_char >> -num_expo; | 101 | ) >> -(and_(alpha_num) >> invalid_number_literal_error) | |
| 102 | '.' >> num_char >> -num_expo >> -(and_(alpha_num) >> invalid_number_literal_error); | ||
| 92 | 103 | ||
| 93 | cut = false_(); | 104 | cut = false_(); |
| 94 | Seperator = true_(); | 105 | Seperator = true_(); |
| 95 | 106 | ||
| 96 | empty_block_error = pl::user(true_(), [](const item_t& item) { | 107 | auto expect_error = [](std::string_view msg) { |
| 97 | throw ParserError("must be followed by a statement or an indented block"sv, item.begin); | 108 | return pl::user(true_(), [msg](const item_t& item) { |
| 98 | return false; | 109 | RaiseError(msg, item); |
| 99 | }); | 110 | return false; |
| 100 | 111 | }); | |
| 101 | export_expression_error = pl::user(true_(), [](const item_t& item) { | 112 | }; |
| 102 | throw ParserError("invalid export expression"sv, item.begin); | ||
| 103 | return false; | ||
| 104 | }); | ||
| 105 | |||
| 106 | invalid_interpolation_error = pl::user(true_(), [](const item_t& item) { | ||
| 107 | throw ParserError("invalid string interpolation"sv, item.begin); | ||
| 108 | return false; | ||
| 109 | }); | ||
| 110 | |||
| 111 | confusing_unary_not_error = pl::user(true_(), [](const item_t& item) { | ||
| 112 | throw ParserError("deprecated use for unary operator 'not' to be here"sv, item.begin); | ||
| 113 | return false; | ||
| 114 | }); | ||
| 115 | |||
| 116 | table_key_pair_error = pl::user(true_(), [](const item_t& item) { | ||
| 117 | throw ParserError("can not put hash pair in a list"sv, item.begin); | ||
| 118 | return false; | ||
| 119 | }); | ||
| 120 | 113 | ||
| 121 | assignment_expression_syntax_error = pl::user(true_(), [](const item_t& item) { | 114 | empty_block_error = expect_error( |
| 122 | throw ParserError("use := for assignment expression"sv, item.begin); | 115 | "must be followed by a statement or an indented block"sv |
| 123 | return false; | 116 | ); |
| 124 | }); | 117 | export_expression_error = expect_error( |
| 118 | "invalid export expression"sv | ||
| 119 | ); | ||
| 120 | invalid_interpolation_error = expect_error( | ||
| 121 | "invalid string interpolation"sv | ||
| 122 | ); | ||
| 123 | confusing_unary_not_error = expect_error( | ||
| 124 | "deprecated use for unary operator 'not' to be here"sv | ||
| 125 | ); | ||
| 126 | table_key_pair_error = expect_error( | ||
| 127 | "can not put hash pair in a list"sv | ||
| 128 | ); | ||
| 129 | assignment_expression_syntax_error = expect_error( | ||
| 130 | "use := for assignment expression"sv | ||
| 131 | ); | ||
| 132 | braces_expression_error = expect_error( | ||
| 133 | "syntax error in brace expression"sv | ||
| 134 | ); | ||
| 135 | brackets_expression_error = expect_error( | ||
| 136 | "unclosed bracket expression"sv | ||
| 137 | ); | ||
| 138 | slice_expression_error = expect_error( | ||
| 139 | "syntax error in slice expression"sv | ||
| 140 | ); | ||
| 141 | unclosed_single_string_error = expect_error( | ||
| 142 | "unclosed single-quoted string"sv | ||
| 143 | ); | ||
| 144 | unclosed_double_string_error = expect_error( | ||
| 145 | "unclosed double-quoted string"sv | ||
| 146 | ); | ||
| 147 | unclosed_lua_string_error = expect_error( | ||
| 148 | "unclosed Lua string"sv | ||
| 149 | ); | ||
| 150 | unexpected_comma_error = expect_error( | ||
| 151 | "got unexpected comma"sv | ||
| 152 | ); | ||
| 153 | parenthesis_error = expect_error( | ||
| 154 | "expected only one expression in parenthesis"sv | ||
| 155 | ); | ||
| 156 | dangling_clause_error = expect_error( | ||
| 157 | "dangling control clause"sv | ||
| 158 | ); | ||
| 159 | keyword_as_label_error = expect_error( | ||
| 160 | "keyword cannot be used as a label name"sv | ||
| 161 | ); | ||
| 162 | vararg_position_error = expect_error( | ||
| 163 | "vararg '...' must be the last parameter in function argument list"sv | ||
| 164 | ); | ||
| 165 | invalid_import_syntax_error = expect_error( | ||
| 166 | "invalid import syntax, expected `import \"X.mod\"`, `import \"X.mod\" as {:name}`, `from mod import name` or `import mod.name`"sv | ||
| 167 | ); | ||
| 168 | invalid_import_as_syntax_error = expect_error( | ||
| 169 | "invalid import syntax, expected `import \"X.mod\" as modname` or `import \"X.mod\" as {:name}`"sv | ||
| 170 | ); | ||
| 171 | expected_expression_error = expect_error( | ||
| 172 | "expected expression"sv | ||
| 173 | ); | ||
| 174 | invalid_from_import_error = expect_error( | ||
| 175 | "invalid import syntax, expected `from \"X.mod\" import name` or `from mod import name`"sv | ||
| 176 | ); | ||
| 177 | invalid_export_syntax_error = expect_error( | ||
| 178 | "invalid export syntax, expected `export item`, `export item = x`, `export.item = x` or `export default item`"sv | ||
| 179 | ); | ||
| 180 | invalid_macro_definition_error = expect_error( | ||
| 181 | "invalid macro definition, expected `macro Name = -> body` or `macro Name = $Name(...)`"sv | ||
| 182 | ); | ||
| 183 | invalid_global_declaration_error = expect_error( | ||
| 184 | "invalid global declaration, expected `global name`, `global name = ...`, `global *`, `global ^` or `global class ...`"sv | ||
| 185 | ); | ||
| 186 | invalid_local_declaration_error = expect_error( | ||
| 187 | "invalid local declaration, expected `local name`, `local name = ...`, `local *` or `local ^`"sv | ||
| 188 | ); | ||
| 189 | invalid_with_syntax_error = expect_error( | ||
| 190 | "invalid 'with' statement"sv | ||
| 191 | ); | ||
| 192 | invalid_try_syntax_error = expect_error( | ||
| 193 | "invalid 'try' expression, expected `try expr` or `try block` optionally followed by `catch err` with a handling block"sv | ||
| 194 | ); | ||
| 195 | keyword_as_identifier_syntax_error = expect_error( | ||
| 196 | "can not use keyword as identifier"sv | ||
| 197 | ); | ||
| 198 | invalid_number_literal_error = expect_error( | ||
| 199 | "invalid numeric literal"sv | ||
| 200 | ); | ||
| 201 | invalid_import_literal_error = expect_error( | ||
| 202 | "invalid import path literal, expected a dotted path like X.Y.Z"sv | ||
| 203 | ); | ||
| 125 | 204 | ||
| 126 | #define ensure(patt, finally) ((patt) >> (finally) | (finally) >> cut) | 205 | #define ensure(patt, finally) ((patt) >> (finally) | (finally) >> cut) |
| 127 | 206 | ||
| @@ -201,20 +280,6 @@ YueParser::YueParser() { | |||
| 201 | return isValid; | 280 | return isValid; |
| 202 | }); | 281 | }); |
| 203 | 282 | ||
| 204 | LabelName = pl::user(UnicodeName, [](const item_t& item) { | ||
| 205 | State* st = reinterpret_cast<State*>(item.user_data); | ||
| 206 | for (auto it = item.begin->m_it; it != item.end->m_it; ++it) { | ||
| 207 | if (*it > 255) { | ||
| 208 | st->buffer.clear(); | ||
| 209 | return true; | ||
| 210 | } | ||
| 211 | st->buffer += static_cast<char>(*it); | ||
| 212 | } | ||
| 213 | auto isValid = LuaKeywords.find(st->buffer) == LuaKeywords.end(); | ||
| 214 | st->buffer.clear(); | ||
| 215 | return isValid; | ||
| 216 | }); | ||
| 217 | |||
| 218 | LuaKeyword = pl::user(Name, [](const item_t& item) { | 283 | LuaKeyword = pl::user(Name, [](const item_t& item) { |
| 219 | State* st = reinterpret_cast<State*>(item.user_data); | 284 | State* st = reinterpret_cast<State*>(item.user_data); |
| 220 | for (auto it = item.begin->m_it; it != item.end->m_it; ++it) st->buffer += static_cast<char>(*it); | 285 | for (auto it = item.begin->m_it; it != item.end->m_it; ++it) st->buffer += static_cast<char>(*it); |
| @@ -247,14 +312,14 @@ YueParser::YueParser() { | |||
| 247 | for (input_it i = item.begin->m_it; i != item.end->m_it; ++i) { | 312 | for (input_it i = item.begin->m_it; i != item.end->m_it; ++i) { |
| 248 | switch (*i) { | 313 | switch (*i) { |
| 249 | case '\t': indent += 4; break; | 314 | case '\t': indent += 4; break; |
| 250 | default: throw ParserError("can not mix the use of tabs and spaces as indents"sv, item.begin); break; | 315 | default: RaiseError("can not mix the use of tabs and spaces as indents"sv, item); break; |
| 251 | } | 316 | } |
| 252 | } | 317 | } |
| 253 | } else { | 318 | } else { |
| 254 | for (input_it i = item.begin->m_it; i != item.end->m_it; ++i) { | 319 | for (input_it i = item.begin->m_it; i != item.end->m_it; ++i) { |
| 255 | switch (*i) { | 320 | switch (*i) { |
| 256 | case ' ': indent++; break; | 321 | case ' ': indent++; break; |
| 257 | default: throw ParserError("can not mix the use of tabs and spaces as indents"sv, item.begin); break; | 322 | default: RaiseError("can not mix the use of tabs and spaces as indents"sv, item); break; |
| 258 | } | 323 | } |
| 259 | } | 324 | } |
| 260 | } | 325 | } |
| @@ -308,8 +373,8 @@ YueParser::YueParser() { | |||
| 308 | in_block = space_break >> *(*set(" \t") >> line_break) >> advance_match >> ensure(Block, pop_indent); | 373 | in_block = space_break >> *(*set(" \t") >> line_break) >> advance_match >> ensure(Block, pop_indent); |
| 309 | 374 | ||
| 310 | LocalFlag = expr('*') | '^'; | 375 | LocalFlag = expr('*') | '^'; |
| 311 | LocalValues = NameList >> -(space >> '=' >> space >> (TableBlock | ExpListLow)); | 376 | LocalValues = NameList >> -(space >> '=' >> space >> (TableBlock | ExpListLow | expected_expression_error)); |
| 312 | Local = key("local") >> space >> (LocalFlag | LocalValues); | 377 | Local = key("local") >> space >> (LocalFlag | LocalValues | invalid_local_declaration_error); |
| 313 | 378 | ||
| 314 | ConstAttrib = key("const"); | 379 | ConstAttrib = key("const"); |
| 315 | CloseAttrib = key("close"); | 380 | CloseAttrib = key("close"); |
| @@ -322,17 +387,25 @@ YueParser::YueParser() { | |||
| 322 | ColonImportName = '\\' >> space >> Variable; | 387 | ColonImportName = '\\' >> space >> Variable; |
| 323 | import_name = ColonImportName | Variable; | 388 | import_name = ColonImportName | Variable; |
| 324 | import_name_list = Seperator >> *space_break >> space >> import_name >> *((+space_break | space >> ',' >> *space_break) >> space >> import_name); | 389 | import_name_list = Seperator >> *space_break >> space >> import_name >> *((+space_break | space >> ',' >> *space_break) >> space >> import_name); |
| 325 | ImportFrom = import_name_list >> *space_break >> space >> key("from") >> space >> (ImportLiteral | not_(String) >> Exp); | 390 | ImportFrom = import_name_list >> *space_break >> space >> key("from") >> space >> (ImportLiteral | not_(String) >> must_exp); |
| 326 | from_import_name_list_line = import_name >> *(space >> ',' >> space >> import_name); | 391 | from_import_name_list_line = import_name >> *(space >> ',' >> space >> import_name); |
| 327 | 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); | 392 | 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); |
| 328 | FromImport = key("from") >> space >> (ImportLiteral | not_(String) >> Exp) >> *space_break >> space >> key("import") >> space >> Seperator >> (from_import_name_list_line >> -(space >> ',') >> -from_import_name_in_block | from_import_name_in_block); | 393 | FromImport = key("from") >> space >> ( |
| 394 | ImportLiteral | not_(String) >> Exp | invalid_from_import_error | ||
| 395 | ) >> *space_break >> space >> ( | ||
| 396 | key("import") | invalid_from_import_error | ||
| 397 | ) >> space >> Seperator >> ( | ||
| 398 | from_import_name_list_line >> -(space >> ',') >> -from_import_name_in_block | | ||
| 399 | from_import_name_in_block | | ||
| 400 | invalid_from_import_error | ||
| 401 | ); | ||
| 329 | 402 | ||
| 330 | ImportLiteralInner = (range('a', 'z') | range('A', 'Z') | set("_-") | larger(255)) >> *(alpha_num | '-' | larger(255)); | 403 | ImportLiteralInner = (range('a', 'z') | range('A', 'Z') | set("_-") | larger(255)) >> *(alpha_num | '-' | larger(255)); |
| 331 | import_literal_chain = Seperator >> ImportLiteralInner >> *('.' >> ImportLiteralInner); | 404 | import_literal_chain = Seperator >> ImportLiteralInner >> *('.' >> ImportLiteralInner); |
| 332 | ImportLiteral = ( | 405 | ImportLiteral = ( |
| 333 | '\'' >> import_literal_chain >> '\'' | 406 | '\'' >> import_literal_chain >> -(not_('\'') >> invalid_import_literal_error) >> '\'' |
| 334 | ) | ( | 407 | ) | ( |
| 335 | '"' >> import_literal_chain >> '"' | 408 | '"' >> import_literal_chain >> -(not_('"') >> invalid_import_literal_error) >> '"' |
| 336 | ); | 409 | ); |
| 337 | 410 | ||
| 338 | MacroNamePair = MacroName >> ':' >> space >> MacroName; | 411 | MacroNamePair = MacroName >> ':' >> space >> MacroName; |
| @@ -363,15 +436,15 @@ YueParser::YueParser() { | |||
| 363 | Seperator >> import_tab_key_value >> *(space >> ',' >> space >> import_tab_key_value) | 436 | Seperator >> import_tab_key_value >> *(space >> ',' >> space >> import_tab_key_value) |
| 364 | ); | 437 | ); |
| 365 | 438 | ||
| 366 | ImportAs = ImportLiteral >> -(space >> key("as") >> space >> (ImportTabLit | Variable | ImportAllMacro)); | 439 | ImportAs = ImportLiteral >> -(space >> key("as") >> space >> (ImportTabLit | Variable | ImportAllMacro | invalid_import_as_syntax_error)); |
| 367 | 440 | ||
| 368 | ImportGlobal = Seperator >> UnicodeName >> *('.' >> UnicodeName) >> -(space >> key("as") >> space >> Variable); | 441 | ImportGlobal = Seperator >> UnicodeName >> *('.' >> UnicodeName) >> -(space >> key("as") >> space >> Variable); |
| 369 | 442 | ||
| 370 | Import = key("import") >> space >> (ImportAs | ImportFrom | ImportGlobal) | FromImport; | 443 | Import = key("import") >> space >> (ImportAs | ImportFrom | ImportGlobal | invalid_import_syntax_error) | FromImport; |
| 371 | 444 | ||
| 372 | Label = "::" >> LabelName >> "::"; | 445 | Label = "::" >> (and_(LuaKeyword >> "::") >> keyword_as_label_error | UnicodeName >> "::"); |
| 373 | 446 | ||
| 374 | Goto = key("goto") >> space >> LabelName; | 447 | Goto = key("goto") >> space >> (and_(LuaKeyword >> not_alpha_num) >> keyword_as_label_error | UnicodeName); |
| 375 | 448 | ||
| 376 | ShortTabAppending = "[]" >> space >> Assign; | 449 | ShortTabAppending = "[]" >> space >> Assign; |
| 377 | 450 | ||
| @@ -381,9 +454,14 @@ YueParser::YueParser() { | |||
| 381 | 454 | ||
| 382 | Return = key("return") >> -(space >> (TableBlock | ExpListLow)); | 455 | Return = key("return") >> -(space >> (TableBlock | ExpListLow)); |
| 383 | 456 | ||
| 384 | with_exp = ExpList >> -(space >> (':' >> Assign | and_('=') >> assignment_expression_syntax_error)); | 457 | must_exp = Exp | expected_expression_error; |
| 385 | 458 | ||
| 386 | With = key("with") >> -ExistentialOp >> space >> disable_do_chain_arg_table_block_rule(with_exp) >> space >> body_with("do"); | 459 | with_exp = ExpList >> -(space >> (':' >> Assign | and_('=') >> assignment_expression_syntax_error)) | expected_expression_error; |
| 460 | |||
| 461 | With = key("with") >> -ExistentialOp >> space >> ( | ||
| 462 | disable_do_chain_arg_table_block_rule(with_exp) >> space >> body_with("do") | | ||
| 463 | invalid_with_syntax_error | ||
| 464 | ); | ||
| 387 | SwitchCase = key("when") >> space >> disable_chain_rule(disable_arg_table_block_rule(SwitchList)) >> space >> body_with("then"); | 465 | SwitchCase = key("when") >> space >> disable_chain_rule(disable_arg_table_block_rule(SwitchList)) >> space >> body_with("then"); |
| 388 | switch_else = key("else") >> space >> body; | 466 | switch_else = key("else") >> space >> body; |
| 389 | 467 | ||
| @@ -395,10 +473,11 @@ YueParser::YueParser() { | |||
| 395 | 473 | ||
| 396 | SwitchList = Seperator >> ( | 474 | SwitchList = Seperator >> ( |
| 397 | and_(SimpleTable | TableLit) >> Exp | | 475 | and_(SimpleTable | TableLit) >> Exp | |
| 398 | exp_not_tab >> *(space >> ',' >> space >> exp_not_tab) | 476 | exp_not_tab >> *(space >> ',' >> space >> exp_not_tab) | |
| 477 | expected_expression_error | ||
| 399 | ); | 478 | ); |
| 400 | Switch = key("switch") >> space >> | 479 | Switch = key("switch") >> space >> |
| 401 | Exp >> -(space >> Assignment) >> | 480 | must_exp >> -(space >> Assignment) >> |
| 402 | space >> Seperator >> ( | 481 | space >> Seperator >> ( |
| 403 | SwitchCase >> space >> ( | 482 | SwitchCase >> space >> ( |
| 404 | switch_block | | 483 | switch_block | |
| @@ -408,7 +487,7 @@ YueParser::YueParser() { | |||
| 408 | ); | 487 | ); |
| 409 | 488 | ||
| 410 | Assignment = -(',' >> space >> ExpList >> space) >> (':' >> Assign | and_('=') >> assignment_expression_syntax_error); | 489 | Assignment = -(',' >> space >> ExpList >> space) >> (':' >> Assign | and_('=') >> assignment_expression_syntax_error); |
| 411 | IfCond = disable_chain_rule(disable_arg_table_block_rule(Exp >> -(space >> Assignment))); | 490 | IfCond = disable_chain_rule(disable_arg_table_block_rule(Exp >> -(space >> Assignment))) | expected_expression_error; |
| 412 | if_else_if = -(line_break >> *space_break >> check_indent_match) >> space >> key("elseif") >> space >> IfCond >> space >> body_with("then"); | 491 | if_else_if = -(line_break >> *space_break >> check_indent_match) >> space >> key("elseif") >> space >> IfCond >> space >> body_with("then"); |
| 413 | if_else = -(line_break >> *space_break >> check_indent_match) >> space >> key("else") >> space >> body; | 492 | if_else = -(line_break >> *space_break >> check_indent_match) >> space >> key("else") >> space >> body; |
| 414 | IfType = (expr("if") | "unless") >> not_alpha_num; | 493 | IfType = (expr("if") | "unless") >> not_alpha_num; |
| @@ -418,22 +497,22 @@ YueParser::YueParser() { | |||
| 418 | State* st = reinterpret_cast<State*>(item.user_data); | 497 | State* st = reinterpret_cast<State*>(item.user_data); |
| 419 | return st->noUntilStack.empty() || !st->noUntilStack.back(); | 498 | return st->noUntilStack.empty() || !st->noUntilStack.back(); |
| 420 | })) >> not_alpha_num; | 499 | })) >> not_alpha_num; |
| 421 | While = key(WhileType) >> space >> disable_do_chain_arg_table_block_rule(Exp >> -(space >> Assignment)) >> space >> opt_body_with("do"); | 500 | While = key(WhileType) >> space >> (disable_do_chain_arg_table_block_rule(Exp >> -(space >> Assignment)) | expected_expression_error) >> space >> opt_body_with("do"); |
| 422 | Repeat = key("repeat") >> space >> ( | 501 | Repeat = key("repeat") >> space >> ( |
| 423 | in_block >> line_break >> *space_break >> check_indent_match | | 502 | in_block >> line_break >> *space_break >> check_indent_match | |
| 424 | disable_until_rule(Statement) | 503 | disable_until_rule(Statement) |
| 425 | ) >> space >> key("until") >> space >> Exp; | 504 | ) >> space >> key("until") >> space >> must_exp; |
| 426 | 505 | ||
| 427 | for_key = pl::user(key("for"), [](const item_t& item) { | 506 | for_key = pl::user(key("for"), [](const item_t& item) { |
| 428 | State* st = reinterpret_cast<State*>(item.user_data); | 507 | State* st = reinterpret_cast<State*>(item.user_data); |
| 429 | return st->noForStack.empty() || !st->noForStack.back(); | 508 | return st->noForStack.empty() || !st->noForStack.back(); |
| 430 | }); | 509 | }); |
| 431 | ForStepValue = ',' >> space >> Exp; | 510 | ForStepValue = ',' >> space >> must_exp; |
| 432 | for_args = Variable >> space >> '=' >> space >> Exp >> space >> ',' >> space >> Exp >> space >> -ForStepValue; | 511 | for_args = Variable >> space >> '=' >> space >> must_exp >> space >> ',' >> space >> must_exp >> space >> -ForStepValue; |
| 433 | 512 | ||
| 434 | For = for_key >> space >> disable_do_chain_arg_table_block_rule(for_args) >> space >> opt_body_with("do"); | 513 | For = for_key >> space >> disable_do_chain_arg_table_block_rule(for_args) >> space >> opt_body_with("do"); |
| 435 | 514 | ||
| 436 | for_in = StarExp | ExpList; | 515 | for_in = StarExp | ExpList | expected_expression_error; |
| 437 | 516 | ||
| 438 | ForEach = for_key >> space >> AssignableNameList >> space >> key("in") >> space >> | 517 | ForEach = for_key >> space >> AssignableNameList >> space >> key("in") >> space >> |
| 439 | disable_do_chain_arg_table_block_rule(for_in) >> space >> opt_body_with("do"); | 518 | disable_do_chain_arg_table_block_rule(for_in) >> space >> opt_body_with("do"); |
| @@ -519,8 +598,8 @@ YueParser::YueParser() { | |||
| 519 | return true; | 598 | return true; |
| 520 | }); | 599 | }); |
| 521 | 600 | ||
| 522 | CatchBlock = line_break >> *space_break >> check_indent_match >> space >> key("catch") >> space >> Variable >> space >> in_block; | 601 | CatchBlock = line_break >> *space_break >> check_indent_match >> space >> key("catch") >> space >> (Variable >> space >> in_block | invalid_try_syntax_error); |
| 523 | Try = key("try") >> -ExistentialOp >> space >> (in_block | Exp) >> -CatchBlock; | 602 | Try = key("try") >> -ExistentialOp >> space >> (in_block | Exp | invalid_try_syntax_error) >> -CatchBlock; |
| 524 | 603 | ||
| 525 | list_value = | 604 | list_value = |
| 526 | and_( | 605 | and_( |
| @@ -556,14 +635,15 @@ YueParser::YueParser() { | |||
| 556 | TblComprehension = and_('{') >> ('{' >> space >> disable_for_rule(Exp >> space >> -(CompValue >> space)) >> CompInner >> space >> '}' | braces_expression_error); | 635 | TblComprehension = and_('{') >> ('{' >> space >> disable_for_rule(Exp >> space >> -(CompValue >> space)) >> CompInner >> space >> '}' | braces_expression_error); |
| 557 | 636 | ||
| 558 | CompInner = Seperator >> (CompForEach | CompFor) >> *(space >> comp_clause); | 637 | CompInner = Seperator >> (CompForEach | CompFor) >> *(space >> comp_clause); |
| 559 | StarExp = '*' >> space >> Exp; | 638 | StarExp = '*' >> space >> must_exp; |
| 560 | CompForEach = key("for") >> space >> AssignableNameList >> space >> key("in") >> space >> (StarExp | Exp); | 639 | CompForEach = key("for") >> space >> AssignableNameList >> space >> key("in") >> space >> (StarExp | must_exp); |
| 561 | CompFor = key("for") >> space >> Variable >> space >> '=' >> space >> Exp >> space >> ',' >> space >> Exp >> -ForStepValue; | 640 | CompFor = key("for") >> space >> Variable >> space >> '=' >> space >> must_exp >> space >> ',' >> space >> must_exp >> -ForStepValue; |
| 562 | comp_clause = CompFor | CompForEach | key("when") >> space >> Exp; | 641 | comp_clause = CompFor | CompForEach | key("when") >> space >> must_exp; |
| 563 | 642 | ||
| 564 | Assign = '=' >> space >> Seperator >> ( | 643 | Assign = '=' >> space >> Seperator >> ( |
| 565 | With | If | Switch | TableBlock | | 644 | With | If | Switch | TableBlock | |
| 566 | (SpreadListExp | Exp) >> *(space >> set(",;") >> space >> (SpreadListExp | Exp)) | 645 | (SpreadListExp | Exp) >> *(space >> set(",;") >> space >> (SpreadListExp | Exp)) | |
| 646 | expected_expression_error | ||
| 567 | ); | 647 | ); |
| 568 | 648 | ||
| 569 | UpdateOp = | 649 | UpdateOp = |
| @@ -571,7 +651,7 @@ YueParser::YueParser() { | |||
| 571 | ">>" | "<<" | "??" | | 651 | ">>" | "<<" | "??" | |
| 572 | set("+-*/%&|^"); | 652 | set("+-*/%&|^"); |
| 573 | 653 | ||
| 574 | Update = UpdateOp >> '=' >> space >> Exp; | 654 | Update = UpdateOp >> '=' >> space >> must_exp; |
| 575 | 655 | ||
| 576 | Assignable = AssignableChain | Variable | SelfItem; | 656 | Assignable = AssignableChain | Variable | SelfItem; |
| 577 | 657 | ||
| @@ -592,18 +672,21 @@ YueParser::YueParser() { | |||
| 592 | UnaryExp = *(UnaryOperator >> space) >> expo_exp >> -(space >> In); | 672 | UnaryExp = *(UnaryOperator >> space) >> expo_exp >> -(space >> In); |
| 593 | 673 | ||
| 594 | pipe_operator = "|>"; | 674 | pipe_operator = "|>"; |
| 595 | pipe_value = pipe_operator >> *space_break >> space >> UnaryExp; | 675 | pipe_value = pipe_operator >> *space_break >> space >> must_unary_exp; |
| 596 | pipe_exp = UnaryExp >> *(space >> pipe_value); | 676 | pipe_exp = UnaryExp >> *(space >> pipe_value); |
| 597 | 677 | ||
| 598 | BinaryOperator = | 678 | BinaryOperator = ( |
| 599 | key("or") | | 679 | key("or") | |
| 600 | key("and") | | 680 | key("and") | |
| 601 | "<=" | ">=" | "~=" | "!=" | "==" | | 681 | "<=" | ">=" | "~=" | "!=" | "==" | |
| 602 | ".." | "<<" | ">>" | "//" | | 682 | ".." | "<<" | ">>" | "//" | |
| 603 | set("+-*/%><|&~"); | 683 | set("+*/%>|&~") | |
| 684 | '-' >> not_('>') | | ||
| 685 | '<' >> not_('-') | ||
| 686 | ) >> not_('='); | ||
| 604 | 687 | ||
| 605 | ExpOpValue = BinaryOperator >> *space_break >> space >> pipe_exp; | 688 | ExpOpValue = BinaryOperator >> *space_break >> space >> (pipe_exp | expected_expression_error); |
| 606 | Exp = Seperator >> pipe_exp >> *(space >> ExpOpValue) >> -(space >> "??" >> space >> Exp); | 689 | Exp = Seperator >> pipe_exp >> *(space >> ExpOpValue) >> -(space >> "??" >> not_('=') >> *space_break >> space >> must_exp); |
| 607 | 690 | ||
| 608 | disable_chain = pl::user(true_(), [](const item_t& item) { | 691 | disable_chain = pl::user(true_(), [](const item_t& item) { |
| 609 | State* st = reinterpret_cast<State*>(item.user_data); | 692 | State* st = reinterpret_cast<State*>(item.user_data); |
| @@ -635,7 +718,7 @@ YueParser::YueParser() { | |||
| 635 | st->expLevel++; | 718 | st->expLevel++; |
| 636 | const int max_exp_level = 100; | 719 | const int max_exp_level = 100; |
| 637 | if (st->expLevel > max_exp_level) { | 720 | if (st->expLevel > max_exp_level) { |
| 638 | throw ParserError("nesting expressions exceeds 100 levels"sv, item.begin); | 721 | RaiseError("nesting expressions exceeds 100 levels"sv, item); |
| 639 | } | 722 | } |
| 640 | return true; | 723 | return true; |
| 641 | }); | 724 | }); |
| @@ -650,13 +733,13 @@ YueParser::YueParser() { | |||
| 650 | Value = inc_exp_level >> ensure(SimpleValue | SimpleTable | ChainValue | String, dec_exp_level); | 733 | Value = inc_exp_level >> ensure(SimpleValue | SimpleTable | ChainValue | String, dec_exp_level); |
| 651 | 734 | ||
| 652 | single_string_inner = '\\' >> set("'\\") | not_('\'') >> any_char; | 735 | single_string_inner = '\\' >> set("'\\") | not_('\'') >> any_char; |
| 653 | SingleString = '\'' >> *single_string_inner >> '\''; | 736 | SingleString = '\'' >> *single_string_inner >> ('\'' | unclosed_single_string_error); |
| 654 | 737 | ||
| 655 | interp = "#{" >> space >> (Exp >> space >> '}' | invalid_interpolation_error); | 738 | interp = "#{" >> space >> (Exp >> space >> '}' | invalid_interpolation_error); |
| 656 | double_string_plain = '\\' >> set("\"\\#") | not_('"') >> any_char; | 739 | double_string_plain = '\\' >> set("\"\\#") | not_('"') >> any_char; |
| 657 | DoubleStringInner = +(not_("#{") >> double_string_plain); | 740 | DoubleStringInner = +(not_("#{") >> double_string_plain); |
| 658 | DoubleStringContent = DoubleStringInner | interp; | 741 | DoubleStringContent = DoubleStringInner | interp; |
| 659 | DoubleString = '"' >> Seperator >> *DoubleStringContent >> '"'; | 742 | DoubleString = '"' >> Seperator >> *DoubleStringContent >> ('"' | unclosed_double_string_error); |
| 660 | 743 | ||
| 661 | YAMLIndent = +set(" \t"); | 744 | YAMLIndent = +set(" \t"); |
| 662 | YAMLLineInner = +('\\' >> set("\"\\#") | not_("#{" | stop) >> any_char); | 745 | YAMLLineInner = +('\\' >> set("\"\\#") | not_("#{" | stop) >> any_char); |
| @@ -685,9 +768,9 @@ YueParser::YueParser() { | |||
| 685 | 768 | ||
| 686 | LuaStringContent = *(not_(LuaStringClose) >> any_char); | 769 | LuaStringContent = *(not_(LuaStringClose) >> any_char); |
| 687 | 770 | ||
| 688 | LuaString = LuaStringOpen >> -line_break >> LuaStringContent >> LuaStringClose; | 771 | LuaString = LuaStringOpen >> -line_break >> LuaStringContent >> (LuaStringClose | unclosed_lua_string_error); |
| 689 | 772 | ||
| 690 | Parens = '(' >> *space_break >> space >> Exp >> *space_break >> space >> ')'; | 773 | Parens = '(' >> (*space_break >> space >> Exp >> *space_break >> space >> ')' | parenthesis_error); |
| 691 | Callable = Variable | SelfItem | MacroName | Parens; | 774 | Callable = Variable | SelfItem | MacroName | Parens; |
| 692 | 775 | ||
| 693 | fn_args_value_list = Exp >> *(space >> ',' >> space >> Exp); | 776 | fn_args_value_list = Exp >> *(space >> ',' >> space >> Exp); |
| @@ -703,7 +786,7 @@ YueParser::YueParser() { | |||
| 703 | fn_args = | 786 | fn_args = |
| 704 | '(' >> -(space >> fn_args_value_list >> -(space >> ',')) >> | 787 | '(' >> -(space >> fn_args_value_list >> -(space >> ',')) >> |
| 705 | -fn_args_lit_lines >> | 788 | -fn_args_lit_lines >> |
| 706 | white >> ')' | space >> '!' >> not_('='); | 789 | white >> -(and_(',') >> unexpected_comma_error) >>')' | space >> '!' >> not_('='); |
| 707 | 790 | ||
| 708 | meta_index = Name | index | String; | 791 | meta_index = Name | index | String; |
| 709 | Metatable = '<' >> space >> '>'; | 792 | Metatable = '<' >> space >> '>'; |
| @@ -735,7 +818,7 @@ YueParser::YueParser() { | |||
| 735 | chain_with_colon = +chain_item >> -colon_chain; | 818 | chain_with_colon = +chain_item >> -colon_chain; |
| 736 | chain_items = chain_with_colon | colon_chain; | 819 | chain_items = chain_with_colon | colon_chain; |
| 737 | 820 | ||
| 738 | index = '[' >> not_('[') >> space >> (ReversedIndex >> and_(space >> ']') | Exp) >> space >> ']'; | 821 | index = '[' >> not_('[') >> space >> (ReversedIndex >> and_(space >> ']') | Exp) >> space >> (']' | brackets_expression_error); |
| 739 | ReversedIndex = '#' >> space >> -('-' >> space >> Exp); | 822 | ReversedIndex = '#' >> space >> -('-' >> space >> Exp); |
| 740 | chain_item = | 823 | chain_item = |
| 741 | Invoke >> -ExistentialOp | | 824 | Invoke >> -ExistentialOp | |
| @@ -808,13 +891,18 @@ YueParser::YueParser() { | |||
| 808 | ClassDecl = | 891 | ClassDecl = |
| 809 | key("class") >> not_(':') >> disable_arg_table_block_rule( | 892 | key("class") >> not_(':') >> disable_arg_table_block_rule( |
| 810 | -(space >> Assignable) >> | 893 | -(space >> Assignable) >> |
| 811 | -(space >> key("extends") >> prevent_indent >> space >> ensure(Exp, pop_indent)) >> | 894 | -(space >> key("extends") >> prevent_indent >> space >> ensure(must_exp, pop_indent)) >> |
| 812 | -(space >> key("using") >> prevent_indent >> space >> ensure(ExpList, pop_indent)) | 895 | -(space >> key("using") >> prevent_indent >> space >> ensure(ExpList | expected_expression_error, pop_indent)) |
| 813 | ) >> -ClassBlock; | 896 | ) >> -ClassBlock; |
| 814 | 897 | ||
| 815 | GlobalValues = NameList >> -(space >> '=' >> space >> (TableBlock | ExpListLow)); | 898 | GlobalValues = NameList >> -(space >> '=' >> space >> (TableBlock | ExpListLow | expected_expression_error)); |
| 816 | GlobalOp = expr('*') | '^'; | 899 | GlobalOp = expr('*') | '^'; |
| 817 | Global = key("global") >> space >> (-(ConstAttrib >> space) >> ClassDecl | GlobalOp | -(ConstAttrib >> space) >> GlobalValues); | 900 | Global = key("global") >> space >> ( |
| 901 | -(ConstAttrib >> space) >> ClassDecl | | ||
| 902 | GlobalOp | | ||
| 903 | -(ConstAttrib >> space) >> GlobalValues | | ||
| 904 | invalid_global_declaration_error | ||
| 905 | ); | ||
| 818 | 906 | ||
| 819 | ExportDefault = key("default"); | 907 | ExportDefault = key("default"); |
| 820 | 908 | ||
| @@ -826,10 +914,10 @@ YueParser::YueParser() { | |||
| 826 | pl::user(space >> ExportDefault >> space >> Exp, [](const item_t& item) { | 914 | pl::user(space >> ExportDefault >> space >> Exp, [](const item_t& item) { |
| 827 | State* st = reinterpret_cast<State*>(item.user_data); | 915 | State* st = reinterpret_cast<State*>(item.user_data); |
| 828 | if (st->exportDefault) { | 916 | if (st->exportDefault) { |
| 829 | throw ParserError("export default has already been declared"sv, item.begin); | 917 | RaiseError("export default has already been declared"sv, item); |
| 830 | } | 918 | } |
| 831 | if (st->exportCount > 1) { | 919 | if (st->exportCount > 1) { |
| 832 | throw ParserError("there are items already being exported"sv, item.begin); | 920 | RaiseError("there are items already being exported"sv, item); |
| 833 | } | 921 | } |
| 834 | st->exportDefault = true; | 922 | st->exportDefault = true; |
| 835 | return true; | 923 | return true; |
| @@ -837,17 +925,17 @@ YueParser::YueParser() { | |||
| 837 | not_(space >> ExportDefault) >> pl::user(true_(), [](const item_t& item) { | 925 | not_(space >> ExportDefault) >> pl::user(true_(), [](const item_t& item) { |
| 838 | State* st = reinterpret_cast<State*>(item.user_data); | 926 | State* st = reinterpret_cast<State*>(item.user_data); |
| 839 | if (st->exportDefault && st->exportCount > 1) { | 927 | if (st->exportDefault && st->exportCount > 1) { |
| 840 | throw ParserError("can not export any more items when 'export default' is declared"sv, item.begin); | 928 | RaiseError("can not export any more items when 'export default' is declared"sv, item); |
| 841 | } | 929 | } |
| 842 | return true; | 930 | return true; |
| 843 | }) >> ( | 931 | }) >> ( |
| 844 | and_(set(".[")) >> ((pl::user(and_('.' >> Metatable), [](const item_t& item) { | 932 | and_(set(".[")) >> ((pl::user(and_('.' >> Metatable), [](const item_t& item) { |
| 845 | State* st = reinterpret_cast<State*>(item.user_data); | 933 | State* st = reinterpret_cast<State*>(item.user_data); |
| 846 | if (st->exportMetatable) { | 934 | if (st->exportMetatable) { |
| 847 | throw ParserError("module metatable duplicated"sv, item.begin); | 935 | RaiseError("module metatable duplicated"sv, item); |
| 848 | } | 936 | } |
| 849 | if (st->exportMetamethod) { | 937 | if (st->exportMetamethod) { |
| 850 | throw ParserError("metatable should be exported before metamethod"sv, item.begin); | 938 | RaiseError("metatable should be exported before metamethod"sv, item); |
| 851 | } | 939 | } |
| 852 | st->exportMetatable = true; | 940 | st->exportMetatable = true; |
| 853 | return true; | 941 | return true; |
| @@ -862,10 +950,13 @@ YueParser::YueParser() { | |||
| 862 | State* st = reinterpret_cast<State*>(item.user_data); | 950 | State* st = reinterpret_cast<State*>(item.user_data); |
| 863 | st->exportMacro = true; | 951 | st->exportMacro = true; |
| 864 | return true; | 952 | return true; |
| 865 | }) | 953 | }) | |
| 954 | invalid_export_syntax_error | ||
| 866 | ) >> not_(space >> StatementAppendix); | 955 | ) >> not_(space >> StatementAppendix); |
| 867 | 956 | ||
| 868 | VariablePair = ':' >> Variable; | 957 | check_keyword_as_identifier = and_(LuaKeyword >> not_alpha_num) >> keyword_as_identifier_syntax_error; |
| 958 | |||
| 959 | VariablePair = ':' >> (Variable | check_keyword_as_identifier); | ||
| 869 | 960 | ||
| 870 | NormalPair = | 961 | NormalPair = |
| 871 | ( | 962 | ( |
| @@ -873,12 +964,12 @@ YueParser::YueParser() { | |||
| 873 | '[' >> not_('[') >> space >> Exp >> space >> ']' | | 964 | '[' >> not_('[') >> space >> Exp >> space >> ']' | |
| 874 | String | 965 | String |
| 875 | ) >> ':' >> not_(':') >> space >> | 966 | ) >> ':' >> not_(':') >> space >> |
| 876 | (Exp | TableBlock | +space_break >> space >> Exp); | 967 | (Exp | TableBlock | +space_break >> space >> Exp | check_keyword_as_identifier); |
| 877 | 968 | ||
| 878 | MetaVariablePair = ":<" >> space >> Variable >> space >> '>'; | 969 | MetaVariablePair = ":<" >> space >> Variable >> space >> '>'; |
| 879 | 970 | ||
| 880 | MetaNormalPair = '<' >> space >> -meta_index >> space >> ">:" >> space >> | 971 | MetaNormalPair = '<' >> space >> -meta_index >> space >> ">:" >> space >> |
| 881 | (Exp | TableBlock | +space_break >> space >> Exp); | 972 | (Exp | TableBlock | +space_break >> space >> Exp | check_keyword_as_identifier); |
| 882 | 973 | ||
| 883 | destruct_def = -(space >> '=' >> space >> Exp); | 974 | destruct_def = -(space >> '=' >> space >> Exp); |
| 884 | VariablePairDef = VariablePair >> destruct_def; | 975 | VariablePairDef = VariablePair >> destruct_def; |
| @@ -911,14 +1002,16 @@ YueParser::YueParser() { | |||
| 911 | 1002 | ||
| 912 | FnArgDef = (Variable | SelfItem >> -ExistentialOp) >> -(space >> '`' >> space >> Name) >> -(space >> '=' >> space >> Exp) | TableLit | SimpleTable; | 1003 | FnArgDef = (Variable | SelfItem >> -ExistentialOp) >> -(space >> '`' >> space >> Name) >> -(space >> '=' >> space >> Exp) | TableLit | SimpleTable; |
| 913 | 1004 | ||
| 1005 | check_vararg_position = and_(white >> ')') | white >> -(',' >> white) >> vararg_position_error; | ||
| 1006 | |||
| 914 | FnArgDefList = Seperator >> ( | 1007 | FnArgDefList = Seperator >> ( |
| 915 | fn_arg_def_lit_lines >> -(-(space >> ',') >> white >> VarArg >> -(space >> '`' >> space >> Name)) | | 1008 | fn_arg_def_lit_lines >> -(-(space >> ',') >> white >> VarArg >> -(space >> '`' >> space >> Name) >> check_vararg_position) | |
| 916 | white >> VarArg >> -(space >> '`' >> space >> Name) | 1009 | white >> VarArg >> -(space >> '`' >> space >> Name) >> check_vararg_position |
| 917 | ); | 1010 | ); |
| 918 | 1011 | ||
| 919 | OuterVarShadow = key("using") >> space >> (NameList | key("nil")); | 1012 | OuterVarShadow = key("using") >> space >> (NameList | key("nil")); |
| 920 | 1013 | ||
| 921 | FnArgsDef = '(' >> *space_break >> -FnArgDefList >> -(white >> OuterVarShadow) >> white >> ')'; | 1014 | FnArgsDef = '(' >> *space_break >> -FnArgDefList >> -(white >> OuterVarShadow) >> white >> -(and_(',') >> unexpected_comma_error) >> ')'; |
| 922 | FnArrow = expr("->") | "=>"; | 1015 | FnArrow = expr("->") | "=>"; |
| 923 | FunLit = pl::user(true_(), [](const item_t& item) { | 1016 | FunLit = pl::user(true_(), [](const item_t& item) { |
| 924 | State* st = reinterpret_cast<State*>(item.user_data); | 1017 | State* st = reinterpret_cast<State*>(item.user_data); |
| @@ -930,10 +1023,13 @@ YueParser::YueParser() { | |||
| 930 | ) >> space >> FnArrow >> -(space >> Body); | 1023 | ) >> space >> FnArrow >> -(space >> Body); |
| 931 | 1024 | ||
| 932 | MacroName = '$' >> UnicodeName; | 1025 | MacroName = '$' >> UnicodeName; |
| 933 | macro_args_def = '(' >> white >> -FnArgDefList >> white >> ')'; | 1026 | macro_args_def = '(' >> white >> -FnArgDefList >> white >> -(and_(',') >> unexpected_comma_error) >> ')'; |
| 934 | MacroLit = -(macro_args_def >> space) >> "->" >> space >> Body; | 1027 | MacroLit = -(macro_args_def >> space) >> "->" >> space >> Body; |
| 935 | MacroFunc = MacroName >> (Invoke | InvokeArgs); | 1028 | MacroFunc = MacroName >> (Invoke | InvokeArgs); |
| 936 | Macro = key("macro") >> space >> UnicodeName >> space >> '=' >> space >> (MacroLit | MacroFunc); | 1029 | Macro = key("macro") >> space >> ( |
| 1030 | UnicodeName >> space >> '=' >> space >> (MacroLit | MacroFunc) | | ||
| 1031 | invalid_macro_definition_error | ||
| 1032 | ); | ||
| 937 | MacroInPlace = '$' >> space >> "->" >> space >> Body; | 1033 | MacroInPlace = '$' >> space >> "->" >> space >> Body; |
| 938 | 1034 | ||
| 939 | NameList = Seperator >> Variable >> *(space >> ',' >> space >> Variable); | 1035 | NameList = Seperator >> Variable >> *(space >> ',' >> space >> Variable); |
| @@ -944,9 +1040,11 @@ YueParser::YueParser() { | |||
| 944 | Backcall = -(FnArgsDef >> space) >> FnArrowBack >> space >> ChainValue; | 1040 | Backcall = -(FnArgsDef >> space) >> FnArrowBack >> space >> ChainValue; |
| 945 | SubBackcall = FnArrowBack >> space >> ChainValue; | 1041 | SubBackcall = FnArrowBack >> space >> ChainValue; |
| 946 | 1042 | ||
| 1043 | must_unary_exp = UnaryExp | expected_expression_error; | ||
| 1044 | |||
| 947 | PipeBody = Seperator >> | 1045 | PipeBody = Seperator >> |
| 948 | pipe_operator >> space >> UnaryExp >> | 1046 | pipe_operator >> space >> must_unary_exp >> |
| 949 | *(+space_break >> check_indent_match >> space >> pipe_operator >> space >> UnaryExp); | 1047 | *(+space_break >> check_indent_match >> space >> pipe_operator >> space >> must_unary_exp); |
| 950 | 1048 | ||
| 951 | ExpList = Seperator >> Exp >> *(space >> ',' >> space >> Exp); | 1049 | ExpList = Seperator >> Exp >> *(space >> ',' >> space >> Exp); |
| 952 | ExpListLow = Seperator >> Exp >> *(space >> set(",;") >> space >> Exp); | 1050 | ExpListLow = Seperator >> Exp >> *(space >> set(",;") >> space >> Exp); |
| @@ -965,35 +1063,14 @@ YueParser::YueParser() { | |||
| 965 | space_break >> advance_match >> arg_block >> -(-(space >> ',') >> arg_table_block) | 1063 | space_break >> advance_match >> arg_block >> -(-(space >> ',') >> arg_table_block) |
| 966 | ) | arg_table_block; | 1064 | ) | arg_table_block; |
| 967 | 1065 | ||
| 968 | leading_spaces_error = pl::user(+space_one >> '(' >> space >> Exp >> +(space >> ',' >> space >> Exp) >> space >> ')', [](const item_t& item) { | ||
| 969 | throw ParserError("write invoke arguments in parentheses without leading spaces or just leading spaces without parentheses"sv, item.begin); | ||
| 970 | return false; | ||
| 971 | }); | ||
| 972 | |||
| 973 | InvokeArgs = | 1066 | InvokeArgs = |
| 974 | not_(set("-~") | "[]") >> space >> Seperator >> ( | 1067 | not_(set("-~") | "[]") >> space >> Seperator >> ( |
| 975 | Exp >> *(space >> ',' >> space >> Exp) >> -(space >> invoke_args_with_table) | | 1068 | Exp >> *(space >> ',' >> space >> Exp) >> -(space >> invoke_args_with_table) | |
| 976 | arg_table_block | | 1069 | arg_table_block |
| 977 | leading_spaces_error | ||
| 978 | ); | 1070 | ); |
| 979 | 1071 | ||
| 980 | ConstValue = (expr("nil") | "true" | "false") >> not_alpha_num; | 1072 | ConstValue = (expr("nil") | "true" | "false") >> not_alpha_num; |
| 981 | 1073 | ||
| 982 | braces_expression_error = pl::user(true_(), [](const item_t& item) { | ||
| 983 | throw ParserError("syntax error in brace expression"sv, item.begin); | ||
| 984 | return false; | ||
| 985 | }); | ||
| 986 | |||
| 987 | brackets_expression_error = pl::user(true_(), [](const item_t& item) { | ||
| 988 | throw ParserError("syntax error in bracket expression"sv, item.begin); | ||
| 989 | return false; | ||
| 990 | }); | ||
| 991 | |||
| 992 | slice_expression_error = pl::user(true_(), [](const item_t& item) { | ||
| 993 | throw ParserError("syntax error in slice expression"sv, item.begin); | ||
| 994 | return false; | ||
| 995 | }); | ||
| 996 | |||
| 997 | SimpleValue = | 1074 | SimpleValue = |
| 998 | TableLit | ConstValue | If | Switch | Try | With | | 1075 | TableLit | ConstValue | If | Switch | Try | With | |
| 999 | ClassDecl | ForEach | For | While | Repeat | Do | | 1076 | ClassDecl | ForEach | For | While | Repeat | Do | |
| @@ -1033,7 +1110,8 @@ YueParser::YueParser() { | |||
| 1033 | Return | Local | Global | Export | Macro | | 1110 | Return | Local | Global | Export | Macro | |
| 1034 | MacroInPlace | BreakLoop | Label | Goto | ShortTabAppending | | 1111 | MacroInPlace | BreakLoop | Label | Goto | ShortTabAppending | |
| 1035 | LocalAttrib | Backcall | PipeBody | ExpListAssign | ChainAssign | | 1112 | LocalAttrib | Backcall | PipeBody | ExpListAssign | ChainAssign | |
| 1036 | StatementAppendix >> empty_block_error | 1113 | StatementAppendix >> empty_block_error | |
| 1114 | and_(key("else") | key("elseif") | key("when")) >> dangling_clause_error | ||
| 1037 | ) >> | 1115 | ) >> |
| 1038 | space >> | 1116 | space >> |
| 1039 | -StatementAppendix; | 1117 | -StatementAppendix; |
| @@ -1048,7 +1126,7 @@ YueParser::YueParser() { | |||
| 1048 | plain_space >> and_(line_break); | 1126 | plain_space >> and_(line_break); |
| 1049 | 1127 | ||
| 1050 | indentation_error = pl::user(not_(pipe_operator | eof()), [](const item_t& item) { | 1128 | indentation_error = pl::user(not_(pipe_operator | eof()), [](const item_t& item) { |
| 1051 | throw ParserError("unexpected indent"sv, item.begin); | 1129 | RaiseError("unexpected indent"sv, item); |
| 1052 | return false; | 1130 | return false; |
| 1053 | }); | 1131 | }); |
| 1054 | 1132 | ||
diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h index d5c37e2..3aca4ef 100644 --- a/src/yuescript/yue_parser.h +++ b/src/yuescript/yue_parser.h | |||
| @@ -149,7 +149,6 @@ private: | |||
| 149 | } | 149 | } |
| 150 | 150 | ||
| 151 | NONE_AST_RULE(empty_block_error); | 151 | NONE_AST_RULE(empty_block_error); |
| 152 | NONE_AST_RULE(leading_spaces_error); | ||
| 153 | NONE_AST_RULE(indentation_error); | 152 | NONE_AST_RULE(indentation_error); |
| 154 | NONE_AST_RULE(braces_expression_error); | 153 | NONE_AST_RULE(braces_expression_error); |
| 155 | NONE_AST_RULE(brackets_expression_error); | 154 | NONE_AST_RULE(brackets_expression_error); |
| @@ -159,11 +158,35 @@ private: | |||
| 159 | NONE_AST_RULE(confusing_unary_not_error); | 158 | NONE_AST_RULE(confusing_unary_not_error); |
| 160 | NONE_AST_RULE(table_key_pair_error); | 159 | NONE_AST_RULE(table_key_pair_error); |
| 161 | NONE_AST_RULE(assignment_expression_syntax_error); | 160 | NONE_AST_RULE(assignment_expression_syntax_error); |
| 161 | NONE_AST_RULE(unclosed_single_string_error); | ||
| 162 | NONE_AST_RULE(unclosed_double_string_error); | ||
| 163 | NONE_AST_RULE(unclosed_lua_string_error); | ||
| 164 | NONE_AST_RULE(unexpected_comma_error); | ||
| 165 | NONE_AST_RULE(parenthesis_error); | ||
| 166 | NONE_AST_RULE(dangling_clause_error); | ||
| 167 | NONE_AST_RULE(keyword_as_label_error); | ||
| 168 | NONE_AST_RULE(check_vararg_position); | ||
| 169 | NONE_AST_RULE(vararg_position_error); | ||
| 170 | NONE_AST_RULE(invalid_import_syntax_error); | ||
| 171 | NONE_AST_RULE(invalid_import_as_syntax_error); | ||
| 172 | NONE_AST_RULE(expected_expression_error); | ||
| 173 | NONE_AST_RULE(invalid_from_import_error); | ||
| 174 | NONE_AST_RULE(invalid_export_syntax_error); | ||
| 175 | NONE_AST_RULE(invalid_macro_definition_error); | ||
| 176 | NONE_AST_RULE(invalid_global_declaration_error); | ||
| 177 | NONE_AST_RULE(invalid_local_declaration_error); | ||
| 178 | NONE_AST_RULE(invalid_with_syntax_error); | ||
| 179 | NONE_AST_RULE(invalid_try_syntax_error); | ||
| 180 | NONE_AST_RULE(keyword_as_identifier_syntax_error); | ||
| 181 | NONE_AST_RULE(check_keyword_as_identifier); | ||
| 182 | NONE_AST_RULE(invalid_number_literal_error); | ||
| 183 | NONE_AST_RULE(invalid_import_literal_error); | ||
| 162 | 184 | ||
| 163 | NONE_AST_RULE(inc_exp_level); | 185 | NONE_AST_RULE(inc_exp_level); |
| 164 | NONE_AST_RULE(dec_exp_level); | 186 | NONE_AST_RULE(dec_exp_level); |
| 165 | 187 | ||
| 166 | NONE_AST_RULE(num_char); | 188 | NONE_AST_RULE(num_char); |
| 189 | NONE_AST_RULE(must_num_char); | ||
| 167 | NONE_AST_RULE(num_char_hex); | 190 | NONE_AST_RULE(num_char_hex); |
| 168 | NONE_AST_RULE(num_lit); | 191 | NONE_AST_RULE(num_lit); |
| 169 | NONE_AST_RULE(num_bin_lit); | 192 | NONE_AST_RULE(num_bin_lit); |
| @@ -282,6 +305,8 @@ private: | |||
| 282 | NONE_AST_RULE(expo_value); | 305 | NONE_AST_RULE(expo_value); |
| 283 | NONE_AST_RULE(expo_exp); | 306 | NONE_AST_RULE(expo_exp); |
| 284 | NONE_AST_RULE(exp_not_tab); | 307 | NONE_AST_RULE(exp_not_tab); |
| 308 | NONE_AST_RULE(must_exp); | ||
| 309 | NONE_AST_RULE(must_unary_exp); | ||
| 285 | NONE_AST_RULE(local_const_item); | 310 | NONE_AST_RULE(local_const_item); |
| 286 | NONE_AST_RULE(empty_line_break); | 311 | NONE_AST_RULE(empty_line_break); |
| 287 | NONE_AST_RULE(yue_comment); | 312 | NONE_AST_RULE(yue_comment); |
| @@ -294,7 +319,6 @@ private: | |||
| 294 | AST_RULE(Name); | 319 | AST_RULE(Name); |
| 295 | AST_RULE(UnicodeName); | 320 | AST_RULE(UnicodeName); |
| 296 | AST_RULE(Variable); | 321 | AST_RULE(Variable); |
| 297 | AST_RULE(LabelName); | ||
| 298 | AST_RULE(LuaKeyword); | 322 | AST_RULE(LuaKeyword); |
| 299 | AST_RULE(Self); | 323 | AST_RULE(Self); |
| 300 | AST_RULE(SelfName); | 324 | AST_RULE(SelfName); |
diff --git a/src/yuescript/yuescript.cpp b/src/yuescript/yuescript.cpp index 2be74be..52236bf 100644 --- a/src/yuescript/yuescript.cpp +++ b/src/yuescript/yuescript.cpp | |||
| @@ -255,7 +255,7 @@ static int yuecheck(lua_State* L) { | |||
| 255 | lua_rawseti(L, -2, ++i); | 255 | lua_rawseti(L, -2, ++i); |
| 256 | } | 256 | } |
| 257 | } | 257 | } |
| 258 | if (result.error) { | 258 | if (!config.lax && result.error) { |
| 259 | lua_pushboolean(L, 0); | 259 | lua_pushboolean(L, 0); |
| 260 | lua_insert(L, -2); | 260 | lua_insert(L, -2); |
| 261 | return 2; | 261 | return 2; |
