From ca1ed557769352c0ac0ca7804dd25e18c1fdf2e1 Mon Sep 17 00:00:00 2001 From: Li Jin Date: Fri, 1 Apr 2022 17:47:27 +0800 Subject: fix some ambiguous syntax caused by arg table block. --- src/yuescript/yue_compiler.cpp | 14 +++++++++++--- src/yuescript/yue_parser.cpp | 40 +++++++++++++++++++++------------------- src/yuescript/yue_parser.h | 8 ++++---- 3 files changed, 36 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index 4e01c24..26a8c5a 100755 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp @@ -60,7 +60,7 @@ using namespace parserlib; typedef std::list str_list; -const std::string_view version = "0.10.7"sv; +const std::string_view version = "0.10.8"sv; const std::string_view extension = "yue"sv; class YueCompilerImpl { @@ -1876,8 +1876,16 @@ private: if (destructNode || (destructNode = value->item.as())) { if (*j != nullNode) { if (auto ssVal = simpleSingleValueFrom(*j)) { - if (ssVal->value.is()) { - throw std::logic_error(_info.errorMessage("can not destructure a const value"sv, ssVal->value)); + switch (ssVal->value->getId()) { + case id(): + throw std::logic_error(_info.errorMessage("can not destructure a const value"sv, ssVal->value)); + break; + case id(): + throw std::logic_error(_info.errorMessage("can not destructure a number"sv, ssVal->value)); + break; + case id(): + throw std::logic_error(_info.errorMessage("can not destructure a function"sv, ssVal->value)); + break; } } } else { diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index 258997e..ab9b657 100755 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp @@ -75,7 +75,7 @@ YueParser::YueParser() { #define key(str) (str >> not_(AlphaNum)) #define disable_do(patt) (DisableDo >> ((patt) >> EnableDo | EnableDo >> Cut)) #define disable_chain(patt) (DisableChain >> ((patt) >> EnableChain | EnableChain >> Cut)) - #define disable_do_chain(patt) (DisableDoChain >> ((patt) >> EnableDoChain | EnableDoChain >> Cut)) + #define disable_do_chain_arg_table_block(patt) (DisableDoChainArgTableBlock >> ((patt) >> EnableDoChainArgTableBlock | EnableDoChainArgTableBlock >> Cut)) #define disable_arg_table_block(patt) (DisableArgTableBlock >> ((patt) >> EnableArgTableBlock | EnableArgTableBlock >> Cut)) #define plain_body_with(str) (-(Space >> key(str)) >> InBlock | Space >> key(str) >> Statement) #define plain_body (InBlock | Statement) @@ -223,8 +223,8 @@ YueParser::YueParser() { WithExp = ExpList >> -Assign; - With = Space >> key("with") >> -existential_op >> disable_do_chain(WithExp) >> plain_body_with("do"); - SwitchCase = Space >> key("when") >> disable_chain(ExpList) >> plain_body_with("then"); + With = Space >> key("with") >> -existential_op >> disable_do_chain_arg_table_block(WithExp) >> plain_body_with("do"); + SwitchCase = Space >> key("when") >> disable_chain(disable_arg_table_block(ExpList)) >> plain_body_with("then"); SwitchElse = Space >> key("else") >> plain_body; SwitchBlock = *EmptyLine >> @@ -238,54 +238,56 @@ YueParser::YueParser() { >> -Space >> Break >> SwitchBlock; assignment = ExpList >> Assign; - IfCond = disable_do_chain(disable_arg_table_block(assignment | Exp)); + IfCond = disable_do_chain_arg_table_block(assignment | Exp); IfElseIf = -(Break >> *EmptyLine >> CheckIndent) >> Space >> key("elseif") >> IfCond >> plain_body_with("then"); IfElse = -(Break >> *EmptyLine >> CheckIndent) >> Space >> key("else") >> plain_body; IfType = (expr("if") | expr("unless")) >> not_(AlphaNum); If = Space >> IfType >> IfCond >> plain_body_with("then") >> *IfElseIf >> -IfElse; WhileType = (expr("while") | expr("until")) >> not_(AlphaNum); - While = WhileType >> disable_do_chain(Exp) >> plain_body_with("do"); + While = WhileType >> disable_do_chain_arg_table_block(Exp) >> plain_body_with("do"); Repeat = key("repeat") >> Body >> Break >> *EmptyLine >> CheckIndent >> Space >> key("until") >> Exp; for_step_value = sym(',') >> Exp; for_args = Space >> Variable >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value; - For = key("for") >> disable_do_chain(for_args) >> plain_body_with("do"); + For = key("for") >> disable_do_chain_arg_table_block(for_args) >> plain_body_with("do"); for_in = star_exp | ExpList; ForEach = key("for") >> AssignableNameList >> Space >> key("in") >> - disable_do_chain(for_in) >> plain_body_with("do"); + disable_do_chain_arg_table_block(for_in) >> plain_body_with("do"); Do = pl::user(Space >> key("do"), [](const item_t& item) { State* st = reinterpret_cast(item.user_data); - return st->doStack.empty() || st->doStack.top(); + return st->noDoStack.empty() || !st->noDoStack.top(); }) >> Body; DisableDo = pl::user(true_(), [](const item_t& item) { State* st = reinterpret_cast(item.user_data); - st->doStack.push(false); + st->noDoStack.push(true); return true; }); EnableDo = pl::user(true_(), [](const item_t& item) { State* st = reinterpret_cast(item.user_data); - st->doStack.pop(); + st->noDoStack.pop(); return true; }); - DisableDoChain = pl::user(true_(), [](const item_t& item) { + DisableDoChainArgTableBlock = pl::user(true_(), [](const item_t& item) { State* st = reinterpret_cast(item.user_data); - st->doStack.push(false); - st->chainBlockStack.push(false); + st->noDoStack.push(true); + st->noChainBlockStack.push(true); + st->noTableBlockStack.push(true); return true; }); - EnableDoChain = pl::user(true_(), [](const item_t& item) { + EnableDoChainArgTableBlock = pl::user(true_(), [](const item_t& item) { State* st = reinterpret_cast(item.user_data); - st->doStack.pop(); - st->chainBlockStack.pop(); + st->noDoStack.pop(); + st->noChainBlockStack.pop(); + st->noTableBlockStack.pop(); return true; }); @@ -370,20 +372,20 @@ YueParser::YueParser() { DisableChain = pl::user(true_(), [](const item_t& item) { State* st = reinterpret_cast(item.user_data); - st->chainBlockStack.push(false); + st->noChainBlockStack.push(true); return true; }); EnableChain = pl::user(true_(), [](const item_t& item) { State* st = reinterpret_cast(item.user_data); - st->chainBlockStack.pop(); + st->noChainBlockStack.pop(); return true; }); chain_line = CheckIndent >> (chain_item | Space >> (chain_dot_chain | ColonChain)) >> -InvokeArgs; chain_block = pl::user(true_(), [](const item_t& item) { State* st = reinterpret_cast(item.user_data); - return st->chainBlockStack.empty() || st->chainBlockStack.top(); + return st->noChainBlockStack.empty() || !st->noChainBlockStack.top(); }) >> +SpaceBreak >> Advance >> ensure( chain_line >> *(+SpaceBreak >> chain_line), PopIndent); ChainValue = Seperator >> (Chain | Callable) >> -existential_op >> -(InvokeArgs | chain_block) >> -table_appending_op; diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h index 51e6977..6be8451 100755 --- a/src/yuescript/yue_parser.h +++ b/src/yuescript/yue_parser.h @@ -77,8 +77,8 @@ protected: std::string moduleName = "_module_0"; std::string buffer; std::stack indents; - std::stack doStack; - std::stack chainBlockStack; + std::stack noDoStack; + std::stack noChainBlockStack; std::stack noTableBlockStack; }; @@ -135,8 +135,8 @@ private: rule EnableDo; rule DisableChain; rule EnableChain; - rule DisableDoChain; - rule EnableDoChain; + rule DisableDoChainArgTableBlock; + rule EnableDoChainArgTableBlock; rule DisableArgTableBlock; rule EnableArgTableBlock; rule SwitchElse; -- cgit v1.2.3-55-g6feb