diff options
author | Li Jin <dragon-fly@qq.com> | 2021-02-15 13:17:47 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2021-02-15 13:17:47 +0800 |
commit | c6e90a619d4bf027fa0c9fd81c71a6227b8cb3ca (patch) | |
tree | 31d0b1b50b718f0aa4e4c67a368c5acbf9e7e146 /src/MoonP/moon_parser.cpp | |
parent | c3a389e2f9f53fb3e3e70a325bf42c8ce02a0b82 (diff) | |
download | yuescript-c6e90a619d4bf027fa0c9fd81c71a6227b8cb3ca.tar.gz yuescript-c6e90a619d4bf027fa0c9fd81c71a6227b8cb3ca.tar.bz2 yuescript-c6e90a619d4bf027fa0c9fd81c71a6227b8cb3ca.zip |
fix some ambiguous syntax.
Diffstat (limited to 'src/MoonP/moon_parser.cpp')
-rw-r--r-- | src/MoonP/moon_parser.cpp | 69 |
1 files changed, 42 insertions, 27 deletions
diff --git a/src/MoonP/moon_parser.cpp b/src/MoonP/moon_parser.cpp index aafe730..a581e15 100644 --- a/src/MoonP/moon_parser.cpp +++ b/src/MoonP/moon_parser.cpp | |||
@@ -70,8 +70,13 @@ MoonParser::MoonParser() { | |||
70 | 70 | ||
71 | #define sym(str) (Space >> str) | 71 | #define sym(str) (Space >> str) |
72 | #define symx(str) expr(str) | 72 | #define symx(str) expr(str) |
73 | #define ensure(patt, finally) (((patt) >> (finally)) | ((finally) >> (Cut))) | 73 | #define ensure(patt, finally) ((patt) >> (finally) | (finally) >> Cut) |
74 | #define key(str) (Space >> str >> not_(AlphaNum)) | 74 | #define key(str) (Space >> str >> not_(AlphaNum)) |
75 | #define disable_do(patt) (DisableDo >> ((patt) >> EnableDo | EnableDo >> Cut)) | ||
76 | #define disable_chain(patt) (DisableChain >> ((patt) >> EnableChain | EnableChain >> Cut)) | ||
77 | #define disable_do_chain(patt) (DisableDoChain >> ((patt) >> EnableDoChain | EnableDoChain >> Cut)) | ||
78 | #define plain_body_with(str) (-key(str) >> InBlock | key(str) >> Statement) | ||
79 | #define plain_body (InBlock | Statement) | ||
75 | 80 | ||
76 | Variable = pl::user(Name, [](const item_t& item) { | 81 | Variable = pl::user(Name, [](const item_t& item) { |
77 | State* st = reinterpret_cast<State*>(item.user_data); | 82 | State* st = reinterpret_cast<State*>(item.user_data); |
@@ -169,7 +174,7 @@ MoonParser::MoonParser() { | |||
169 | return true; | 174 | return true; |
170 | }); | 175 | }); |
171 | 176 | ||
172 | InBlock = Advance >> ensure(Block, PopIndent); | 177 | InBlock = +SpaceBreak >> Advance >> ensure(Block, PopIndent); |
173 | 178 | ||
174 | local_flag = expr('*') | expr('^'); | 179 | local_flag = expr('*') | expr('^'); |
175 | local_values = NameList >> -(sym('=') >> (TableBlock | ExpListLow)); | 180 | local_values = NameList >> -(sym('=') >> (TableBlock | ExpListLow)); |
@@ -219,11 +224,11 @@ MoonParser::MoonParser() { | |||
219 | 224 | ||
220 | Return = key("return") >> -ExpListLow; | 225 | Return = key("return") >> -ExpListLow; |
221 | 226 | ||
222 | WithExp = DisableChainBlock >> ensure(ExpList >> -Assign, PopChainBlock); | 227 | WithExp = ExpList >> -Assign; |
223 | 228 | ||
224 | With = key("with") >> -existential_op >> DisableDo >> ensure(WithExp, PopDo) >> -key("do") >> Body; | 229 | With = key("with") >> -existential_op >> disable_do_chain(WithExp) >> plain_body_with("do"); |
225 | SwitchCase = key("when") >> ExpList >> -key("then") >> Body; | 230 | SwitchCase = key("when") >> disable_chain(ExpList) >> plain_body_with("then"); |
226 | SwitchElse = key("else") >> Body; | 231 | SwitchElse = key("else") >> plain_body; |
227 | 232 | ||
228 | SwitchBlock = *EmptyLine >> | 233 | SwitchBlock = *EmptyLine >> |
229 | Advance >> Seperator >> | 234 | Advance >> Seperator >> |
@@ -232,31 +237,27 @@ MoonParser::MoonParser() { | |||
232 | -(+SpaceBreak >> SwitchElse) >> | 237 | -(+SpaceBreak >> SwitchElse) >> |
233 | PopIndent; | 238 | PopIndent; |
234 | 239 | ||
235 | Switch = key("switch") >> | 240 | Switch = key("switch") >> disable_do(Exp) >> -key("do") |
236 | DisableDo >> ensure(Exp, PopDo) >> | 241 | >> -Space >> Break >> SwitchBlock; |
237 | -key("do") >> -Space >> Break >> SwitchBlock; | ||
238 | 242 | ||
239 | IfCond = Exp >> -Assign; | 243 | IfCond = disable_chain(Exp >> -Assign); |
240 | IfElseIf = -(Break >> *EmptyLine >> CheckIndent) >> key("elseif") >> IfCond >> -key("then") >> Body; | 244 | IfElseIf = -(Break >> *EmptyLine >> CheckIndent) >> key("elseif") >> IfCond >> plain_body_with("then"); |
241 | IfElse = -(Break >> *EmptyLine >> CheckIndent) >> key("else") >> Body; | 245 | IfElse = -(Break >> *EmptyLine >> CheckIndent) >> key("else") >> plain_body; |
242 | If = key("if") >> Seperator >> IfCond >> -key("then") >> Body >> *IfElseIf >> -IfElse; | 246 | If = key("if") >> Seperator >> IfCond >> plain_body_with("then") >> *IfElseIf >> -IfElse; |
243 | Unless = key("unless") >> Seperator >> IfCond >> -key("then") >> Body >> *IfElseIf >> -IfElse; | 247 | Unless = key("unless") >> Seperator >> IfCond >> plain_body_with("then") >> *IfElseIf >> -IfElse; |
244 | 248 | ||
245 | While = key("while") >> DisableDo >> ensure(Exp, PopDo) >> -key("do") >> Body; | 249 | While = key("while") >> disable_do_chain(Exp) >> plain_body_with("do"); |
246 | Repeat = key("repeat") >> Body >> Break >> *EmptyLine >> CheckIndent >> key("until") >> Exp; | 250 | Repeat = key("repeat") >> Body >> Break >> *EmptyLine >> CheckIndent >> key("until") >> Exp; |
247 | 251 | ||
248 | for_step_value = sym(',') >> Exp; | 252 | for_step_value = sym(',') >> Exp; |
249 | for_args = Space >> Variable >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value; | 253 | for_args = Space >> Variable >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value; |
250 | 254 | ||
251 | For = key("for") >> DisableDo >> | 255 | For = key("for") >> disable_do_chain(for_args) >> plain_body_with("do"); |
252 | ensure(for_args, PopDo) >> | ||
253 | -key("do") >> Body; | ||
254 | 256 | ||
255 | for_in = star_exp | ExpList; | 257 | for_in = star_exp | ExpList; |
256 | 258 | ||
257 | ForEach = key("for") >> AssignableNameList >> key("in") >> | 259 | ForEach = key("for") >> AssignableNameList >> key("in") >> |
258 | DisableDo >> ensure(for_in, PopDo) >> | 260 | disable_do_chain(for_in) >> plain_body_with("do"); |
259 | -key("do") >> Body; | ||
260 | 261 | ||
261 | Do = pl::user(key("do"), [](const item_t& item) { | 262 | Do = pl::user(key("do"), [](const item_t& item) { |
262 | State* st = reinterpret_cast<State*>(item.user_data); | 263 | State* st = reinterpret_cast<State*>(item.user_data); |
@@ -269,12 +270,26 @@ MoonParser::MoonParser() { | |||
269 | return true; | 270 | return true; |
270 | }); | 271 | }); |
271 | 272 | ||
272 | PopDo = pl::user(true_(), [](const item_t& item) { | 273 | EnableDo = pl::user(true_(), [](const item_t& item) { |
273 | State* st = reinterpret_cast<State*>(item.user_data); | 274 | State* st = reinterpret_cast<State*>(item.user_data); |
274 | st->doStack.pop(); | 275 | st->doStack.pop(); |
275 | return true; | 276 | return true; |
276 | }); | 277 | }); |
277 | 278 | ||
279 | DisableDoChain = pl::user(true_(), [](const item_t& item) { | ||
280 | State* st = reinterpret_cast<State*>(item.user_data); | ||
281 | st->doStack.push(false); | ||
282 | st->chainBlockStack.push(false); | ||
283 | return true; | ||
284 | }); | ||
285 | |||
286 | EnableDoChain = pl::user(true_(), [](const item_t& item) { | ||
287 | State* st = reinterpret_cast<State*>(item.user_data); | ||
288 | st->doStack.pop(); | ||
289 | st->chainBlockStack.pop(); | ||
290 | return true; | ||
291 | }); | ||
292 | |||
278 | Comprehension = sym('[') >> Exp >> CompInner >> sym(']'); | 293 | Comprehension = sym('[') >> Exp >> CompInner >> sym(']'); |
279 | comp_value = sym(',') >> Exp; | 294 | comp_value = sym(',') >> Exp; |
280 | TblComprehension = sym('{') >> Exp >> -comp_value >> CompInner >> sym('}'); | 295 | TblComprehension = sym('{') >> Exp >> -comp_value >> CompInner >> sym('}'); |
@@ -338,13 +353,13 @@ MoonParser::MoonParser() { | |||
338 | exp_op_value = Space >> BinaryOperator >> *SpaceBreak >> backcall_exp; | 353 | exp_op_value = Space >> BinaryOperator >> *SpaceBreak >> backcall_exp; |
339 | Exp = Seperator >> backcall_exp >> *exp_op_value; | 354 | Exp = Seperator >> backcall_exp >> *exp_op_value; |
340 | 355 | ||
341 | DisableChainBlock = pl::user(true_(), [](const item_t& item) { | 356 | DisableChain = pl::user(true_(), [](const item_t& item) { |
342 | State* st = reinterpret_cast<State*>(item.user_data); | 357 | State* st = reinterpret_cast<State*>(item.user_data); |
343 | st->chainBlockStack.push(false); | 358 | st->chainBlockStack.push(false); |
344 | return true; | 359 | return true; |
345 | }); | 360 | }); |
346 | 361 | ||
347 | PopChainBlock = pl::user(true_(), [](const item_t& item) { | 362 | EnableChain = pl::user(true_(), [](const item_t& item) { |
348 | State* st = reinterpret_cast<State*>(item.user_data); | 363 | State* st = reinterpret_cast<State*>(item.user_data); |
349 | st->chainBlockStack.pop(); | 364 | st->chainBlockStack.pop(); |
350 | return true; | 365 | return true; |
@@ -356,7 +371,7 @@ MoonParser::MoonParser() { | |||
356 | return st->chainBlockStack.empty() || st->chainBlockStack.top(); | 371 | return st->chainBlockStack.empty() || st->chainBlockStack.top(); |
357 | }) >> +SpaceBreak >> Advance >> ensure( | 372 | }) >> +SpaceBreak >> Advance >> ensure( |
358 | chain_line >> *(+SpaceBreak >> chain_line), PopIndent); | 373 | chain_line >> *(+SpaceBreak >> chain_line), PopIndent); |
359 | ChainValue = Seperator >> (Chain | Callable) >> -existential_op >> (chain_block | -InvokeArgs); | 374 | ChainValue = Seperator >> (Chain | Callable) >> -existential_op >> -(InvokeArgs | chain_block); |
360 | 375 | ||
361 | simple_table = Seperator >> KeyValue >> *(sym(',') >> KeyValue); | 376 | simple_table = Seperator >> KeyValue >> *(sym(',') >> KeyValue); |
362 | Value = SimpleValue | simple_table | ChainValue | String; | 377 | Value = SimpleValue | simple_table | ChainValue | String; |
@@ -586,10 +601,10 @@ MoonParser::MoonParser() { | |||
586 | ) >> Space >> | 601 | ) >> Space >> |
587 | -statement_appendix >> -statement_sep; | 602 | -statement_appendix >> -statement_sep; |
588 | 603 | ||
589 | Body = Space >> Break >> *EmptyLine >> InBlock | Statement; | 604 | Body = InBlock | Statement; |
590 | 605 | ||
591 | empty_line_stop = Space >> and_(Stop); | 606 | empty_line_stop = Space >> and_(Stop); |
592 | Line = CheckIndent >> Statement | and_(Space >> BackcallOperator) >> Advance >> ensure(Statement, PopIndent) | empty_line_stop; | 607 | Line = and_(check_indent >> Space >> not_(BackcallOperator)) >> Statement | Advance >> ensure(and_(Space >> BackcallOperator) >> Statement, PopIndent) | empty_line_stop; |
593 | Block = Seperator >> Line >> *(+Break >> Line); | 608 | Block = Seperator >> Line >> *(+Break >> Line); |
594 | 609 | ||
595 | Shebang = expr("#!") >> *(not_(Stop) >> Any); | 610 | Shebang = expr("#!") >> *(not_(Stop) >> Any); |