aboutsummaryrefslogtreecommitdiff
path: root/MoonParser/main.cpp
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2017-07-13 16:03:11 +0800
committerLi Jin <dragon-fly@qq.com>2017-07-13 16:03:11 +0800
commitcb906e739f27931e9798510cd83725131ed55209 (patch)
tree52b465c5eb2250dec3ed3d5f02b86db79653b838 /MoonParser/main.cpp
parent975c3c7dfa032229272c3b225de1127f1605e2d2 (diff)
downloadyuescript-cb906e739f27931e9798510cd83725131ed55209.tar.gz
yuescript-cb906e739f27931e9798510cd83725131ed55209.tar.bz2
yuescript-cb906e739f27931e9798510cd83725131ed55209.zip
rewrite parsing codes with parserlib.
Diffstat (limited to 'MoonParser/main.cpp')
-rw-r--r--MoonParser/main.cpp2121
1 files changed, 502 insertions, 1619 deletions
diff --git a/MoonParser/main.cpp b/MoonParser/main.cpp
index e692732..cf7bc2d 100644
--- a/MoonParser/main.cpp
+++ b/MoonParser/main.cpp
@@ -1,1698 +1,581 @@
1//
2// main.cpp
3// PegtlStudy
4//
5// Created by Li Jin on 2017/6/16.
6// Copyright © 2017年 Li Jin. All rights reserved.
7//
8
9#include <iostream> 1#include <iostream>
2using std::cout;
3#include <string>
4using std::string;
10#include <unordered_set> 5#include <unordered_set>
11#include <vector> 6using std::unordered_set;
12#include <queue>
13#include <stack> 7#include <stack>
14#include <memory> 8using std::stack;
15#include "pegtl.hpp" 9#include <algorithm>
16#include "pegtl/analyze.hpp" 10#include <sstream>
17#include "slice.h" 11using std::stringstream;
18using namespace silly; 12#include "parserlib.hpp"
19 13using namespace parserlib;
20using namespace tao::pegtl; 14
21 15#define p(expr) user(expr, [](const item_t& item) \
22namespace helloworld // with operator precedence climbing 16{ \
17 stringstream stream; \
18 for (input_it i = item.begin; i != item.end; ++i) stream << static_cast<char>(*i); \
19 cout << #expr << ": [" << stream.str() << "]\n"; \
20 return true; \
21})
22
23struct State
23{ 24{
24 struct Stack 25 State()
25 { 26 {
26 Stack() 27 indents.push(0);
27 { 28 stringOpen = -1;
28 pushStack(); 29 }
29 } 30 size_t stringOpen;
30 void pushValue(int value) 31 stack<int> indents;
31 { 32 stack<bool> doStack;
32 _values.back().push(value); 33 unordered_set<string> keywords = {
33 } 34 "and", "while", "else", "using", "continue",
34 void pushOp(char op) 35 "local", "not", "then", "return", "from",
35 { 36 "extends", "for", "do", "or", "export",
36 _ops.back().push(op); 37 "class", "in", "unless", "when", "elseif",
37 } 38 "switch", "break", "if", "with", "import"
38 void pushStack()
39 {
40 _values.emplace_back();
41 _ops.emplace_back();
42 }
43 int getPriority(char op)
44 {
45 switch (op)
46 {
47 case '+': return 1;
48 case '-': return 1;
49 case '*': return 2;
50 case '/': return 2;
51 }
52 return 0;
53 }
54 /*
55 def compute_expr(tokenizer, min_prec):
56 atom_lhs = tokenizer.get_next_token()
57
58 while True:
59 cur = tokenizer.cur_token
60 if (cur is None or OPINFO_MAP[cur.value].prec < min_prec):
61 break
62
63 op = cur.value
64 prec, assoc = OPINFO_MAP[op]
65 next_min_prec = prec + 1 if assoc == 'LEFT' else prec
66
67 atom_rhs = compute_expr(tokenizer, next_min_prec)
68
69 atom_lhs = compute_op(op, atom_lhs, atom_rhs)
70
71 return atom_lhs
72 */
73 int parseNext(int minPrecedence)
74 {
75 int lhs = _values.back().front();
76 _values.back().pop();
77
78 while (true)
79 {
80 if (_ops.back().empty())
81 {
82 break;
83 }
84 char op = _ops.back().front();
85 if (getPriority(op) < minPrecedence)
86 {
87 break;
88 }
89 _ops.back().pop();
90 int nextMinPrecedence = getPriority(op) + 1;
91 int rhs = parseNext(nextMinPrecedence);
92 switch (op)
93 {
94 case '+':
95 std::cout << lhs << " + " << rhs << " = " << lhs+rhs << '\n';
96 lhs = lhs + rhs;
97 break;
98 case '-':
99 std::cout << lhs << " - " << rhs << " = " << lhs-rhs << '\n';
100 lhs = lhs - rhs;
101 break;
102 case '*':
103 std::cout << lhs << " * " << rhs << " = " << lhs*rhs << '\n';
104 lhs = lhs * rhs;
105 break;
106 case '/':
107 std::cout << lhs << " / " << rhs << " = " << lhs/rhs << '\n';
108 lhs = lhs / rhs;
109 break;
110 }
111 }
112 return lhs;
113 }
114 void popStack()
115 {
116 int value = parseNext(0);
117 _values.pop_back();
118 if (_values.empty())
119 {
120 _values.emplace_back();
121 }
122 _ops.pop_back();
123 if (_ops.empty())
124 {
125 _ops.emplace_back();
126 }
127 pushValue(value);
128 }
129 int getValue() const
130 {
131 return _values.back().back();
132 }
133 private:
134 std::vector<std::queue<char>> _ops;
135 std::vector<std::queue<int>> _values;
136 }; 39 };
137 40};
138 struct number : seq<opt<one<'+', '-'>>, plus<digit>> { }; 41
139 42rule Any = any();
140 struct expr; 43rule White = *set(" \t\r\n");
141 44rule plain_space = *set(" \t");
142 struct bracket : if_must<one<'('>, expr, one<')'>> { }; 45rule Break = nl(-expr('\r') >> '\n');
143 46rule Stop = Break | eof();
144 struct atomic : sor<number, bracket> { }; 47rule Comment = "--" >> *(not_(set("\r\n")) >> Any) >> and_(Stop);
145 48rule Indent = *set(" \t");
146 struct op : one<'+', '-', '*', '/'> { }; 49rule Space = plain_space >> -Comment;
147 50rule SomeSpace = +set(" \t") >> -Comment;
148 struct expr : list<atomic, op, space> { }; 51rule SpaceBreak = Space >> Break;
149 52rule EmptyLine = SpaceBreak;
150 template<typename Rule> 53rule AlphaNum = range('a', 'z') | range('A', 'Z') | range('0', '9') | '_';
151 struct action : nothing<Rule> { }; 54rule _Name = (range('a', 'z') | range('A', 'Z') | '_') >> *AlphaNum;
152 55rule SpaceName = Space >> _Name;
153 template<> 56rule _Num =
154 struct action<number> 57 (
58 "0x" >>
59 +(range('0', '9') | range('a', 'f') | range('A', 'F')) >>
60 -(-set("uU") >> set("lL") >> set("lL"))
61 ) | (
62 +range('0', '9') >> -set("uU") >> set("lL") >> set("lL")
63 ) | (
64 (
65 (+range('0', '9') >> -('.' >> +range('0', '9'))) |
66 ('.' >> +range('0', '9'))
67 ) >> -(set("eE") >> -expr('-') >> +range('0', '9'))
68 );
69rule Num = Space >> _Num;
70rule Cut = false_();
71rule Nothing = true_();
72
73#define sym(str) (Space >> str)
74#define symx(str) expr(str)
75#define ensure(patt, finally) (((patt) >> (finally)) | ((finally) >> (Cut)))
76#define key(str) (Space >> str >> not_(AlphaNum))
77#define opWord(str) (Space >> str >> not_(AlphaNum))
78#define op(str) (Space >> str)
79
80rule Name = user(SpaceName, [](const item_t& item)
81{
82 stringstream stream;
83 for (input_it i = item.begin; i != item.end; ++i) stream << static_cast<char>(*i);
84 string name;
85 stream >> name;
86 State* st = reinterpret_cast<State*>(item.user_data);
87 auto it = st->keywords.find(name);
88 return it == st->keywords.end();
89});
90
91rule self = expr('@');
92rule self_name = '@' >> _Name;
93rule self_class = expr("@@");
94rule self_class_name = "@@" >> _Name;
95
96rule SelfName = Space >> (self_class_name | self_class | self_name | self);
97rule KeyName = SelfName | Space >> _Name;
98rule VarArg = Space >> "...";
99
100rule check_indent = user(Indent, [](const item_t& item)
101{
102 int indent = 0;
103 for (input_it i = item.begin; i != item.end; ++i)
155 { 104 {
156 template<typename Input> 105 switch (*i)
157 static void apply(const Input& in, Stack& stack)
158 { 106 {
159 stack.pushValue(std::stoi(in.string())); 107 case ' ': indent++; break;
108 case '\t': indent += 4; break;
160 } 109 }
161 }; 110 }
111 State* st = reinterpret_cast<State*>(item.user_data);
112 return st->indents.top() == indent;
113});
114rule CheckIndent = and_(check_indent);
162 115
163 template<> 116rule advance = user(Indent, [](const item_t& item)
164 struct action<op> 117{
118 int indent = 0;
119 for (input_it i = item.begin; i != item.end; ++i)
165 { 120 {
166 template<typename Input> 121 switch (*i)
167 static void apply(const Input& in, Stack& stack)
168 { 122 {
169 stack.pushOp(*in.begin()); 123 case ' ': indent++; break;
124 case '\t': indent += 4; break;
170 } 125 }
171 }; 126 }
172 127 State* st = reinterpret_cast<State*>(item.user_data);
173 template<> 128 int top = st->indents.top();
174 struct action<one<'('>> 129 if (top != -1 && indent > top)
175 { 130 {
176 static void apply0(Stack& stack) 131 st->indents.push(indent);
177 { 132 return true;
178 stack.pushStack(); 133 }
179 } 134 return false;
180 }; 135});
136rule Advance = and_(advance);
181 137
182 template<> 138rule push_indent = user(Indent, [](const item_t& item)
183 struct action<expr> 139{
140 int indent = 0;
141 for (input_it i = item.begin; i != item.end; ++i)
184 { 142 {
185 template<typename Input> 143 switch (*i)
186 static void apply(const Input& in, Stack& stack)
187 { 144 {
188 stack.popStack(); 145 case ' ': indent++; break;
146 case '\t': indent += 4; break;
189 } 147 }
190 }; 148 }
149 State* st = reinterpret_cast<State*>(item.user_data);
150 st->indents.push(indent);
151 return true;
152});
153rule PushIndent = and_(push_indent);
191 154
192} // namespace hello 155rule PreventIndent = user(true_(), [](const item_t& item)
156{
157 State* st = reinterpret_cast<State*>(item.user_data);
158 st->indents.push(-1);
159 return true;
160});
193 161
194namespace moon 162rule PopIndent = user(true_(), [](const item_t& item)
195{ 163{
196 int moonType = 0; 164 State* st = reinterpret_cast<State*>(item.user_data);
165 st->indents.pop();
166 return true;
167});
197 168
198 template <class T> 169extern rule Block;
199 int MoonType()
200 {
201 static int type = moonType++;
202 return type;
203 }
204 170
205 struct Node 171rule InBlock = Advance >> Block >> PopIndent;
206 {
207 virtual ~Node() {}
208 slice::Slice token;
209 };
210 172
211 struct State 173extern rule NameList;
212 {
213 State()
214 {
215 indents.push(0);
216 stringOpen = -1;
217 astStack.emplace_back();
218 }
219 size_t stringOpen;
220 std::stack<int> indents;
221 std::stack<bool> doStack;
222 std::unordered_set<std::string> keywords =
223 {
224 "and", "while", "else", "using", "continue",
225 "local", "not", "then", "return", "from",
226 "extends", "for", "do", "or", "export",
227 "class", "in", "unless", "when", "elseif",
228 "switch", "break", "if", "with", "import"
229 };
230 std::stack<size_t> indexStack;
231 std::vector<std::vector<std::shared_ptr<Node>>> astStack;
232 };
233 174
234 struct White : star<one<' ', '\t', '\r', '\n'>> {}; 175rule Local = key("local") >> (op('*') | op('^') | NameList);
235 struct plain_space : star<one<' ', '\t'>> {};
236 struct Break : seq<opt<one<'\r'>>, one<'\n'>> {};
237 struct Stop : sor<Break, eof> {};
238 struct Comment : seq<string<'-', '-'>, star<not_at<one<'\r', '\n'>>, any>, at<Stop>> {};
239 struct Indent : star<one<' ', '\t'>> {};
240 struct Space : seq<plain_space, opt<Comment>> {};
241 struct SomeSpace : seq<plus<blank>, opt<Comment>> {};
242 struct SpaceBreak : seq<Space, Break> {};
243 typedef SpaceBreak EmptyLine;
244 struct AlphaNum : ranges<'a', 'z', 'A', 'Z', '0', '9', '_', '_'> {};
245 struct _Name : seq<ranges<'a', 'z', 'A', 'Z', '_', '_'>, star<AlphaNum>> {};
246 struct SpaceName : seq<Space, _Name> {};
247 struct _Num : sor<
248 seq<
249 string<'0' ,'x'>,
250 plus<ranges<'0', '9', 'a', 'f', 'A', 'F'>>,
251 opt<seq<
252 opt<one<'u', 'U'>>, one<'l', 'L'>, one<'l', 'L'>
253 >>
254 >,
255 seq<
256 plus<range<'0', '9'>>,
257 seq<
258 opt<one<'u', 'U'>>, one<'l', 'L'>, one<'l', 'L'>
259 >
260 >,
261 seq<
262 sor<
263 seq<
264 plus<range<'0', '9'>>,
265 opt<seq<
266 one<'.'>, plus<range<'0', '9'>>
267 >>
268 >,
269 seq<
270 one<'.'>,
271 plus<range<'0', '9'>>
272 >
273 >,
274 opt<seq<
275 one<'e', 'E'>, opt<one<'-'>>, plus<range<'0', '9'>>
276 >>
277 >
278 > {};
279 struct Num : seq<Space, _Num> {};
280
281 struct Cut : failure {};
282
283 template<char... Cs> struct sym : seq<Space, string<Cs...>> {};
284 template<char... Cs> struct symx : string<Cs...> {};
285
286 template<typename patt, typename finally>
287 struct ensure : sor<seq<patt, finally>, seq<finally, Cut>> {};
288
289 template<char... Cs> struct key : seq<Space, string<Cs...>, not_at<AlphaNum>> {};
290 template<char... Cs> struct opWord : seq<Space, string<Cs...>, not_at<AlphaNum>> {};
291 template<char... Cs> struct op : seq<Space, string<Cs...>> {};
292
293 struct Name
294 {
295 using analyze_t = analysis::generic<analysis::rule_type::ANY>;
296 176
297 template<apply_mode A, rewind_mode M, 177rule colon_import_name = sym('\\') >> Name;
298 template<typename...> class Action, 178rule ImportName = colon_import_name | Name;
299 template<typename...> class Control, 179rule ImportNameList = *SpaceBreak >> ImportName >> *((+SpaceBreak | sym(',') >> *SpaceBreak) >> ImportName);
300 typename Input>
301 static bool match(Input& in, State& st)
302 {
303 const char* current = in.current();
304 memory_input<> memIn(current, in.end() - current, current);
305 if (SpaceName::match<A, M, Action, Control>(memIn, st))
306 {
307 auto name = slice::Slice(current, memIn.current() - current);
308 auto trimed = name;
309 trimed.trimSpace();
310 auto it = st.keywords.find(trimed);
311 if (it == st.keywords.end())
312 {
313 in.bump(name.size());
314 return true;
315 }
316 }
317 return false;
318 }
319 };
320 180
321 struct self : one<'@'> {}; 181extern rule Exp;
322 struct self_name : seq<one<'@'>, _Name> {};
323 struct self_class : string<'@', '@'> {};
324 struct self_class_name : seq<string<'@', '@'>, _Name> {};
325 182
326 struct SelfName : seq<Space, sor<self_class_name, self_class, self_name, self>> {}; 183rule Import = key("import") >> ImportNameList >> *SpaceBreak >> key("from") >> Exp;
327 struct KeyName : sor<SelfName, seq<Space, _Name>> {}; 184rule BreakLoop = key("break") | key("continue");
328 struct VarArg : seq<Space, string<'.', '.', '.'>> {};
329 185
330 struct CheckIndentBump 186extern rule ExpListLow, ExpList, Assign;
331 {
332 using analyze_t = analysis::generic<analysis::rule_type::ANY>;
333 187
334 template<apply_mode A, rewind_mode M, 188rule Return = key("return") >> (ExpListLow | Nothing);
335 template<typename...> class Action, 189rule WithExp = ExpList >> -Assign;
336 template<typename...> class Control,
337 typename Input>
338 static bool match(Input& in, State& st)
339 {
340 const char* current = in.current();
341 if (Indent::match<A, M, Action, Control>(in, st))
342 {
343 int indent = 0;
344 for (const char* ch = current; ch < in.current(); ch++)
345 {
346 switch (*ch)
347 {
348 case ' ': indent++; break;
349 case '\t': indent += 4; break;
350 }
351 }
352 return st.indents.top() == indent;
353 }
354 return false;
355 }
356 };
357 struct CheckIndent : at<CheckIndentBump> {};
358 190
359 struct AdvanceBump 191extern rule DisableDo, PopDo, Body;
360 {
361 using analyze_t = analysis::generic<analysis::rule_type::ANY>;
362 192
363 template<apply_mode A, rewind_mode M, 193rule With = key("with") >> DisableDo >> ensure(WithExp, PopDo) >> -key("do") >> Body;
364 template<typename...> class Action, 194rule SwitchCase = key("when") >> ExpList >> -key("then") >> Body;
365 template<typename...> class Control, 195rule SwitchElse = key("else") >> Body;
366 typename Input>
367 static bool match(Input& in, State& st)
368 {
369 const char* current = in.current();
370 if (Indent::match<A, M, Action, Control>(in, st))
371 {
372 int indent = 0;
373 for (const char* ch = current; ch < in.current(); ch++)
374 {
375 switch (*ch)
376 {
377 case ' ': indent++; break;
378 case '\t': indent += 4; break;
379 }
380 }
381 int top = st.indents.top();
382 if (top != -1 && indent > top)
383 {
384 st.indents.push(indent);
385 return true;
386 }
387 return false;
388 }
389 return false;
390 }
391 };
392 struct Advance : at<AdvanceBump> {};
393 196
394 struct PushIndentBump 197rule SwitchBlock = *EmptyLine >>
395 { 198 Advance >>
396 using analyze_t = analysis::generic<analysis::rule_type::ANY>; 199 SwitchCase >>
200 *(+Break >> SwitchCase) >>
201 -(+Break >> SwitchElse) >>
202 PopIndent;
397 203
398 template<apply_mode A, rewind_mode M, 204rule Switch = key("switch") >>
399 template<typename...> class Action, 205 DisableDo >> ensure(Exp, PopDo) >>
400 template<typename...> class Control, 206 -key("do") >> -Space >> Break >> SwitchBlock;
401 typename Input>
402 static bool match(Input& in, State& st)
403 {
404 const char* current = in.current();
405 if (Indent::match<A, M, Action, Control>(in, st))
406 {
407 int indent = 0;
408 for (const char* ch = current; ch < in.current(); ch++)
409 {
410 switch (*ch)
411 {
412 case ' ': indent++; break;
413 case '\t': indent += 4; break;
414 }
415 }
416 st.indents.push(indent);
417 return true;
418 }
419 return false;
420 }
421 };
422 struct PushIndent : at<PushIndentBump> {};
423 207
424 struct PreventIndentBump 208rule IfCond = Exp >> -Assign;
425 { 209rule IfElseIf = -(Break >> *EmptyLine >> CheckIndent) >> key("elseif") >> IfCond >> -key("then") >> Body;
426 using analyze_t = analysis::generic<analysis::rule_type::ANY>; 210rule IfElse = -(Break >> *EmptyLine >> CheckIndent) >> key("else") >> Body;
211rule If = key("if") >> IfCond >> -key("then") >> Body >> *IfElseIf >> -IfElse;
212rule Unless = key("unless") >> IfCond >> -key("then") >> Body >> *IfElseIf >> -IfElse;
427 213
428 template<apply_mode A, rewind_mode M, 214rule While = key("while") >> DisableDo >> ensure(Exp, PopDo) >> -key("do") >> Body;
429 template<typename...> class Action,
430 template<typename...> class Control,
431 typename Input>
432 static bool match(Input& in, State& st)
433 {
434 st.indents.push(-1);
435 return true;
436 }
437 };
438 struct PreventIndent : at<PreventIndentBump> {};
439 215
440 struct PopIndentBump 216rule for_args = Name >> sym('=') >> Exp >> sym(',') >> Exp >> (sym(',') >> Exp | Nothing);
441 {
442 using analyze_t = analysis::generic<analysis::rule_type::ANY>;
443 217
444 template<apply_mode A, rewind_mode M, 218rule For = key("for") >> DisableDo >>
445 template<typename...> class Action, 219 ensure(for_args, PopDo) >>
446 template<typename...> class Control, 220 -key("do") >> Body;
447 typename Input>
448 static bool match(Input& in, State& st)
449 {
450 st.indents.pop();
451 return true;
452 }
453 };
454 struct PopIndent : at<PopIndentBump> {};
455
456 struct Block;
457
458 struct InBlock : seq<Advance, Block, PopIndent> {};
459
460 struct NameList;
461
462 struct Local : seq<
463 key<'l', 'o', 'c', 'a', 'l'>,
464 sor<
465 sor<op<'*'>, op<'^'>>,
466 NameList
467 >
468 > {};
469
470 struct colon_import_name : seq<sym<'\\'>, Name> {};
471 struct ImportName : sor<colon_import_name, Name> {};
472 struct ImportNameList : seq<
473 star<SpaceBreak>,
474 ImportName,
475 star<
476 sor<
477 plus<SpaceBreak>,
478 seq<sym<','>, star<SpaceBreak>>
479 >,
480 ImportName
481 >
482 > {};
483
484 struct Exp;
485
486 struct Import : seq<key<'i', 'm', 'p', 'o', 'r', 't'>, ImportNameList, star<SpaceBreak>, key<'f', 'r', 'o', 'm'>, Exp> {};
487
488 struct BreakLoop : sor<key<'b', 'r', 'e', 'a', 'k'>, key<'c', 'o', 'n', 't', 'i', 'n', 'u', 'e'>> {};
489
490 struct ExpListLow;
491
492 struct ExpList;
493 struct Assign;
494
495 struct Return : seq<key<'r', 'e', 't', 'u', 'r', 'n'>, sor<ExpListLow, success>> {};
496 struct WithExp : seq<ExpList, opt<Assign>> {};
497
498 struct DisableDo;
499 struct PopDo;
500 struct Body;
501
502 struct With : seq<key<'w', 'i', 't', 'h'>, DisableDo, ensure<WithExp, PopDo>, opt<key<'d', 'o'>>, Body> {};
503
504 struct SwitchCase : seq<key<'w', 'h', 'e', 'n'>, ExpList, opt<key<'t', 'h', 'e', 'n'>>, Body> {};
505 struct SwitchElse : seq<key<'e', 'l', 's', 'e'>, Body> {};
506 struct SwitchBlock : seq<
507 star<EmptyLine>,
508 Advance,
509 seq<
510 SwitchCase,
511 star<plus<Break>, SwitchCase>,
512 opt<plus<Break>, SwitchElse>
513 >,
514 PopIndent
515 > {};
516 struct Switch : seq<key<'s', 'w', 'i', 't', 'c', 'h'>, DisableDo, ensure<Exp, PopDo>, opt<key<'d', 'o'>>, opt<Space>, Break, SwitchBlock> {};
517
518 struct IfCond : seq<Exp, opt<Assign>> {};
519
520 struct IfElse : seq<
521 opt<Break, star<EmptyLine>, CheckIndent>,
522 key<'e', 'l', 's', 'e'>, Body
523 > {};
524
525 struct IfElseIf : seq<
526 opt<Break, star<EmptyLine>, CheckIndent>,
527 key<'e', 'l', 's', 'e', 'i', 'f'>, IfCond,
528 opt<key<'t', 'h', 'e', 'n'>>, Body
529 > {};
530
531 struct If : seq<key<'i', 'f'>, IfCond, opt<key<'t', 'h', 'e', 'n'>>, Body, star<IfElseIf>, opt<IfElse>> {};
532 struct Unless : seq<key<'u', 'n', 'l', 'e', 's', 's'>, IfCond, opt<key<'t', 'h', 'e', 'n'>>, Body, star<IfElseIf>, opt<IfElse>> {};
533
534 struct While : seq<key<'w', 'h', 'i', 'l', 'e'>, DisableDo, ensure<Exp, PopDo>, opt<key<'d','o'>>, Body> {};
535 struct For : seq<key<'f', 'o', 'r'>, DisableDo,
536 ensure<
537 seq<
538 Name, sym<'='>,
539 seq<Exp, sym<','>, Exp, opt<sym<','>, Exp>>
540 >,
541 PopDo
542 >,
543 opt<key<'d', 'o'>>, Body> {};
544
545 struct AssignableNameList;
546
547 struct ForEach : seq<
548 key<'f', 'o', 'r'>,
549 AssignableNameList,
550 key<'i', 'n'>,
551 DisableDo,
552 ensure<
553 sor<
554 seq<sym<'*'>, Exp>, ExpList
555 >,
556 PopDo
557 >,
558 opt<key<'d', 'o'>>,
559 Body
560 > {};
561
562 struct Do
563 {
564 using analyze_t = analysis::generic<analysis::rule_type::ANY>;
565 221
566 template<apply_mode A, rewind_mode M, 222extern rule AssignableNameList;
567 template<typename...> class Action,
568 template<typename...> class Control,
569 typename Input>
570 static bool match(Input& in, State& st)
571 {
572 if (at<seq<key<'d', 'o'>, Body>>::match<A, M, Action, Control>(in, st))
573 {
574 if (st.doStack.empty() || st.doStack.top())
575 {
576 return true;
577 }
578 }
579 return false;
580 }
581 };
582 223
583 struct DisableDo 224rule for_in = sym('*') >> Exp | ExpList;
584 {
585 using analyze_t = analysis::generic<analysis::rule_type::ANY>;
586 225
587 template<apply_mode A, rewind_mode M, 226rule ForEach = key("for") >> AssignableNameList >> key("in") >>
588 template<typename...> class Action, 227 DisableDo >> ensure(for_in, PopDo) >>
589 template<typename...> class Control, 228 -key("do") >> Body;
590 typename Input>
591 static bool match(Input& in, State& st)
592 {
593 st.doStack.push(false);
594 return true;
595 }
596 };
597 229
598 struct PopDo 230rule Do = user(key("do") >> Body, [](const item_t& item)
599 { 231{
600 using analyze_t = analysis::generic<analysis::rule_type::ANY>; 232 State* st = reinterpret_cast<State*>(item.user_data);
233 return st->doStack.empty() || st->doStack.top();
234});
601 235
602 template<apply_mode A, rewind_mode M, 236rule DisableDo = user(true_(), [](const item_t& item)
603 template<typename...> class Action, 237{
604 template<typename...> class Control, 238 State* st = reinterpret_cast<State*>(item.user_data);
605 typename Input> 239 st->doStack.push(false);
606 static bool match(Input& in, State& st) 240 return true;
607 { 241});
608 st.doStack.pop();
609 return true;
610 }
611 };
612 242
613 struct CompInner; 243rule PopDo = user(true_(), [](const item_t& item)
614 244{
615 struct Comprehension : seq<sym<'['>, Exp, CompInner, sym<']'>> {}; 245 State* st = reinterpret_cast<State*>(item.user_data);
616 struct TblComprehension : seq<sym<'{'>, seq<Exp, opt<sym<','>, Exp>>, CompInner, sym<'}'>> {}; 246 st->doStack.pop();
617 247 return true;
618 struct CompForEach; 248});
619 struct CompFor;
620 struct CompClause;
621
622 struct CompInner : seq<sor<CompForEach, CompFor>, star<CompClause>> {};
623 struct CompForEach : seq<
624 key<'f', 'o', 'r'>,
625 AssignableNameList,
626 key<'i', 'n'>,
627 sor<
628 seq<sym<'*'>, Exp>, Exp
629 >
630 > {};
631 struct CompFor : seq<key<'f', 'o', 'r'>, Name, sym<'='>, seq<Exp, sym<','>, Exp, opt<sym<','>, Exp>>> {};
632 struct CompClause : sor<CompFor, CompForEach, seq<key<'w', 'h', 'e', 'n'>, Exp>> {};
633
634 struct TableBlock;
635
636 struct Assign : seq<sym<'='>, sor<With, If, Switch, TableBlock, ExpListLow>> {};
637
638 struct Update : seq<sor<
639 sym<'.', '.', '='>,
640 sym<'+', '='>,
641 sym<'-', '='>,
642 sym<'*', '='>,
643 sym<'/', '='>,
644 sym<'%', '='>,
645 sym<'o', 'r', '='>,
646 sym<'a', 'n', 'd', '='>,
647 sym<'&', '='>,
648 sym<'|', '='>,
649 sym<'>', '>', '='>,
650 sym<'<', '<', '='>
651 >, Exp> {};
652
653 struct CharOperators : seq<Space, one<'+', '-', '*' ,'/', '%', '^', '>', '<', '|', '&'>> {};
654 struct WordOperators : sor<
655 opWord<'o', 'r'>,
656 opWord<'a', 'n', 'd'>,
657 op<'<', '='>,
658 op<'>', '='>,
659 op<'~', '='>,
660 op<'!', '='>,
661 op<'=', '='>,
662 op<'.', '.'>,
663 op<'<', '<'>,
664 op<'>', '>'>,
665 op<'/', '/'>> {};
666 struct BinaryOperator : seq<sor<WordOperators, CharOperators>, star<SpaceBreak>> {};
667
668 struct Chain;
669
670 struct Assignable : sor<at<Chain>, Name, SelfName> {};
671
672 struct Value;
673
674 struct Exp : seq<Value, star<BinaryOperator, Value>> {};
675
676 struct Callable;
677 struct InvokeArgs;
678
679 struct ChainValue : seq<sor<Chain, Callable>, opt<InvokeArgs>> {};
680
681 struct KeyValueList;
682 struct String;
683 struct SimpleValue;
684
685 struct Value : sor<SimpleValue, KeyValueList, ChainValue, String> {};
686 struct SliceValue : Exp {};
687
688 struct LuaString;
689
690 struct single_string_inner : sor<string<'\\', '\''>, string<'\\', '\\'>, not_one<'\''>> {};
691 struct SingleString : seq<symx<'\''>, star<single_string_inner>, sym<'\''>> {};
692 struct interp : seq<symx<'#', '{'>, Exp, sym<'}'>> {};
693 struct double_string_plain : sor<string<'\\', '\"'>, string<'\\', '\\'>, not_one<'\"'>> {};
694 struct double_string_inner : plus<seq<not_at<interp>, double_string_plain>> {};
695 struct DoubleString : seq<symx<'\"'>, star<sor<double_string_inner, interp>>, sym<'\"'>> {};
696 struct String : sor<seq<Space, DoubleString>, seq<Space, SingleString>, LuaString> {};
697
698 struct lua_string_open : seq<one<'['>, star<one<'='>>, one<'['>> {};
699 struct lua_string_close : seq<one<']'>, star<one<'='>>, one<']'>> {};
700
701 struct LuaStringOpen
702 {
703 using analyze_t = analysis::generic<analysis::rule_type::ANY>;
704 249
705 template<apply_mode A, rewind_mode M, 250extern rule CompInner;
706 template<typename...> class Action,
707 template<typename...> class Control,
708 typename Input>
709 static bool match(Input& in, State& st)
710 {
711 const char* current = in.current();
712 if (lua_string_open::match<A, M, Action, Control>(in, st))
713 {
714 st.stringOpen = in.current() - current + 1;
715 return true;
716 }
717 return false;
718 }
719 };
720 251
721 struct LuaStringClose 252rule Comprehension = sym('[') >> Exp >> CompInner >> sym(']');
722 { 253rule TblComprehension = sym('{') >> (Exp >> -(sym(',') >> Exp)) >> CompInner >> sym('}');
723 using analyze_t = analysis::generic<analysis::rule_type::ANY>;
724 254
725 template<apply_mode A, rewind_mode M, 255extern rule CompForEach, CompFor, CompClause;
726 template<typename...> class Action,
727 template<typename...> class Control,
728 typename Input>
729 static bool match(Input& in, State& st)
730 {
731 const char* current = in.current();
732 if (lua_string_close::match<A, M, Action, Control>(in, st))
733 {
734 return st.stringOpen == in.current() - current + 1;
735 }
736 return false;
737 }
738 };
739 256
740 struct LuaStringContent : star<not_at<LuaStringClose>, any> {}; 257rule CompInner = (CompForEach | CompFor) >> *CompClause;
258rule CompForEach = key("for") >> AssignableNameList >> key("in") >> (sym('*') >> Exp | Exp);
259rule CompFor = key("for") >> Name >> sym('=') >> Exp >> sym(',') >> Exp >> (sym(',') >> Exp | Nothing);
260rule CompClause = CompFor | CompForEach | key("when") >> Exp;
741 261
742 struct LuaString 262extern rule TableBlock;
743 {
744 using analyze_t = analysis::generic<analysis::rule_type::ANY>;
745 263
746 template<apply_mode A, rewind_mode M, 264rule Assign = sym('=') >> (With | If | Switch | TableBlock | ExpListLow);
747 template<typename...> class Action,
748 template<typename...> class Control,
749 typename Input>
750 static bool match(Input& in, State& st)
751 {
752 bool result = seq<LuaStringOpen, opt<Break>, LuaStringContent, LuaStringClose>::match<A, M, Action, Control>(in, st);
753 st.stringOpen = -1;
754 return result;
755 }
756 };
757 265
758 struct Parens : seq<sym<'('>, star<SpaceBreak>, Exp, star<SpaceBreak>, sym<')'>> {}; 266rule Update =
759 struct Callable : sor<Name, SelfName, VarArg, Parens> {}; 267(
760 268 sym("..=") |
761 struct FnArgsExpList : seq< 269 sym("+=") |
762 Exp, 270 sym("-=") |
763 star< 271 sym("*=") |
764 sor<Break, sym<','>>, 272 sym("/=") |
765 White, Exp 273 sym("%=") |
766 > 274 sym("or=") |
767 > {}; 275 sym("and=") |
768 276 sym("&=") |
769 struct FnArgs : sor< 277 sym("|=") |
770 seq<symx<'('>, star<SpaceBreak>, opt<FnArgsExpList>, star<SpaceBreak>, sym<')'>>, 278 sym(">>=") |
771 seq<sym<'!'>, not_at<one<'='>>> 279 sym("<<=")
772 > {}; 280) >> Exp;
773
774 struct ChainItems;
775 struct DotChainItem;
776 struct ColonChain;
777
778 struct Chain : sor<
779 seq<
780 sor<Callable, String, not_at<one<'.', '\\'>>>,
781 ChainItems
782 >,
783 seq<Space,
784 sor<
785 seq<DotChainItem, opt<ChainItems>>,
786 ColonChain
787 >
788 >
789 > {};
790
791 struct ChainItem;
792
793 struct ChainItems : sor<
794 seq<plus<ChainItem>, opt<ColonChain>>,
795 ColonChain
796 > {};
797
798 struct Invoke;
799 struct Slice;
800
801 struct ChainItem : sor<
802 Invoke,
803 DotChainItem,
804 Slice,
805 seq<symx<'['>, Exp, sym<']'>>
806 > {};
807
808 struct DotChainItem : seq<symx<'.'>, _Name> {};
809 struct ColonChainItem : seq<symx<'\\'>, _Name> {};
810 struct ColonChain : seq<
811 ColonChainItem,
812 opt<Invoke, opt<ChainItems>>
813 > {};
814
815 struct SliceOne : success {};
816 struct SliceTwo : success {};
817 struct Slice : seq<
818 symx<'['>, sor<SliceValue, SliceOne>, sym<','>, sor<SliceValue, SliceTwo>, opt<sym<','>, SliceValue>, sym<']'>> {};
819
820 struct Invoke : sor<
821 FnArgs,
822 SingleString,
823 DoubleString,
824 seq<at<one<'['>>, LuaString>
825 > {};
826
827 struct KeyValue;
828 struct TableValueList;
829 struct TableLitLine;
830
831 struct TableValue : sor<KeyValue, Exp> {};
832 struct TableLit : seq<
833 sym<'{'>,
834 seq<
835 opt<TableValueList>, opt<sym<','>>,
836 opt<
837 SpaceBreak, TableLitLine,
838 star<opt<sym<','>>, SpaceBreak, TableLitLine>,
839 opt<sym<','>>
840 >
841 >,
842 White, sym<'}'>
843 > {};
844
845 struct TableValueList : seq<TableValue, star<sym<','>, TableValue>> {};
846 struct TableLitLine : sor<
847 seq<PushIndent, sor<seq<TableValueList, PopIndent>, seq<PopIndent, Cut>>>,
848 Space
849 > {};
850
851 struct KeyValueLine;
852
853 struct TableBlockInner : seq<KeyValueLine, star<plus<SpaceBreak>, KeyValueLine>> {};
854 struct TableBlock : seq<plus<SpaceBreak>, Advance, ensure<TableBlockInner, PopIndent>> {};
855
856 struct Statement;
857
858 struct ClassLine : seq<
859 CheckIndent,
860 seq<
861 sor<KeyValueList, Statement, Exp>,
862 opt<sym<','>>
863 >
864 > {};
865
866 struct ClassBlock : seq<plus<SpaceBreak>, Advance, ClassLine, star<plus<SpaceBreak>, ClassLine>, PopIndent> {};
867
868 struct class_no_derive : success {};
869 struct class_no_extend : success {};
870 struct class_no_body : success {};
871 struct ClassDecl : seq<
872 string<'c', 'l', 'a', 's', 's'>,
873 not_at<one<':'>>,
874 sor<Assignable, class_no_derive>,
875 opt<sor<string<'e', 'x', 't', 'e', 'n', 'd', 's'>, PreventIndent, ensure<Exp, PopIndent>, class_no_extend>>,
876 sor<ClassBlock, class_no_body>
877 > {};
878
879 struct Export : seq<
880 string<'e', 'x', 'p', 'o', 'r', 't'>,
881 sor<
882 ClassDecl,
883 op<'*'>,
884 op<'^'>,
885 seq<NameList, opt<sym<'='>, ExpListLow>>
886 >
887 > {};
888
889 struct KeyValue : sor<
890 seq<sym<':'>, not_at<SomeSpace>, Name>,
891 seq<
892 sor<
893 KeyName,
894 seq<sym<'['>, Exp, sym<']'>>,
895 seq<Space, DoubleString>,
896 seq<Space, SingleString>
897 >,
898 symx<':'>,
899 sor<
900 Exp, TableBlock, seq<plus<SpaceBreak>, Exp>
901 >
902 >
903 > {};
904
905 struct KeyValueList : seq<KeyValue, star<sym<','>, KeyValue>> {};
906 struct KeyValueLine : seq<CheckIndent, KeyValueList, opt<sym<','>>> {};
907
908 struct FnArgDef : seq<sor<Name, SelfName>, opt<sym<'='>, Exp>> {};
909
910 struct FnArgDefList : sor<
911 seq<
912 FnArgDef,
913 star<sor<sym<','>, Break>, White, FnArgDef>,
914 star<sor<sym<','>, Break>, White, VarArg>
915 >,
916 VarArg
917 > {};
918
919 struct outer_value_shadow : seq<string<'u', 's', 'i', 'n', 'g'>, sor<NameList, seq<Space, string<'n', 'i', 'l'>>>> {};
920 struct outer_value_no_shadow : success {};
921 struct without_args_def : success {};
922
923 struct FnArgsDef : sor<
924 seq<sym<'('>, White, opt<FnArgDefList>,
925 sor<
926 outer_value_shadow,
927 outer_value_no_shadow
928 >,
929 White, sym<')'>
930 >,
931 without_args_def
932 > {};
933
934 struct FunLit : seq<
935 FnArgsDef,
936 sor<
937 sym<'-', '>'>,
938 sym<'=', '>'>
939 >,
940 sor<Body, success>
941 > {};
942
943 struct NameList : seq<Name, star<sym<','>, Name>> {};
944 struct NameOrDestructure : sor<Name, TableLit> {};
945 struct AssignableNameList : seq<NameOrDestructure, star<sym<','>, NameOrDestructure>> {};
946
947 struct ExpList : seq<Exp, star<sym<','>, Exp>> {};
948 struct ExpListLow : seq<Exp, star<sor<sym<','>, sym<';'>>, Exp>> {};
949
950 struct ArgLine : seq<CheckIndent, ExpList> {};
951 struct ArgBlock : seq<ArgLine, star<sym<','>, SpaceBreak, ArgLine>, PopIndent> {};
952
953 struct InvokeArgs : seq<
954 not_at<one<'-'>>,
955 sor<
956 seq<
957 ExpList,
958 opt<sor<
959 seq<
960 sym<','>,
961 sor<
962 TableBlock, seq<SpaceBreak, Advance, ArgBlock, opt<TableBlock>>
963 >
964 >,
965 TableBlock
966 >>
967 >,
968 TableBlock
969 >
970 > {};
971
972 struct SimpleValue : sor<
973 key<'n', 'i', 'l'>,
974 key<'t', 'r', 'u', 'e'>,
975 key<'f', 'a', 'l', 's', 'e'>,
976 If, Unless, Switch, With, ClassDecl, ForEach, For, While, Do,
977 seq<sym<'-'>, not_at<SomeSpace>, Exp>,
978 seq<sym<'#'>, Exp>,
979 seq<sym<'~'>, Exp>,
980 seq<key<'n', 'o', 't'>, Exp>,
981 TblComprehension,
982 TableLit,
983 Comprehension,
984 FunLit,
985 Num
986 > {};
987
988 struct Assignment : seq<
989 ExpList,
990 sor<Update, Assign>
991 > {};
992
993 struct Statement : seq<
994 sor<
995 Import, While, With, For, ForEach,
996 Switch, Return, Local, Export, BreakLoop,
997 Assignment, ExpList
998 >,
999 Space,
1000 opt<
1001 sor<
1002 seq<
1003 key<'i', 'f'>, Exp,
1004 opt<
1005 key<'e', 'l', 's', 'e'>, Exp
1006 >,
1007 Space
1008 >,
1009 seq<key<'u', 'n', 'l', 'e', 's', 's'>, Exp>,
1010 CompInner
1011 >,
1012 Space
1013 >
1014 > {};
1015
1016 struct Body : sor<
1017 seq<opt<Space>, Break, star<EmptyLine>, InBlock>,
1018 Statement
1019 > {};
1020
1021 struct Line : sor<
1022 seq<CheckIndent, Statement>,
1023 seq<Space, at<Stop>>
1024 > {};
1025
1026 struct Block : seq<Line, star<plus<Break>, Line>> {};
1027
1028 struct BlockWithEnd : seq<Block, eof> {};
1029
1030 template <class T>
1031 struct NodeBase : Node
1032 {
1033 static int id;
1034 };
1035 281
1036 template <class T> 282rule CharOperators = Space >> set("+-*/%^><|&");
1037 int NodeBase<T>::id = MoonType<T>(); 283rule WordOperators =
284 opWord("or") |
285 opWord("and") |
286 op("<=") |
287 op(">=") |
288 op("~=") |
289 op("!=") |
290 op("==") |
291 op("..") |
292 op("<<") |
293 op(">>") |
294 op("//");
1038 295
1039 struct ImportNameNode : Node 296rule BinaryOperator = (WordOperators | CharOperators) >> *SpaceBreak;
1040 {
1041 };
1042 297
1043 struct ImportNameListNode : NodeBase<ImportNameListNode> 298extern rule Chain;
1044 {
1045 std::vector<std::shared_ptr<Node>> names;
1046 };
1047 299
1048 struct ImportNode : NodeBase<ImportNode> 300rule Assignable = Chain | Name | SelfName;
1049 {
1050 std::shared_ptr<Node> nameList;
1051 std::shared_ptr<Node> exp;
1052 };
1053 301
1054 template<typename Rule> 302extern rule Value;
1055 struct action : nothing<Rule> {};
1056 303
1057 template<> 304rule Exp = Value >> *(BinaryOperator >> Value);
1058 struct action<ImportName>
1059 {
1060 template<typename Input>
1061 static void apply(const Input& in, State& st)
1062 {
1063 auto node = std::make_shared<ImportNameNode>();
1064 node->token = slice::Slice(in.begin(), in.end() - in.begin());
1065 node->token.trimSpace();
1066 st.astStack.pop_back();
1067 st.astStack.back().push_back(node);
1068 }
1069 };
1070 305
1071 template<> 306extern rule Callable, InvokeArgs;
1072 struct action<Exp>
1073 {
1074 template<typename Input>
1075 static void apply(const Input& in, State& st)
1076 {
1077 auto node = std::make_shared<Node>();
1078 node->token = slice::Slice(in.begin(), in.end() - in.begin());
1079 node->token.trimSpace();
1080 st.astStack.pop_back();
1081 st.astStack.back().push_back(node);
1082 }
1083 };
1084 307
1085 template<> 308rule ChainValue = (Chain | Callable) >> (InvokeArgs | Nothing);
1086 struct action<Import>
1087 {
1088 template<typename Input>
1089 static void apply(const Input& in, State& st)
1090 {
1091 auto node = std::make_shared<ImportNode>();
1092 node->exp = st.astStack.back().back();
1093 st.astStack.back().pop_back();
1094 node->nameList = st.astStack.back().back();
1095 st.astStack.back().pop_back();
1096 st.astStack.pop_back();
1097 st.astStack.back().push_back(node);
1098 }
1099 };
1100 309
1101 template<> 310extern rule KeyValueList, String, SimpleValue;
1102 struct action<ImportNameListNode>
1103 {
1104 template<typename Input>
1105 static void apply(const Input& in, State& st)
1106 {
1107 auto node = std::make_shared<ImportNameListNode>();
1108 node->names = std::move(st.astStack.back());
1109 st.astStack.pop_back();
1110 st.astStack.back().push_back(node);
1111 }
1112 };
1113 311
1114 template<typename Rule> 312rule Value = SimpleValue | KeyValueList | ChainValue | String;
1115 struct control : normal<Rule> {}; 313rule SliceValue = Exp;
1116 314
1117 template<> 315extern rule LuaString;
1118 struct control<ImportNameListNode> : normal<ImportNameListNode>
1119 {
1120 template<typename Input>
1121 static void start(Input& in, State& st)
1122 {
1123 st.astStack.emplace_back();
1124 }
1125 316
1126 template<typename Input> 317rule single_string_inner = expr("\\'") | "\\\\" | not_(expr('\'')) >> Any;
1127 static void failure(Input& /*unused*/, State& st) 318rule SingleString = symx('\'') >> *single_string_inner >> sym('\'');
1128 { 319rule interp = symx("#{") >> Exp >> sym('}');
1129 st.astStack.pop_back(); 320rule double_string_plain = expr("\\\"") | "\\\\" | not_(expr('"')) >> Any;
1130 } 321rule double_string_inner = +(not_(interp) >> double_string_plain);
322rule DoubleString = symx('"') >> *(double_string_inner | interp) >> sym('"');
323rule String = Space >> (DoubleString | SingleString | LuaString);
1131 324
1132 template<typename Input> 325rule lua_string_open = '[' >> *expr('=') >> '[';
1133 static void success(Input& /*unused*/, State& st) 326rule lua_string_close = ']' >> *expr('=') >> ']';
1134 {
1135 }
1136 };
1137}
1138 327
1139int main() 328rule LuaStringOpen = user(lua_string_open, [](const item_t& item)
1140{ 329{
1141 analyze<moon::BlockWithEnd>(); 330 size_t count = std::distance(item.begin, item.end);
1142 moon::State state; 331 State* st = reinterpret_cast<State*>(item.user_data);
1143 string_input<> inName(R"xoxox( 332 st->stringOpen = count;
1144 333 return true;
1145Dorothy! 334});
1146EditMenuView = require "View.Control.Operation.EditMenu" 335
1147MessageBox = require "Control.Basic.MessageBox" 336rule LuaStringClose = user(lua_string_close, [](const item_t& item)
1148 337{
1149-- [no signals] 338 size_t count = std::distance(item.begin, item.end);
1150-- [no params] 339 State* st = reinterpret_cast<State*>(item.user_data);
1151Class EditMenuView, 340 return st->stringOpen == count;
1152 __init:=> 341});
1153 {:width} = CCDirector.winSize 342
1154 isHide = false 343rule LuaStringContent = *(not_(LuaStringClose) >> Any);
1155
1156 @itemArea\setupMenuScroll @itemMenu
1157 @itemArea.viewSize = @itemMenu\alignItems!
1158
1159 for child in *@itemMenu.children
1160 child.positionX = -35
1161 child.visible = false
1162 child.displayed = false
1163 @showItemButtons {"graphic","physics","logic","data"},true,true
1164
1165 buttonNames = {
1166 "sprite","model","body"
1167 "effect","layer","world"
1168 }
1169 344
1170 clearSelection = -> 345rule LuaString = user(LuaStringOpen >> -Break >> LuaStringContent >> LuaStringClose, [](const item_t& item)
1171 for name in *buttonNames 346{
1172 with @[name.."Btn"] 347 State* st = reinterpret_cast<State*>(item.user_data);
1173 if .selected 348 st->stringOpen = -1;
1174 .selected = false 349 return true;
1175 .color = ccColor3 0x00ffff 350});
1176 .scaleX = 0 351
1177 .scaleY = 0 352rule Parens = sym('(') >> *SpaceBreak >> Exp >> *SpaceBreak >> sym(')');
1178 \perform oScale 0.3,1,1,oEase.OutBack 353rule Callable = Name | SelfName | VarArg | Parens;
1179 emit .event,nil 354rule FnArgsExpList = Exp >> *((Break | sym(',')) >> White >> Exp);
1180 355
1181 for name in *buttonNames 356rule FnArgs =
1182 with @[name.."Btn"] 357(
1183 .selected = false 358 symx('(') >> *SpaceBreak >> (FnArgsExpList | Nothing) >> *SpaceBreak >> sym(')')
1184 upperName = name\sub(1,1)\upper!..name\sub(2,-1) 359) | (
1185 .event = "Scene."..upperName.."Selected" 360 sym('!') >> not_(expr('=')) >> Nothing
1186 @gslot .event,(item)-> 361);
1187 if item 362
1188 .selected = true 363extern rule ChainItems, DotChainItem, ColonChain;
1189 .color = ccColor3 0xff0088 364
1190 .scaleX = 0 365rule chain_call = (Callable | String) >> ChainItems;
1191 .scaleY = 0 366rule chain_item = not_(set(".\\")) >> ChainItems;
1192 \perform oScale 0.3,1,1,oEase.OutBack 367rule chain_dot_chain = DotChainItem >> (ChainItems | Nothing);
1193 \slot "Tapped",-> 368
1194 if not .selected 369rule Chain =
1195 emit "Scene.View"..upperName 370 chain_call |
1196 clearSelection! 371 chain_item |
1197 else 372 Space >> (chain_dot_chain | ColonChain);
1198 .selected = false 373
1199 .color = ccColor3 0x00ffff 374extern rule ChainItem;
1200 emit .event,nil 375
1201 376rule chain_items = +ChainItem >> (ColonChain | Nothing);
1202 @triggerBtn\slot "Tapped",-> 377rule ChainItems = chain_items | ColonChain;
1203 clearSelection! 378
1204 if @pickPanel.visible 379extern rule Invoke, Slice;
1205 MessageBox text:"Pick An Item First",okOnly:true 380
1206 else 381rule ChainItem = Invoke | DotChainItem | Slice | symx('[') >> Exp >> sym(']');
1207 emit "Scene.Trigger.Open" 382rule DotChainItem = symx('.') >> _Name;
1208 383rule ColonChainItem = symx('\\') >> _Name;
1209 @actionBtn\slot "Tapped",-> 384rule ColonChain = ColonChainItem >> ((Invoke >> (ChainItems | Nothing)) | Nothing >> Nothing);
1210 clearSelection! 385
1211 if @pickPanel.visible 386rule Slice =
1212 MessageBox text:"Pick An Item First",okOnly:true 387 symx('[') >>
1213 else 388 (SliceValue | Nothing) >>
1214 emit "Scene.Action.Open" 389 sym(',') >>
1215 390 (SliceValue | Nothing) >>
1216 @aiBtn\slot "Tapped",-> 391 (sym(',') >>
1217 clearSelection! 392 SliceValue | Nothing) >>
1218 if @pickPanel.visible 393 sym(']');
1219 MessageBox text:"Pick An Item First",okOnly:true 394
1220 else 395rule Invoke =
1221 emit "Scene.AITree.Open" 396 FnArgs |
1222 397 SingleString |
1223 @unitBtn\slot "Tapped",-> 398 DoubleString |
1224 clearSelection! 399 and_(expr('[')) >> LuaString;
1225 if @pickPanel.visible 400
1226 MessageBox text:"Pick An Item First",okOnly:true 401extern rule KeyValue, TableValueList, TableLitLine;
1227 else 402
1228 emit "Scene.Unit.Open" 403rule TableValue = KeyValue | Exp;
1229 404
1230 @delBtn\slot "Tapped",-> 405rule table_lit_lines = SpaceBreak >> TableLitLine >> *(-sym(',') >> SpaceBreak >> TableLitLine) >> -sym(',');
1231 clearSelection! 406
1232 emit "Scene.EditMenu.Delete" 407rule TableLit =
1233 408 sym('{') >>
1234 mode = 0 409 (TableValueList | Nothing) >>
1235 @zoomBtn\slot "Tapped",-> 410 -sym(',') >>
1236 scale = switch mode 411 (table_lit_lines | Nothing) >>
1237 when 0 then 2 412 White >> sym('}');
1238 when 1 then 0.5 413
1239 when 2 then 1 414rule TableValueList = TableValue >> *(sym(',') >> TableValue);
1240 mode += 1 415
1241 mode %= 3 416rule TableLitLine =
1242 @zoomBtn.text = string.format("%d%%",scale*100) 417(
1243 emit "Scene.ViewArea.ScaleTo",scale 418 PushIndent >> (TableValueList >> PopIndent | PopIndent)
1244 419) | (
1245 @originBtn\slot "Tapped",-> editor\moveTo oVec2.zero 420 Space >> Nothing
1246 421);
1247 @progressUp.visible = false 422
1248 @progressDown.visible = false 423extern rule KeyValueLine;
1249 424
1250 with @upBtn 425rule TableBlockInner = KeyValueLine >> *(+(SpaceBreak) >> KeyValueLine);
1251 .visible = false 426rule TableBlock = +(SpaceBreak) >> Advance >> ensure(TableBlockInner, PopIndent);
1252 .enabled = false 427
1253 \slot "TapBegan",-> 428extern rule Statement;
1254 clearSelection! 429
1255 \schedule once -> 430rule ClassLine = CheckIndent >> (KeyValueList | Statement | Exp) >> -sym(',');
1256 sleep 0.4 431rule ClassBlock = +(SpaceBreak) >> Advance >> ClassLine >> *(+(SpaceBreak) >> ClassLine) >> PopIndent;
1257 @progressUp.visible = true 432
1258 @progressUp\play! 433rule ClassDecl =
1259 \slot "Tapped",-> 434 key("class") >> not_(expr(':')) >>
1260 if @progressUp.visible 435 (Assignable | Nothing) >>
1261 if @progressUp.done 436 (key("extends") >> PreventIndent >> ensure(Exp, PopIndent) | Nothing) >>
1262 emit "Scene.EditMenu.Top" 437 (ClassBlock | Nothing);
1263 else 438
1264 emit "Scene.EditMenu.Up" 439rule export_values = sym('=') >> ExpListLow;
1265 \slot "TapEnded",-> 440rule Export = key("export") >> (ClassDecl | op('*') | op('^') | NameList >> (export_values | Nothing));
1266 \unschedule! 441
1267 if @progressUp.visible 442rule KeyValue =
1268 @progressUp.visible = false 443(
1269 444 sym(':') >> not_(SomeSpace) >> Name
1270 with @downBtn 445) | (
1271 .visible = false 446 (KeyName |
1272 .enabled = false 447 sym('[') >> Exp >> sym(']') |
1273 \slot "TapBegan",-> 448 Space >> DoubleString |
1274 clearSelection! 449 Space >> SingleString
1275 \schedule once -> 450 ) >>
1276 sleep 0.4 451 symx(':') >>
1277 @progressDown.visible = true 452 (Exp | TableBlock | +(SpaceBreak) >> Exp)
1278 @progressDown\play! 453);
1279 \slot "Tapped",-> 454
1280 if @progressDown.visible 455rule KeyValueList = KeyValue >> *(sym(',') >> KeyValue);
1281 if @progressDown.done 456rule KeyValueLine = CheckIndent >> KeyValueList >> -sym(',');
1282 emit "Scene.EditMenu.Bottom" 457
1283 else 458rule FnArgDef = (Name | SelfName) >> (sym('=') >> Exp | Nothing);
1284 emit "Scene.EditMenu.Down" 459
1285 \slot "TapEnded",-> 460rule FnArgDefList =
1286 \unschedule! 461(
1287 if @progressDown.visible 462 FnArgDef >>
1288 @progressDown.visible = false 463 *((sym(',') | Break) >> White >> FnArgDef) >>
1289 464 ((sym(',') | Break) >> White >> VarArg | Nothing)
1290 with @foldBtn 465) | (
1291 .visible = false 466 VarArg
1292 .enabled = false 467);
1293 \slot "Tapped",-> 468
1294 clearSelection! 469rule outer_value_shadow = key("using") >> (NameList | Space >> expr("nil"));
1295 emit "Scene.ViewPanel.Fold",editor.currentData 470
1296 471rule normal_fn_args_def =
1297 with @editBtn 472 sym('(') >> White >> (FnArgDefList | Nothing) >> (outer_value_shadow | Nothing) >> White >> sym(')');
1298 .visible = false 473
1299 .enabled = false 474rule FnArgsDef = normal_fn_args_def | Nothing;
1300 \slot "Tapped",-> 475rule fn_arrow = sym("->");
1301 emit "Scene.SettingPanel.Edit",nil 476rule fat_arrow = sym("=>");
1302 editor\editCurrentItemInPlace! 477rule FunLit = FnArgsDef >> (fn_arrow | fat_arrow) >> (Body | Nothing);
1303 478
1304 with @menuBtn 479rule NameList = Name >> *(sym(',') >> Name);
1305 .dirty = false 480rule NameOrDestructure = Name | TableLit;
1306 \slot "Tapped",-> 481rule AssignableNameList = NameOrDestructure >> *(sym(',') >> NameOrDestructure);
1307 clearSelection! 482
1308 if .dirty 483rule ExpList = Exp >> *(sym(',') >> Exp);
1309 editor\save! 484rule ExpListLow = Exp >> *((sym(',') | sym(';')) >> Exp);
1310 emit "Scene.Dirty",false 485
1311 else 486rule ArgLine = CheckIndent >> ExpList;
1312 ScenePanel = require "Control.Item.ScenePanel" 487rule ArgBlock = ArgLine >> *(sym(',') >> SpaceBreak >> ArgLine) >> PopIndent;
1313 ScenePanel! 488
1314 emit "Scene.SettingPanel.Edit",nil 489rule invoke_args_with_table =
1315 490 sym(',') >>
1316 with @undoBtn 491 (
1317 .visible = false 492 TableBlock >> Nothing |
1318 \slot "Tapped",-> 493 SpaceBreak>> Advance >> ArgBlock >> (TableBlock | Nothing)
1319 clearSelection! 494 );
1320 editor.currentSceneFile = editor.currentSceneFile 495
1321 emit "Scene.Dirty",false 496rule InvokeArgs =
1322 497 not_(expr('-')) >>
1323 with @xFixBtn 498 (
1324 .visible = false 499 ExpList >> (invoke_args_with_table | TableBlock | Nothing) |
1325 \slot "Tapped",(button)-> 500 TableBlock >> Nothing
1326 editor.xFix = not editor.xFix 501 );
1327 if editor.yFix 502
1328 editor.yFix = false 503rule SimpleValue =
1329 @yFixBtn.color = ccColor3 0x00ffff 504 key("nil") | key("true") | key("false") |
1330 button.color = ccColor3 editor.xFix and 0xff0088 or 0x00ffff 505 If | Unless | Switch | With | ClassDecl | ForEach | For | While | Do |
1331 emit "Scene.FixChange" 506 sym('-') >> not_(SomeSpace) >> Exp |
1332 507 sym('#') >> Exp |
1333 with @yFixBtn 508 sym('~') >> Exp |
1334 .visible = false 509 key("not") >> Exp |
1335 \slot "Tapped",(button)-> 510 TblComprehension | TableLit | Comprehension | FunLit | Num;
1336 editor.yFix = not editor.yFix 511
1337 if editor.xFix 512rule Assignment = ExpList >> (Update | Assign);
1338 editor.xFix = false 513
1339 @xFixBtn.color = ccColor3 0x00ffff 514rule if_else_line = key("if") >> Exp >> (key("else") >> Exp | Nothing);
1340 button.color = ccColor3 editor.yFix and 0xff0088 or 0x00ffff 515rule unless_line = key("unless") >> Exp;
1341 emit "Scene.FixChange" 516
1342 517rule Statement =
1343 @iconCam.visible = false 518(
1344 519 Import | While | With | For | ForEach |
1345 currentSubCam = nil 520 Switch | Return | Local | Export | BreakLoop |
1346 with @camBtn 521 Assignment | ExpList
1347 .visible = false 522) >> Space >>
1348 .editing = false 523(
1349 \gslot "Scene.Camera.Select",(subCam)-> 524 (if_else_line | unless_line | CompInner) >> Space | Nothing
1350 currentSubCam = subCam 525);
1351 \slot "Tapped",-> 526
1352 .editing = not .editing 527rule Body = -Space >> Break >> *EmptyLine >> InBlock | Statement;
1353 if .editing 528
1354 emit "Scene.Camera.Activate",currentSubCam 529rule empty_line_stop = Space >> and_(Stop);
1355 else 530rule Line = CheckIndent >> Statement | empty_line_stop;
1356 emit "Scene.Camera.Activate",nil 531rule Block = Line >> *(+Break >> Line);
1357 532rule BlockWithEnd = Block >> eof();
1358 with @zoomEditBtn 533
1359 .visible = false 534class AstNode : public ast_container
1360 .editing = false 535{
1361 \slot "Tapped",-> 536public:
1362 .editing = not .editing 537 virtual void construct(ast_stack& st)
1363 if .editing and currentSubCam
1364 emit "Scene.Edit.ShowRuler", {currentSubCam.zoom,0.5,10,1,(value)->
1365 emit "Scene.ViewArea.Scale",value
1366 }
1367 else
1368 emit "Scene.Edit.ShowRuler",nil
1369
1370 @playBtn\slot "Tapped",->
1371 settings = editor\getSettings!
1372 sceneFile = if settings.StartupScene
1373 editor.sceneFullPath..settings.StartupScene..".scene"
1374 else
1375 nil
1376 if not sceneFile or not oContent\exist sceneFile
1377 MessageBox text:"Startup Scene\nIs Required!",okOnly:true
1378 return
1379 @menuBtn\emit "Tapped" if @menuBtn.dirty
1380 -- test codes below
1381 Game = require "Lib.Game.Game"
1382 game = Game editor.game,false
1383 editorData = editor\getEditorData!
1384 editorData.lastScene = editor.lastScene
1385 emit "Scene.EditorData",editorData
1386 editor\emit "Quit",game\loadScene!
1387
1388 setupItemButton = (button,groupLine,subItems)->
1389 groupLine.data = button
1390 with button
1391 .showItem = false
1392 \slot "Tapped",->
1393 return if .scheduled
1394 .showItem = not .showItem
1395 if .showItem
1396 groupLine.visible = true
1397 groupLine.opacity = 0
1398 groupLine\perform oOpacity 0.3,1
1399 groupLine.position = button.position-oVec2 25,25
1400 else
1401 \schedule once ->
1402 groupLine\perform oOpacity 0.3,0
1403 sleep 0.3
1404 groupLine.visible = false
1405 @showItemButtons subItems,.showItem
1406 setupItemButton @graphicBtn,@graphicLine,{"sprite","model","effect","layer"}
1407 setupItemButton @physicsBtn,@physicsLine,{"body","world"}
1408 setupItemButton @logicBtn,@logicLine,{"trigger","action","ai"}
1409 setupItemButton @dataBtn,@dataLine,{"unit"}
1410
1411 @gslot "Scene.ShowFix",(value)->
1412 editor.xFix = false
1413 editor.yFix = false
1414 emit "Scene.FixChange"
1415 if value
1416 with @xFixBtn
1417 .visible = true
1418 .color = ccColor3 0x00ffff
1419 .scaleX = 0
1420 .scaleY = 0
1421 \perform oScale 0.5,1,1,oEase.OutBack
1422 with @yFixBtn
1423 .visible = true
1424 .color = ccColor3 0x00ffff
1425 .scaleX = 0
1426 .scaleY = 0
1427 \perform oScale 0.5,1,1,oEase.OutBack
1428 else
1429 @xFixBtn.visible = false
1430 @yFixBtn.visible = false
1431
1432 @gslot "Scene.Dirty",(dirty)->
1433 with @menuBtn
1434 if .dirty ~= dirty
1435 .dirty = dirty
1436 if dirty
1437 .text = "Save"
1438 with @undoBtn
1439 if not .visible
1440 .enabled = true
1441 .visible = true
1442 .scaleX = 0
1443 .scaleY = 0
1444 \perform oScale 0.3,1,1,oEase.OutBack
1445 else
1446 .color = ccColor3 0x00ffff
1447 .text = "Menu"
1448 with @undoBtn
1449 if .visible
1450 .enabled = false
1451 \perform CCSequence {
1452 oScale 0.3,0,0,oEase.InBack
1453 CCHide!
1454 }
1455
1456 itemChoosed = (itemData)->
1457 return if isHide
1458 if @camBtn.visible or @iconCam.visible
1459 @iconCam.visible = false
1460 @camBtn.visible = false
1461 emit "Scene.Camera.Activate",nil
1462 emit "Scene.Camera.Select",nil
1463 emit "Scene.ViewPanel.FoldState",{
1464 itemData:itemData
1465 handler:(state)->
1466 if state ~= nil
1467 @setButtonVisible @foldBtn,true
1468 switch itemData.typeName
1469 when "Body","Model","Effect"
1470 @setButtonVisible @editBtn,true
1471 else
1472 @setButtonVisible @editBtn,false
1473 text = @foldBtn.text
1474 targetText = state and "Un\nFold" or "Fold"
1475 if text ~= targetText
1476 @foldBtn.text = targetText
1477 if @foldBtn.scale.done
1478 @setButtonVisible @foldBtn,true
1479 else
1480 @setButtonVisible @foldBtn,false
1481 @setButtonVisible @upBtn,false
1482 @setButtonVisible @downBtn,false
1483 @setButtonVisible @editBtn,false
1484 }
1485 return unless itemData
1486 switch itemData.typeName
1487 when "Camera","PlatformWorld","UILayer"
1488 @setButtonVisible @upBtn,false
1489 @setButtonVisible @downBtn,false
1490 {:x,:y} = @upBtn.position
1491 @foldBtn\runAction oPos 0.3,x,y,oEase.OutQuad
1492 if itemData.typeName == "Camera"
1493 clearSelection!
1494 with @iconCam
1495 .visible = true
1496 .scaleX = 0
1497 .scaleY = 0
1498 \perform oScale 0.3,0.5,0.5,oEase.OutBack
1499 else
1500 item = editor\getItem itemData
1501 hasChildren = false
1502 if itemData.typeName == "World"
1503 hasChildren = #item.parent.parent.children > 1
1504 else
1505 hasChildren = #item.parent.children > 1
1506 if item.parent.children and hasChildren
1507 @setButtonVisible @upBtn,true
1508 @setButtonVisible @downBtn,true
1509 {:x,:y} = @downBtn.position
1510 @foldBtn\runAction oPos 0.3,x,y-60,oEase.OutQuad
1511 @editBtn\runAction oPos 0.3,x,y-120,oEase.OutQuad
1512 else
1513 @setButtonVisible @upBtn,false
1514 @setButtonVisible @downBtn,false
1515 {:x,:y} = @upBtn.position
1516 @foldBtn\runAction oPos 0.3,x,y,oEase.OutQuad
1517 @editBtn\runAction oPos 0.3,x,y-60,oEase.OutQuad
1518 @gslot "Scene.ViewPanel.Pick",itemChoosed
1519 @gslot "Scene.ViewPanel.Select",itemChoosed
1520
1521 @gslot "Scene.ViewArea.Scale",(scale)->
1522 mode = 2 if scale ~= 1
1523 @zoomBtn.text = string.format("%d%%",scale*100)
1524 @gslot "Scene.ViewArea.ScaleReset",->
1525 mode = 0
1526 @zoomBtn.text = "100%"
1527 emit "Scene.ViewArea.ScaleTo",1
1528
1529 @gslot "Scene.Camera.Select",(subCam)->
1530 if subCam and not @camBtn.visible
1531 @iconCam.opacity = 0
1532 with @camBtn
1533 .visible = true
1534 .scaleX = 0
1535 .scaleY = 0
1536 \perform oScale 0.3,1,1,oEase.OutBack
1537 else
1538 @camBtn.visible = false
1539 with @iconCam
1540 .opacity = 1
1541 .scaleX = 0
1542 .scaleY = 0
1543 \perform oScale 0.3,0.5,0.5,oEase.OutBack
1544
1545 changeDisplay = (child)->
1546 if child.positionX < width/2
1547 child\perform oPos 0.5,-child.positionX,child.positionY,oEase.OutQuad
1548 else
1549 child\perform oPos 0.5,width*2-child.positionX,child.positionY,oEase.OutQuad
1550
1551 @gslot "Scene.HideEditor",(args)->
1552 {hide,all} = args
1553 return if isHide == hide
1554 isHide = hide
1555 @enabled = @camBtn.editing or not hide
1556 for i = 1,#@children
1557 child = @children[i]
1558 switch child
1559 when @camBtn
1560 posX = @camBtn.editing and width-35 or width-345
1561 child\perform oPos 0.5,posX,child.positionY,oEase.OutQuad
1562 when @menuBtn,@undoBtn,@zoomEditBtn,@iconCam
1563 if all
1564 changeDisplay child
1565 else
1566 continue
1567 else
1568 changeDisplay child
1569
1570 @gslot "Scene.Camera.Activate",(subCam)->
1571 editor.isFixed = not @camBtn.editing
1572 if subCam
1573 with @zoomEditBtn
1574 .scaleX = 0
1575 .scaleY = 0
1576 .visible = true
1577 \perform CCSequence {
1578 CCDelay 0.5
1579 oScale 0.3,1,1,oEase.OutBack
1580 }
1581 else
1582 @zoomEditBtn.visible = false
1583 @zoomEditBtn.editing = false
1584 emit "Scene.Edit.ShowRuler",nil
1585
1586 @gslot "Scene.EditMenu.ClearSelection",clearSelection
1587
1588 setButtonVisible:(button,visible)=>
1589 return if visible == button.enabled
1590 button.enabled = visible
1591 if visible
1592 if not button.visible
1593 button.visible = true
1594 button.scaleX = 0
1595 button.scaleY = 0
1596 button\perform oScale 0.3,1,1,oEase.OutBack
1597 else
1598 button\perform CCSequence {
1599 oScale 0.3,0,0,oEase.InBack
1600 CCHide!
1601 }
1602
1603 showItemButtons:(names,visible,instant=false)=>
1604 buttonSet = {@["#{name}Btn"],true for name in *names}
1605 posX = 35
1606 posY = @itemMenu.height-25
1607 if visible
1608 offset = @itemArea.offset
1609 firstItem = nil
1610 for child in *@itemMenu.children
1611 isTarget = buttonSet[child]
1612 firstItem = child if isTarget and not firstItem
1613 if child.displayed or isTarget
1614 offsetX = switch child
1615 when @graphicBtn,@physicsBtn,@logicBtn,@dataBtn then 0
1616 else 20
1617 child.position = offset+oVec2(posX+offsetX,posY)
1618 if isTarget
1619 child.displayed = true
1620 child.visible = true
1621 if not instant
1622 child.face.scaleY = 0
1623 child.face\perform oScale 0.3,1,1,oEase.OutBack
1624 posY -= 60
1625 elseif child.data -- data is parentButton
1626 child.position = child.data.position-oVec2(25,25)
1627 @itemArea.viewSize = CCSize 70,@itemArea.height-posY-35
1628 @itemArea\scrollToPosY firstItem.positionY
1629 else
1630 @itemMenu\schedule once ->
1631 if not instant
1632 for child in *@itemMenu.children
1633 if buttonSet[child]
1634 child.face\perform oScale 0.3,1,0,oEase.OutQuad
1635 sleep 0.3
1636 offset = @itemArea.offset
1637 lastPosY = nil
1638 for child in *@itemMenu.children
1639 if buttonSet[child]
1640 child.positionX = -35
1641 child.displayed = false
1642 child.visible = false
1643 lastPosY = child.positionY
1644 elseif child.displayed
1645 if lastPosY and child.positionY < lastPosY
1646 child.face.scaleY = 0
1647 child.face\perform oScale 0.3,1,1,oEase.OutBack
1648 offsetX = switch child
1649 when @graphicBtn,@physicsBtn,@logicBtn,@dataBtn then 0
1650 else 20
1651 child.position = offset+oVec2(posX+offsetX,posY)
1652 posY -= 60
1653 elseif lastPosY and child.data and child.positionY < lastPosY
1654 child.opacity = 0
1655 child\perform oOpacity 0.3,1
1656 child.position = child.data.position-oVec2(25,25)
1657 @itemArea.viewSize = CCSize 70,@itemArea.height-posY-35
1658
1659)xoxox", "abc");
1660
1661 string_input<> in(R"PIG(import Path, Struct from require "utils")PIG", "bcd");
1662 try
1663 { 538 {
1664 if (parse<must<moon::Import, eof>, moon::action, moon::control>(in, state)) 539 stringstream stream;
540 for (input::iterator it = m_begin.m_it; it != m_end.m_it; ++it)
1665 { 541 {
1666 std::cout << "matched.\n"; 542 stream << (char)*it;
1667 }
1668 else
1669 {
1670 std::cout << "not matched.\n";
1671 } 543 }
544 _value = stream.str();
1672 } 545 }
1673 catch (parse_error e) 546 void print()
1674 { 547 {
1675 std::cout << "not matched.\n"; 548 cout << _value << '\n';
1676 std::cout << e.what() << '\n';
1677 } 549 }
1678/* 550private:
1679 analyze<hello::expr>(); 551 string _value;
1680 const char* text = "1 + 2 + 3 * 4 / 2"; 552};
1681 string_input<> in(text, "abc"); 553
1682 try 554rule ExprEnd = Block >> eof();
555
556ast<AstNode> testNode(ExprEnd);
557
558int main()
559{
560 string s = R"baddog()baddog";
561 input i(s.begin(), s.end());
562
563 error_list el;
564 AstNode* root = nullptr;
565 State st;
566 if (parse(i, ExprEnd, el, root, &st))
1683 { 567 {
1684 hello::Stack stack; 568 cout << "matched!\n";
1685 if (parse<hello::expr, hello::action>(in, stack))
1686 {
1687 std::cout << text << " = " << stack.getValue() << '\n';
1688 }
1689 return 0;
1690 } 569 }
1691 catch (parse_error e) 570 else
1692 { 571 {
1693 std::cout << e.what() << '\n'; 572 cout << "not matched!\n";
1694 return 1; 573 for (error_list::iterator it = el.begin(); it != el.end(); ++it)
574 {
575 const error& err = *it;
576 cout << "line " << err.m_begin.m_line << ", col " << err.m_begin.m_col << ": syntax error\n";
577 }
1695 } 578 }
1696*/ 579 system("pause");
1697 return 0; 580 return 0;
1698} 581}