aboutsummaryrefslogtreecommitdiff
path: root/MoonParser/moon_parser.cpp
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2020-01-10 16:30:34 +0800
committerLi Jin <dragon-fly@qq.com>2020-01-10 16:30:34 +0800
commit52a6536103f46c26a3ba9b149b0fe7b40d524d8c (patch)
tree67e4759f8e1ea922079d0e162d84ecba5e558261 /MoonParser/moon_parser.cpp
parent975167856ed0b11c2ede03c6eb750ca4e4a6a7fc (diff)
downloadyuescript-52a6536103f46c26a3ba9b149b0fe7b40d524d8c.tar.gz
yuescript-52a6536103f46c26a3ba9b149b0fe7b40d524d8c.tar.bz2
yuescript-52a6536103f46c26a3ba9b149b0fe7b40d524d8c.zip
update.
Diffstat (limited to 'MoonParser/moon_parser.cpp')
-rw-r--r--MoonParser/moon_parser.cpp513
1 files changed, 0 insertions, 513 deletions
diff --git a/MoonParser/moon_parser.cpp b/MoonParser/moon_parser.cpp
deleted file mode 100644
index 2b93c22..0000000
--- a/MoonParser/moon_parser.cpp
+++ /dev/null
@@ -1,513 +0,0 @@
1#include "moon_parser.h"
2
3namespace MoonP {
4
5std::unordered_set<std::string> State::luaKeywords = {
6 "and", "break", "do", "else", "elseif",
7 "end", "false", "for", "function", "if",
8 "in", "local", "nil", "not", "or",
9 "repeat", "return", "then", "true", "until",
10 "while"
11};
12
13std::unordered_set<std::string> State::keywords = {
14 "and", "break", "do", "else", "elseif",
15 "end", "false", "for", "function", "if",
16 "in", "local", "nil", "not", "or",
17 "repeat", "return", "then", "true", "until",
18 "while", // Lua keywords
19 "class", "continue", "export", "extends", "from",
20 "import", "switch", "unless", "using", "when",
21 "with" // Moon keywords
22};
23
24rule plain_space = *set(" \t");
25rule Break = nl(-expr('\r') >> '\n');
26rule Any = Break | any();
27rule White = *(set(" \t") | Break);
28rule Stop = Break | eof();
29rule Comment = "--" >> *(not_(set("\r\n")) >> Any) >> and_(Stop);
30rule Indent = *set(" \t");
31rule Space = plain_space >> -Comment;
32rule SomeSpace = +set(" \t") >> -Comment;
33rule SpaceBreak = Space >> Break;
34rule EmptyLine = SpaceBreak;
35rule AlphaNum = range('a', 'z') | range('A', 'Z') | range('0', '9') | '_';
36rule Name = (range('a', 'z') | range('A', 'Z') | '_') >> *AlphaNum;
37rule Num =
38 (
39 "0x" >>
40 +(range('0', '9') | range('a', 'f') | range('A', 'F'))
41 ) | (
42 (
43 (+range('0', '9') >> -('.' >> +range('0', '9'))) |
44 ('.' >> +range('0', '9'))
45 ) >> -(set("eE") >> -expr('-') >> +range('0', '9'))
46 );
47rule Cut = false_();
48rule Seperator = true_();
49
50#define sym(str) (Space >> str)
51#define symx(str) expr(str)
52#define ensure(patt, finally) (((patt) >> (finally)) | ((finally) >> (Cut)))
53#define key(str) (Space >> str >> not_(AlphaNum))
54
55rule Variable = user(Name, [](const item_t& item) {
56 State* st = reinterpret_cast<State*>(item.user_data);
57 for (auto it = item.begin; it != item.end; ++it) st->buffer += static_cast<char>(*it);
58 auto it = State::keywords.find(st->buffer);
59 st->buffer.clear();
60 return it == State::keywords.end();
61});
62
63rule LuaKeyword = user(Name, [](const item_t& item) {
64 State* st = reinterpret_cast<State*>(item.user_data);
65 for (auto it = item.begin; it != item.end; ++it) st->buffer += static_cast<char>(*it);
66 auto it = State::luaKeywords.find(st->buffer);
67 st->buffer.clear();
68 return it != State::luaKeywords.end();
69});
70
71rule self = expr('@');
72rule self_name = '@' >> Name;
73rule self_class = expr("@@");
74rule self_class_name = "@@" >> Name;
75
76rule SelfName = Space >> (self_class_name | self_class | self_name | self);
77rule KeyName = SelfName | Space >> Name;
78rule VarArg = Space >> "...";
79
80rule check_indent = user(Indent, [](const item_t& item) {
81 int indent = 0;
82 for (input_it i = item.begin; i != item.end; ++i) {
83 switch (*i) {
84 case ' ': indent++; break;
85 case '\t': indent += 4; break;
86 }
87 }
88 State* st = reinterpret_cast<State*>(item.user_data);
89 return st->indents.top() == indent;
90});
91rule CheckIndent = and_(check_indent);
92
93rule advance = user(Indent, [](const item_t& item) {
94 int indent = 0;
95 for (input_it i = item.begin; i != item.end; ++i) {
96 switch (*i) {
97 case ' ': indent++; break;
98 case '\t': indent += 4; break;
99 }
100 }
101 State* st = reinterpret_cast<State*>(item.user_data);
102 int top = st->indents.top();
103 if (top != -1 && indent > top) {
104 st->indents.push(indent);
105 return true;
106 }
107 return false;
108});
109rule Advance = and_(advance);
110
111rule push_indent = user(Indent, [](const item_t& item) {
112 int indent = 0;
113 for (input_it i = item.begin; i != item.end; ++i) {
114 switch (*i) {
115 case ' ': indent++; break;
116 case '\t': indent += 4; break;
117 }
118 }
119 State* st = reinterpret_cast<State*>(item.user_data);
120 st->indents.push(indent);
121 return true;
122});
123rule PushIndent = and_(push_indent);
124
125rule PreventIndent = user(true_(), [](const item_t& item) {
126 State* st = reinterpret_cast<State*>(item.user_data);
127 st->indents.push(-1);
128 return true;
129});
130
131rule PopIndent = user(true_(), [](const item_t& item) {
132 State* st = reinterpret_cast<State*>(item.user_data);
133 st->indents.pop();
134 return true;
135});
136
137extern rule Block;
138
139rule InBlock = Advance >> Block >> PopIndent;
140
141extern rule NameList;
142
143rule local_flag = expr('*') | expr('^');
144rule Local = key("local") >> ((Space >> local_flag) | NameList);
145
146rule colon_import_name = sym('\\') >> Space >> Variable;
147rule ImportName = colon_import_name | Space >> Variable;
148rule ImportNameList = Seperator >> *SpaceBreak >> ImportName >> *((+SpaceBreak | sym(',') >> *SpaceBreak) >> ImportName);
149
150extern rule Exp;
151
152rule Import = key("import") >> ImportNameList >> *SpaceBreak >> key("from") >> Exp;
153rule BreakLoop = (expr("break") | expr("continue")) >> not_(AlphaNum);
154
155extern rule ExpListLow, ExpList, Assign;
156
157rule Return = key("return") >> -ExpListLow;
158rule WithExp = ExpList >> -Assign;
159
160extern rule DisableDo, PopDo, Body;
161
162rule With = key("with") >> DisableDo >> ensure(WithExp, PopDo) >> -key("do") >> Body;
163rule SwitchCase = key("when") >> ExpList >> -key("then") >> Body;
164rule SwitchElse = key("else") >> Body;
165
166rule SwitchBlock = *EmptyLine >>
167 Advance >> Seperator >>
168 SwitchCase >>
169 *(+Break >> SwitchCase) >>
170 -(+Break >> SwitchElse) >>
171 PopIndent;
172
173rule Switch = key("switch") >>
174 DisableDo >> ensure(Exp, PopDo) >>
175 -key("do") >> -Space >> Break >> SwitchBlock;
176
177rule IfCond = Exp >> -Assign;
178rule IfElseIf = -(Break >> *EmptyLine >> CheckIndent) >> key("elseif") >> IfCond >> -key("then") >> Body;
179rule IfElse = -(Break >> *EmptyLine >> CheckIndent) >> key("else") >> Body;
180rule If = key("if") >> Seperator >> IfCond >> -key("then") >> Body >> *IfElseIf >> -IfElse;
181rule Unless = key("unless") >> Seperator >> IfCond >> -key("then") >> Body >> *IfElseIf >> -IfElse;
182
183rule While = key("while") >> DisableDo >> ensure(Exp, PopDo) >> -key("do") >> Body;
184
185rule for_step_value = sym(',') >> Exp;
186rule for_args = Space >> Variable >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value;
187
188rule For = key("for") >> DisableDo >>
189 ensure(for_args, PopDo) >>
190 -key("do") >> Body;
191
192extern rule AssignableNameList;
193
194extern rule star_exp;
195
196rule for_in = star_exp | ExpList;
197
198rule ForEach = key("for") >> AssignableNameList >> key("in") >>
199 DisableDo >> ensure(for_in, PopDo) >>
200 -key("do") >> Body;
201
202rule Do = user(key("do") >> Body, [](const item_t& item)
203{
204 State* st = reinterpret_cast<State*>(item.user_data);
205 return st->doStack.empty() || st->doStack.top();
206});
207
208rule DisableDo = user(true_(), [](const item_t& item)
209{
210 State* st = reinterpret_cast<State*>(item.user_data);
211 st->doStack.push(false);
212 return true;
213});
214
215rule PopDo = user(true_(), [](const item_t& item)
216{
217 State* st = reinterpret_cast<State*>(item.user_data);
218 st->doStack.pop();
219 return true;
220});
221
222extern rule CompInner;
223
224rule Comprehension = sym('[') >> Exp >> CompInner >> sym(']');
225rule comp_value = sym(',') >> Exp;
226rule TblComprehension = sym('{') >> (Exp >> -comp_value) >> CompInner >> sym('}');
227
228extern rule CompForEach, CompFor, CompClause;
229
230rule CompInner = Seperator >> (CompForEach | CompFor) >> *CompClause;
231rule star_exp = sym('*') >> Exp;
232rule CompForEach = key("for") >> AssignableNameList >> key("in") >> (star_exp | Exp);
233rule CompFor = key("for") >> Space >> Variable >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value;
234rule CompClause = CompFor | CompForEach | key("when") >> Exp;
235
236extern rule TableBlock;
237
238rule Assign = sym('=') >> Seperator >> (With | If | Switch | TableBlock | Exp >> *((sym(',') | sym(';')) >> Exp));
239
240rule update_op =
241 expr("..") |
242 expr("+") |
243 expr("-") |
244 expr("*") |
245 expr("/") |
246 expr("%") |
247 expr("or") |
248 expr("and") |
249 expr("&") |
250 expr("|") |
251 expr(">>") |
252 expr("<<");
253
254rule Update = Space >> update_op >> expr("=") >> Exp;
255
256rule BinaryOperator =
257 (expr("or") >> not_(AlphaNum)) |
258 (expr("and") >> not_(AlphaNum)) |
259 expr("<=") |
260 expr(">=") |
261 expr("~=") |
262 expr("!=") |
263 expr("==") |
264 expr("..") |
265 expr("<<") |
266 expr(">>") |
267 expr("//") |
268 set("+-*/%^><|&");
269
270extern rule AssignableChain;
271
272rule Assignable = AssignableChain | Space >> Variable | SelfName;
273
274extern rule Value;
275
276rule exp_op_value = Space >> BinaryOperator >> *SpaceBreak >> Value;
277rule Exp = Value >> *exp_op_value;
278
279extern rule Chain, Callable, InvokeArgs;
280
281rule ChainValue = Seperator >> (Chain | Callable) >> -InvokeArgs;
282
283extern rule KeyValue, String, SimpleValue;
284
285rule simple_table = Seperator >> KeyValue >> *(sym(',') >> KeyValue);
286rule Value = SimpleValue | simple_table | ChainValue | String;
287
288extern rule LuaString;
289
290rule single_string_inner = expr("\\'") | "\\\\" | not_(expr('\'')) >> Any;
291rule SingleString = symx('\'') >> *single_string_inner >> sym('\'');
292rule interp = symx("#{") >> Exp >> sym('}');
293rule double_string_plain = expr("\\\"") | "\\\\" | not_(expr('"')) >> Any;
294rule double_string_inner = +(not_(interp) >> double_string_plain);
295rule double_string_content = double_string_inner | interp;
296rule DoubleString = symx('"') >> Seperator >> *double_string_content >> sym('"');
297rule String = Space >> (DoubleString | SingleString | LuaString);
298
299rule lua_string_open = '[' >> *expr('=') >> '[';
300rule lua_string_close = ']' >> *expr('=') >> ']';
301
302rule LuaStringOpen = user(lua_string_open, [](const item_t& item)
303{
304 size_t count = std::distance(item.begin, item.end);
305 State* st = reinterpret_cast<State*>(item.user_data);
306 st->stringOpen = count;
307 return true;
308});
309
310rule LuaStringClose = user(lua_string_close, [](const item_t& item)
311{
312 size_t count = std::distance(item.begin, item.end);
313 State* st = reinterpret_cast<State*>(item.user_data);
314 return st->stringOpen == count;
315});
316
317rule LuaStringContent = *(not_(LuaStringClose) >> (Break | Any));
318
319rule LuaString = user(LuaStringOpen >> -Break >> LuaStringContent >> LuaStringClose, [](const item_t& item)
320{
321 State* st = reinterpret_cast<State*>(item.user_data);
322 st->stringOpen = -1;
323 return true;
324});
325
326rule Parens = sym('(') >> *SpaceBreak >> Exp >> *SpaceBreak >> sym(')');
327rule Callable = Space >> Variable | SelfName | VarArg | Parens;
328rule FnArgsExpList = Exp >> *((Break | sym(',')) >> White >> Exp);
329
330rule FnArgs = (symx('(') >> *SpaceBreak >> -FnArgsExpList >> *SpaceBreak >> sym(')')) |
331 (sym('!') >> not_(expr('=')));
332
333extern rule ChainItems, DotChainItem, ColonChain;
334
335rule chain_call = (Callable | String) >> ChainItems;
336rule chain_item = and_(set(".\\")) >> ChainItems;
337rule chain_dot_chain = DotChainItem >> -ChainItems;
338
339rule Chain = chain_call | chain_item |
340 Space >> (chain_dot_chain | ColonChain);
341
342rule AssignableChain = Seperator >> Chain;
343
344extern rule ChainItem;
345
346rule chain_with_colon = +ChainItem >> -ColonChain;
347rule ChainItems = chain_with_colon | ColonChain;
348
349extern rule Invoke, Slice;
350
351rule Index = symx('[') >> Exp >> sym(']');
352rule ChainItem = Invoke | DotChainItem | Slice | Index;
353rule DotChainItem = symx('.') >> Name;
354rule ColonChainItem = symx('\\') >> (LuaKeyword | Name);
355rule invoke_chain = Invoke >> -ChainItems;
356rule ColonChain = ColonChainItem >> -invoke_chain;
357
358rule default_value = true_();
359rule Slice =
360 symx('[') >>
361 (Exp | default_value) >>
362 sym(',') >>
363 (Exp | default_value) >>
364 (sym(',') >> Exp | default_value) >>
365 sym(']');
366
367rule Invoke = Seperator >> (
368 FnArgs |
369 SingleString |
370 DoubleString |
371 and_(expr('[')) >> LuaString);
372
373extern rule TableValueList, TableLitLine;
374
375rule TableValue = KeyValue | Exp;
376
377rule table_lit_lines = SpaceBreak >> TableLitLine >> *(-sym(',') >> SpaceBreak >> TableLitLine) >> -sym(',');
378
379rule TableLit =
380 sym('{') >> Seperator >>
381 -TableValueList >>
382 -sym(',') >>
383 -table_lit_lines >>
384 White >> sym('}');
385
386rule TableValueList = TableValue >> *(sym(',') >> TableValue);
387
388rule TableLitLine =
389(
390 PushIndent >> (TableValueList >> PopIndent | PopIndent)
391) | (
392 Space
393);
394
395extern rule KeyValueLine;
396
397rule TableBlockInner = Seperator >> KeyValueLine >> *(+(SpaceBreak) >> KeyValueLine);
398rule TableBlock = +(SpaceBreak) >> Advance >> ensure(TableBlockInner, PopIndent);
399
400extern rule Statement;
401
402rule class_member_list = Seperator >> KeyValue >> *(sym(',') >> KeyValue);
403rule ClassLine = CheckIndent >> (class_member_list | Statement) >> -sym(',');
404rule ClassBlock = +(SpaceBreak) >> Advance >>Seperator >> ClassLine >> *(+(SpaceBreak) >> ClassLine) >> PopIndent;
405
406rule ClassDecl =
407 key("class") >> not_(expr(':')) >>
408 -Assignable >>
409 -(key("extends") >> PreventIndent >> ensure(Exp, PopIndent)) >>
410 -ClassBlock;
411
412rule export_values = NameList >> -(sym('=') >> ExpListLow);
413rule export_op = expr('*') | expr('^');
414rule Export = key("export") >> (ClassDecl | (Space >> export_op) | export_values);
415
416rule variable_pair = sym(':') >> not_(SomeSpace) >> Space >> Variable;
417
418rule normal_pair =
419(
420 KeyName |
421 sym('[') >> Exp >> sym(']') |
422 Space >> DoubleString |
423 Space >> SingleString
424) >>
425symx(':') >>
426(Exp | TableBlock | +(SpaceBreak) >> Exp);
427
428rule KeyValue = variable_pair | normal_pair;
429
430rule KeyValueList = KeyValue >> *(sym(',') >> KeyValue);
431rule KeyValueLine = CheckIndent >> KeyValueList >> -sym(',');
432
433rule FnArgDef = (Space >> Variable | SelfName) >> -(sym('=') >> Exp);
434
435rule FnArgDefList = Seperator >>
436(
437 (
438 FnArgDef >>
439 *((sym(',') | Break) >> White >> FnArgDef) >>
440 -((sym(',') | Break) >> White >> VarArg)
441 ) | (
442 VarArg
443 )
444);
445
446rule outer_var_shadow = key("using") >> (NameList | Space >> expr("nil"));
447
448rule FnArgsDef = sym('(') >> White >> -FnArgDefList >> -outer_var_shadow >> White >> sym(')');
449rule fn_arrow = expr("->") | expr("=>");
450rule FunLit = -FnArgsDef >> Space >> fn_arrow >> -Body;
451
452rule NameList = Seperator >> Space >> Variable >> *(sym(',') >> Space >> Variable);
453rule NameOrDestructure = Space >> Variable | TableLit;
454rule AssignableNameList = Seperator >> NameOrDestructure >> *(sym(',') >> NameOrDestructure);
455
456rule ExpList = Seperator >> Exp >> *(sym(',') >> Exp);
457rule ExpListLow = Seperator >> Exp >> *((sym(',') | sym(';')) >> Exp);
458
459rule ArgLine = CheckIndent >> Exp >> *(sym(',') >> Exp);
460rule ArgBlock = ArgLine >> *(sym(',') >> SpaceBreak >> ArgLine) >> PopIndent;
461
462rule invoke_args_with_table =
463 sym(',') >>
464 (
465 TableBlock |
466 SpaceBreak >> Advance >> ArgBlock >> -TableBlock
467 );
468
469rule InvokeArgs =
470 not_(expr('-')) >> Seperator >>
471 (
472 Exp >> *(sym(',') >> Exp) >> -(invoke_args_with_table | TableBlock) |
473 TableBlock
474 );
475
476rule const_value = (expr("nil") | expr("true") | expr("false")) >> not_(AlphaNum);
477rule minus_exp = expr('-') >> not_(SomeSpace) >> Exp;
478rule sharp_exp = expr('#') >> Exp;
479rule tilde_exp = expr('~') >> Exp;
480rule not_exp = expr("not") >> not_(AlphaNum) >> Exp;
481rule unary_exp = minus_exp | sharp_exp | tilde_exp | not_exp;
482
483rule SimpleValue =
484 (Space >> const_value) |
485 If | Unless | Switch | With | ClassDecl | ForEach | For | While | Do |
486 (Space >> unary_exp) |
487 TblComprehension | TableLit | Comprehension | FunLit |
488 (Space >> Num);
489
490rule ExpListAssign = ExpList >> -(Update | Assign);
491
492rule if_else_line = key("if") >> Exp >> (key("else") >> Exp | default_value);
493rule unless_line = key("unless") >> Exp;
494
495rule statement_appendix = (if_else_line | unless_line | CompInner) >> Space;
496rule Statement =
497(
498 Import | While | For | ForEach |
499 Return | Local | Export | Space >> BreakLoop |
500 ExpListAssign
501) >> Space >>
502-statement_appendix;
503
504rule Body = -Space >> Break >> *EmptyLine >> InBlock | Statement;
505
506rule empty_line_stop = Space >> and_(Stop);
507rule Line = CheckIndent >> Statement | empty_line_stop;
508rule Block = Seperator >> Line >> *(+Break >> Line);
509
510rule Shebang = expr("#!") >> *(not_(Stop) >> Any);
511rule File = White >> -Shebang >> Block >> eof();
512
513} // namespace MoonP