aboutsummaryrefslogtreecommitdiff
path: root/MoonParser/moon_parser.cpp
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2017-07-19 11:05:45 +0800
committerLi Jin <dragon-fly@qq.com>2017-07-19 11:05:45 +0800
commit65dd230959dbab99b52b99fd807534c254fb4ed9 (patch)
treefb5b2718be96bf1f67bf8b015fcc8e2b1dfd5d7e /MoonParser/moon_parser.cpp
parent2531792fa8da2a2f2ae218c43937f88028d26888 (diff)
downloadyuescript-65dd230959dbab99b52b99fd807534c254fb4ed9.tar.gz
yuescript-65dd230959dbab99b52b99fd807534c254fb4ed9.tar.bz2
yuescript-65dd230959dbab99b52b99fd807534c254fb4ed9.zip
add codes.
Diffstat (limited to 'MoonParser/moon_parser.cpp')
-rw-r--r--MoonParser/moon_parser.cpp508
1 files changed, 508 insertions, 0 deletions
diff --git a/MoonParser/moon_parser.cpp b/MoonParser/moon_parser.cpp
new file mode 100644
index 0000000..3069659
--- /dev/null
+++ b/MoonParser/moon_parser.cpp
@@ -0,0 +1,508 @@
1#include "moon_parser.h"
2
3rule Any = any();
4rule plain_space = *set(" \t");
5rule Break = nl(-expr('\r') >> '\n');
6rule White = *(set(" \t") | Break);
7rule Stop = Break | eof();
8rule Comment = "--" >> *(not_(set("\r\n")) >> Any) >> and_(Stop);
9rule Indent = *set(" \t");
10rule Space = plain_space >> -Comment;
11rule SomeSpace = +set(" \t") >> -Comment;
12rule SpaceBreak = Space >> Break;
13rule EmptyLine = SpaceBreak;
14rule AlphaNum = range('a', 'z') | range('A', 'Z') | range('0', '9') | '_';
15rule _Name = (range('a', 'z') | range('A', 'Z') | '_') >> *AlphaNum;
16rule SpaceName = Space >> _Name;
17rule _Num =
18 (
19 "0x" >>
20 +(range('0', '9') | range('a', 'f') | range('A', 'F')) >>
21 -(-set("uU") >> set("lL") >> set("lL"))
22 ) | (
23 +range('0', '9') >> -set("uU") >> set("lL") >> set("lL")
24 ) | (
25 (
26 (+range('0', '9') >> -('.' >> +range('0', '9'))) |
27 ('.' >> +range('0', '9'))
28 ) >> -(set("eE") >> -expr('-') >> +range('0', '9'))
29 );
30rule Num = Space >> _Num;
31rule Cut = false_();
32rule Seperator = true_();
33
34#define sym(str) (Space >> str)
35#define symx(str) expr(str)
36#define ensure(patt, finally) (((patt) >> (finally)) | ((finally) >> (Cut)))
37#define key(str) (Space >> str >> not_(AlphaNum))
38#define opWord(str) (Space >> str >> not_(AlphaNum))
39#define op(str) (Space >> str)
40
41rule Name = user(SpaceName, [](const item_t& item)
42{
43 State* st = reinterpret_cast<State*>(item.user_data);
44 for (auto it = item.begin; it != item.end; ++it) st->buffer << static_cast<char>(*it);
45 std::string name;
46 st->buffer >> name;
47 st->buffer.str("");
48 st->buffer.clear();
49 auto it = st->keywords.find(name);
50 return it == st->keywords.end();
51});
52
53rule self = expr('@');
54rule self_name = '@' >> _Name;
55rule self_class = expr("@@");
56rule self_class_name = "@@" >> _Name;
57
58rule SelfName = Space >> (self_class_name | self_class | self_name | self);
59rule KeyName = SelfName | Space >> _Name;
60rule VarArg = Space >> "...";
61
62rule check_indent = user(Indent, [](const item_t& item)
63{
64 int indent = 0;
65 for (input_it i = item.begin; i != item.end; ++i)
66 {
67 switch (*i)
68 {
69 case ' ': indent++; break;
70 case '\t': indent += 4; break;
71 }
72 }
73 State* st = reinterpret_cast<State*>(item.user_data);
74 return st->indents.top() == indent;
75});
76rule CheckIndent = and_(check_indent);
77
78rule advance = user(Indent, [](const item_t& item)
79{
80 int indent = 0;
81 for (input_it i = item.begin; i != item.end; ++i)
82 {
83 switch (*i)
84 {
85 case ' ': indent++; break;
86 case '\t': indent += 4; break;
87 }
88 }
89 State* st = reinterpret_cast<State*>(item.user_data);
90 int top = st->indents.top();
91 if (top != -1 && indent > top)
92 {
93 st->indents.push(indent);
94 return true;
95 }
96 return false;
97});
98rule Advance = and_(advance);
99
100rule push_indent = user(Indent, [](const item_t& item)
101{
102 int indent = 0;
103 for (input_it i = item.begin; i != item.end; ++i)
104 {
105 switch (*i)
106 {
107 case ' ': indent++; break;
108 case '\t': indent += 4; break;
109 }
110 }
111 State* st = reinterpret_cast<State*>(item.user_data);
112 st->indents.push(indent);
113 return true;
114});
115rule PushIndent = and_(push_indent);
116
117rule PreventIndent = user(true_(), [](const item_t& item)
118{
119 State* st = reinterpret_cast<State*>(item.user_data);
120 st->indents.push(-1);
121 return true;
122});
123
124rule PopIndent = user(true_(), [](const item_t& item)
125{
126 State* st = reinterpret_cast<State*>(item.user_data);
127 st->indents.pop();
128 return true;
129});
130
131extern rule Block;
132
133rule InBlock = Advance >> Block >> PopIndent;
134
135extern rule NameList;
136
137rule local_flag = op('*') | op('^');
138rule Local = key("local") >> (local_flag | NameList);
139
140rule colon_import_name = sym('\\') >> Name;
141rule ImportName = colon_import_name | Name;
142rule ImportNameList = Seperator >> *SpaceBreak >> ImportName >> *((+SpaceBreak | sym(',') >> *SpaceBreak) >> ImportName);
143
144extern rule Exp;
145
146rule Import = key("import") >> ImportNameList >> *SpaceBreak >> key("from") >> Exp;
147rule BreakLoop = key("break") | key("continue");
148
149extern rule ExpListLow, ExpList, Assign;
150
151rule Return = key("return") >> -ExpListLow;
152rule WithExp = ExpList >> -Assign;
153
154extern rule DisableDo, PopDo, Body;
155
156rule With = key("with") >> DisableDo >> ensure(WithExp, PopDo) >> -key("do") >> Body;
157rule SwitchCase = key("when") >> ExpList >> -key("then") >> Body;
158rule SwitchElse = key("else") >> Body;
159
160rule SwitchBlock = *EmptyLine >>
161 Advance >> Seperator >>
162 SwitchCase >>
163 *(+Break >> SwitchCase) >>
164 -(+Break >> SwitchElse) >>
165 PopIndent;
166
167rule Switch = key("switch") >>
168 DisableDo >> ensure(Exp, PopDo) >>
169 -key("do") >> -Space >> Break >> SwitchBlock;
170
171rule IfCond = Exp >> -Assign;
172rule IfElseIf = -(Break >> *EmptyLine >> CheckIndent) >> key("elseif") >> IfCond >> -key("then") >> Body;
173rule IfElse = -(Break >> *EmptyLine >> CheckIndent) >> key("else") >> Body;
174rule If = key("if") >> IfCond >> -key("then") >> Body >> Seperator >> *IfElseIf >> -IfElse;
175rule Unless = key("unless") >> IfCond >> -key("then") >> Body >> Seperator >> *IfElseIf >> -IfElse;
176
177rule While = key("while") >> DisableDo >> ensure(Exp, PopDo) >> -key("do") >> Body;
178
179rule for_step_value = sym(',') >> Exp;
180rule for_args = Name >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value;
181
182rule For = key("for") >> DisableDo >>
183 ensure(for_args, PopDo) >>
184 -key("do") >> Body;
185
186extern rule AssignableNameList;
187
188rule for_in = sym('*') >> Exp | ExpList;
189
190rule ForEach = key("for") >> AssignableNameList >> key("in") >>
191 DisableDo >> ensure(for_in, PopDo) >>
192 -key("do") >> Body;
193
194rule Do = user(key("do") >> Body, [](const item_t& item)
195{
196 State* st = reinterpret_cast<State*>(item.user_data);
197 return st->doStack.empty() || st->doStack.top();
198});
199
200rule DisableDo = user(true_(), [](const item_t& item)
201{
202 State* st = reinterpret_cast<State*>(item.user_data);
203 st->doStack.push(false);
204 return true;
205});
206
207rule PopDo = user(true_(), [](const item_t& item)
208{
209 State* st = reinterpret_cast<State*>(item.user_data);
210 st->doStack.pop();
211 return true;
212});
213
214extern rule CompInner;
215
216rule Comprehension = sym('[') >> Exp >> CompInner >> sym(']');
217rule comp_value = sym(',') >> Exp;
218rule TblComprehension = sym('{') >> (Exp >> -comp_value) >> CompInner >> sym('}');
219
220extern rule CompForEach, CompFor, CompClause;
221
222rule CompInner = (CompForEach | CompFor) >> Seperator >> *CompClause;
223rule star_exp = sym('*') >> Exp;
224rule CompForEach = key("for") >> AssignableNameList >> key("in") >> (star_exp | Exp);
225rule CompFor = key("for") >> Name >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value;
226rule CompClause = CompFor | CompForEach | key("when") >> Exp;
227
228extern rule TableBlock;
229
230rule Assign = sym('=') >> (With | If | Switch | TableBlock | ExpListLow);
231
232rule update_op =
233 sym("..=") |
234 sym("+=") |
235 sym("-=") |
236 sym("*=") |
237 sym("/=") |
238 sym("%=") |
239 sym("or=") |
240 sym("and=") |
241 sym("&=") |
242 sym("|=") |
243 sym(">>=") |
244 sym("<<=");
245
246rule Update = update_op >> Exp;
247
248rule CharOperators = Space >> set("+-*/%^><|&");
249rule WordOperators =
250 opWord("or") |
251 opWord("and") |
252 op("<=") |
253 op(">=") |
254 op("~=") |
255 op("!=") |
256 op("==") |
257 op("..") |
258 op("<<") |
259 op(">>") |
260 op("//");
261
262rule BinaryOperator = (WordOperators | CharOperators) >> *SpaceBreak;
263
264extern rule Chain;
265
266rule Assignable = Chain | Name | SelfName;
267
268extern rule Value;
269
270rule exp_op_value = BinaryOperator >> Value;
271rule Exp = Value >> *exp_op_value;
272
273extern rule Callable, InvokeArgs;
274
275rule ChainValue = (Chain | Callable) >> -InvokeArgs;
276
277extern rule KeyValue, String, SimpleValue;
278
279rule simple_table = Seperator >> KeyValue >> *(sym(',') >> KeyValue);
280rule Value = SimpleValue | simple_table | ChainValue | String;
281
282extern rule LuaString;
283
284rule single_string_inner = expr("\\'") | "\\\\" | not_(expr('\'')) >> Any;
285rule SingleString = symx('\'') >> *single_string_inner >> sym('\'');
286rule interp = symx("#{") >> Exp >> sym('}');
287rule double_string_plain = expr("\\\"") | "\\\\" | not_(expr('"')) >> Any;
288rule double_string_inner = +(not_(interp) >> double_string_plain);
289rule double_string_content = double_string_inner | interp;
290rule DoubleString = symx('"') >> Seperator >> *double_string_content >> sym('"');
291rule String = Space >> (DoubleString | SingleString | LuaString);
292
293rule lua_string_open = '[' >> *expr('=') >> '[';
294rule lua_string_close = ']' >> *expr('=') >> ']';
295
296rule LuaStringOpen = user(lua_string_open, [](const item_t& item)
297{
298 size_t count = std::distance(item.begin, item.end);
299 State* st = reinterpret_cast<State*>(item.user_data);
300 st->stringOpen = count;
301 return true;
302});
303
304rule LuaStringClose = user(lua_string_close, [](const item_t& item)
305{
306 size_t count = std::distance(item.begin, item.end);
307 State* st = reinterpret_cast<State*>(item.user_data);
308 return st->stringOpen == count;
309});
310
311rule LuaStringContent = *(not_(LuaStringClose) >> (Break | Any));
312
313rule LuaString = user(LuaStringOpen >> -Break >> LuaStringContent >> LuaStringClose, [](const item_t& item)
314{
315 State* st = reinterpret_cast<State*>(item.user_data);
316 st->stringOpen = -1;
317 return true;
318});
319
320rule Parens = sym('(') >> *SpaceBreak >> Exp >> *SpaceBreak >> sym(')');
321rule Callable = Name | SelfName | VarArg | Parens;
322rule FnArgsExpList = Exp >> *((Break | sym(',')) >> White >> Exp);
323
324rule FnArgs = Seperator >>
325(
326 (
327 symx('(') >> *SpaceBreak >> -FnArgsExpList >> *SpaceBreak >> sym(')')
328 ) | (
329 sym('!') >> not_(expr('='))
330 )
331);
332
333extern rule ChainItems, DotChainItem, ColonChain;
334
335rule chain_call = (Callable | String) >> ChainItems;
336rule chain_item = not_(set(".\\")) >> ChainItems;
337rule chain_dot_chain = DotChainItem >> -ChainItems;
338
339rule Chain =
340 chain_call |
341 chain_item |
342 Space >> (chain_dot_chain | ColonChain);
343
344extern rule ChainItem;
345
346rule chain_with_colon = +ChainItem >> -ColonChain;
347rule ChainItems = Seperator >> (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('\\') >> _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 =
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 | Exp) >> -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 = op('*') | op('^');
414rule Export = key("export") >> (ClassDecl | export_op | export_values);
415
416rule variable_pair = sym(':') >> not_(SomeSpace) >> Name;
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 = (Name | 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 = sym("->") | sym("=>");
450rule FunLit = -FnArgsDef >> fn_arrow >> -Body;
451
452rule NameList = Seperator >> Name >> *(sym(',') >> Name);
453rule NameOrDestructure = Name | 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 = Seperator >> 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('-')) >>
471 (
472 ExpList >> -(invoke_args_with_table | TableBlock) |
473 TableBlock
474 );
475
476rule const_value = key("nil") | key("true") | key("false");
477rule minus_exp = sym('-') >> not_(SomeSpace) >> Exp;
478rule sharp_exp = sym('#') >> Exp;
479rule tilde_exp = sym('~') >> Exp;
480rule not_exp = key("not") >> Exp;
481rule unary_exp = minus_exp | sharp_exp | tilde_exp | not_exp;
482
483rule SimpleValue =
484 const_value |
485 If | Unless | Switch | With | ClassDecl | ForEach | For | While | Do |
486 unary_exp |
487 TblComprehension | TableLit | Comprehension | FunLit | Num;
488
489rule Assignment = ExpList >> (Update | Assign);
490
491rule if_else_line = key("if") >> Exp >> (key("else") >> Exp | default_value);
492rule unless_line = key("unless") >> Exp;
493
494rule statement_appendix = (if_else_line | unless_line | CompInner) >> Space;
495rule Statement =
496(
497 Import | While | With | For | ForEach |
498 Switch | Return | Local | Export | BreakLoop |
499 Assignment | ExpList
500) >> Space >>
501-statement_appendix;
502
503rule Body = -Space >> Break >> *EmptyLine >> InBlock | Statement;
504
505rule empty_line_stop = Space >> and_(Stop);
506rule Line = CheckIndent >> Statement | empty_line_stop;
507rule Block = Seperator >> Line >> *(+Break >> Line);
508rule BlockEnd = Block >> eof();