aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2017-07-16 17:05:31 +0800
committerLi Jin <dragon-fly@qq.com>2017-07-16 17:05:31 +0800
commit9e63302e5906d53d9f39f64c549b9aa7e806b669 (patch)
treea76f39ed3e6336e13fe58f2387495c8f091639a3
parentcb906e739f27931e9798510cd83725131ed55209 (diff)
downloadyuescript-parserlib.tar.gz
yuescript-parserlib.tar.bz2
yuescript-parserlib.zip
AST generating succeeded.parserlib
-rw-r--r--MoonParser/ast.cpp1
-rw-r--r--MoonParser/ast.hpp83
-rw-r--r--MoonParser/main.cpp835
-rw-r--r--MoonParser/parser.hpp1
4 files changed, 804 insertions, 116 deletions
diff --git a/MoonParser/ast.cpp b/MoonParser/ast.cpp
index 66f6493..916fdd7 100644
--- a/MoonParser/ast.cpp
+++ b/MoonParser/ast.cpp
@@ -51,7 +51,6 @@ void ast_member::_init() {
51/** parses the given input. 51/** parses the given input.
52 @param i input. 52 @param i input.
53 @param g root rule of grammar. 53 @param g root rule of grammar.
54 @param ws whitespace rule.
55 @param el list of errors. 54 @param el list of errors.
56 @param ud user data, passed to the parse procedures. 55 @param ud user data, passed to the parse procedures.
57 @return pointer to ast node created, or null if there was an error. 56 @return pointer to ast node created, or null if there was an error.
diff --git a/MoonParser/ast.hpp b/MoonParser/ast.hpp
index 5d87db9..664c8af 100644
--- a/MoonParser/ast.hpp
+++ b/MoonParser/ast.hpp
@@ -53,12 +53,17 @@ public:
53 @param st stack. 53 @param st stack.
54 */ 54 */
55 virtual void construct(ast_stack &st) {} 55 virtual void construct(ast_stack &st) {}
56 56
57 /** interface for visiting AST tree use.
58 @param user_data vector for storing user data.
59 */
60 virtual void visit(void* user_data) {}
57private: 61private:
58 //parent 62 //parent
59 ast_node *m_parent; 63 ast_node *m_parent;
60 64
61 template <class T, bool OPT> friend class ast_ptr; 65 template <class T, bool OPT> friend class ast_ptr;
66 template <class ...Args> friend class ast_choice;
62 template <class T> friend class ast_list; 67 template <class T> friend class ast_list;
63 template <class T> friend class ast; 68 template <class T> friend class ast;
64}; 69};
@@ -240,7 +245,10 @@ public:
240 */ 245 */
241 virtual void construct(ast_stack &st) { 246 virtual void construct(ast_stack &st) {
242 //check the stack node 247 //check the stack node
243 if (st.empty()) throw std::logic_error("invalid AST stack"); 248 if (st.empty()) {
249 if (OPT) return;
250 else throw std::logic_error("invalid AST stack");
251 }
244 252
245 //get the node 253 //get the node
246 ast_node *node = st.back(); 254 ast_node *node = st.back();
@@ -277,6 +285,77 @@ private:
277 } 285 }
278}; 286};
279 287
288template <class ...Args> class ast_choice : public ast_member {
289public:
290 ast_choice(ast_node *obj = 0) : m_ptr(obj) {
291 _set_parent();
292 }
293
294 ast_choice(const ast_choice<Args...> &src) :
295 m_ptr(src.m_ptr ? new ast_node(*src.m_ptr) : 0)
296 {
297 _set_parent();
298 }
299
300 ~ast_choice() {
301 delete m_ptr;
302 }
303
304 ast_choice<Args...> &operator = (const ast_node *obj) {
305 delete m_ptr;
306 m_ptr = obj ? new ast_node(*obj) : 0;
307 _set_parent();
308 return *this;
309 }
310
311 ast_choice<Args...> &operator = (const ast_choice<Args...> &src) {
312 delete m_ptr;
313 m_ptr = src.m_ptr ? new ast_node(*src.m_ptr) : 0;
314 _set_parent();
315 return *this;
316 }
317
318 ast_node *get() const {
319 return m_ptr;
320 }
321
322 operator ast_node *() const {
323 return m_ptr;
324 }
325
326 ast_node *operator ->() const {
327 assert(m_ptr);
328 return m_ptr;
329 }
330
331 virtual void construct(ast_stack &st) {
332 if (st.empty()) {
333 throw std::logic_error("invalid AST stack");
334 }
335
336 ast_node *node = st.back();
337 ast_node *obj = nullptr;
338
339 using swallow = bool[];
340 (void)swallow{obj || (obj = dynamic_cast<Args*>(node))...};
341
342 if (!obj) throw std::logic_error("invalid AST node");
343
344 st.pop_back();
345
346 delete m_ptr;
347 m_ptr = obj;
348 _set_parent();
349 }
350
351private:
352 //ptr
353 ast_node *m_ptr;
354
355 void _set_parent() {
356 if (m_ptr) m_ptr->m_parent = container();
357 }
358};
280 359
281/** A list of objects. 360/** A list of objects.
282 It pops objects of the given type from the ast stack, until no more objects can be popped. 361 It pops objects of the given type from the ast stack, until no more objects can be popped.
diff --git a/MoonParser/main.cpp b/MoonParser/main.cpp
index cf7bc2d..985fdcf 100644
--- a/MoonParser/main.cpp
+++ b/MoonParser/main.cpp
@@ -9,6 +9,8 @@ using std::stack;
9#include <algorithm> 9#include <algorithm>
10#include <sstream> 10#include <sstream>
11using std::stringstream; 11using std::stringstream;
12#include <vector>
13using std::vector;
12#include "parserlib.hpp" 14#include "parserlib.hpp"
13using namespace parserlib; 15using namespace parserlib;
14 16
@@ -27,6 +29,7 @@ struct State
27 indents.push(0); 29 indents.push(0);
28 stringOpen = -1; 30 stringOpen = -1;
29 } 31 }
32 stringstream buffer;
30 size_t stringOpen; 33 size_t stringOpen;
31 stack<int> indents; 34 stack<int> indents;
32 stack<bool> doStack; 35 stack<bool> doStack;
@@ -39,10 +42,15 @@ struct State
39 }; 42 };
40}; 43};
41 44
45struct Data
46{
47 vector<char> bytes;
48};
49
42rule Any = any(); 50rule Any = any();
43rule White = *set(" \t\r\n");
44rule plain_space = *set(" \t"); 51rule plain_space = *set(" \t");
45rule Break = nl(-expr('\r') >> '\n'); 52rule Break = nl(-expr('\r') >> '\n');
53rule White = *(set(" \t\r") | Break);
46rule Stop = Break | eof(); 54rule Stop = Break | eof();
47rule Comment = "--" >> *(not_(set("\r\n")) >> Any) >> and_(Stop); 55rule Comment = "--" >> *(not_(set("\r\n")) >> Any) >> and_(Stop);
48rule Indent = *set(" \t"); 56rule Indent = *set(" \t");
@@ -68,7 +76,7 @@ rule _Num =
68 ); 76 );
69rule Num = Space >> _Num; 77rule Num = Space >> _Num;
70rule Cut = false_(); 78rule Cut = false_();
71rule Nothing = true_(); 79rule Seperator = true_();
72 80
73#define sym(str) (Space >> str) 81#define sym(str) (Space >> str)
74#define symx(str) expr(str) 82#define symx(str) expr(str)
@@ -79,11 +87,12 @@ rule Nothing = true_();
79 87
80rule Name = user(SpaceName, [](const item_t& item) 88rule Name = user(SpaceName, [](const item_t& item)
81{ 89{
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); 90 State* st = reinterpret_cast<State*>(item.user_data);
91 for (input_it i = item.begin; i != item.end; ++i) st->buffer << static_cast<char>(*i);
92 string name;
93 st->buffer >> name;
94 st->buffer.str("");
95 st->buffer.clear();
87 auto it = st->keywords.find(name); 96 auto it = st->keywords.find(name);
88 return it == st->keywords.end(); 97 return it == st->keywords.end();
89}); 98});
@@ -172,11 +181,12 @@ rule InBlock = Advance >> Block >> PopIndent;
172 181
173extern rule NameList; 182extern rule NameList;
174 183
175rule Local = key("local") >> (op('*') | op('^') | NameList); 184rule local_flag = op('*') | op('^');
185rule Local = key("local") >> (local_flag | NameList);
176 186
177rule colon_import_name = sym('\\') >> Name; 187rule colon_import_name = sym('\\') >> Name;
178rule ImportName = colon_import_name | Name; 188rule ImportName = colon_import_name | Name;
179rule ImportNameList = *SpaceBreak >> ImportName >> *((+SpaceBreak | sym(',') >> *SpaceBreak) >> ImportName); 189rule ImportNameList = Seperator >> *SpaceBreak >> ImportName >> *((+SpaceBreak | sym(',') >> *SpaceBreak) >> ImportName);
180 190
181extern rule Exp; 191extern rule Exp;
182 192
@@ -185,7 +195,7 @@ rule BreakLoop = key("break") | key("continue");
185 195
186extern rule ExpListLow, ExpList, Assign; 196extern rule ExpListLow, ExpList, Assign;
187 197
188rule Return = key("return") >> (ExpListLow | Nothing); 198rule Return = key("return") >> -ExpListLow;
189rule WithExp = ExpList >> -Assign; 199rule WithExp = ExpList >> -Assign;
190 200
191extern rule DisableDo, PopDo, Body; 201extern rule DisableDo, PopDo, Body;
@@ -195,7 +205,7 @@ rule SwitchCase = key("when") >> ExpList >> -key("then") >> Body;
195rule SwitchElse = key("else") >> Body; 205rule SwitchElse = key("else") >> Body;
196 206
197rule SwitchBlock = *EmptyLine >> 207rule SwitchBlock = *EmptyLine >>
198 Advance >> 208 Advance >> Seperator >>
199 SwitchCase >> 209 SwitchCase >>
200 *(+Break >> SwitchCase) >> 210 *(+Break >> SwitchCase) >>
201 -(+Break >> SwitchElse) >> 211 -(+Break >> SwitchElse) >>
@@ -208,12 +218,13 @@ rule Switch = key("switch") >>
208rule IfCond = Exp >> -Assign; 218rule IfCond = Exp >> -Assign;
209rule IfElseIf = -(Break >> *EmptyLine >> CheckIndent) >> key("elseif") >> IfCond >> -key("then") >> Body; 219rule IfElseIf = -(Break >> *EmptyLine >> CheckIndent) >> key("elseif") >> IfCond >> -key("then") >> Body;
210rule IfElse = -(Break >> *EmptyLine >> CheckIndent) >> key("else") >> Body; 220rule IfElse = -(Break >> *EmptyLine >> CheckIndent) >> key("else") >> Body;
211rule If = key("if") >> IfCond >> -key("then") >> Body >> *IfElseIf >> -IfElse; 221rule If = key("if") >> IfCond >> -key("then") >> Body >> Seperator >> *IfElseIf >> -IfElse;
212rule Unless = key("unless") >> IfCond >> -key("then") >> Body >> *IfElseIf >> -IfElse; 222rule Unless = key("unless") >> IfCond >> -key("then") >> Body >> Seperator >> *IfElseIf >> -IfElse;
213 223
214rule While = key("while") >> DisableDo >> ensure(Exp, PopDo) >> -key("do") >> Body; 224rule While = key("while") >> DisableDo >> ensure(Exp, PopDo) >> -key("do") >> Body;
215 225
216rule for_args = Name >> sym('=') >> Exp >> sym(',') >> Exp >> (sym(',') >> Exp | Nothing); 226rule for_step_value = sym(',') >> Exp;
227rule for_args = Name >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value;
217 228
218rule For = key("for") >> DisableDo >> 229rule For = key("for") >> DisableDo >>
219 ensure(for_args, PopDo) >> 230 ensure(for_args, PopDo) >>
@@ -250,21 +261,22 @@ rule PopDo = user(true_(), [](const item_t& item)
250extern rule CompInner; 261extern rule CompInner;
251 262
252rule Comprehension = sym('[') >> Exp >> CompInner >> sym(']'); 263rule Comprehension = sym('[') >> Exp >> CompInner >> sym(']');
253rule TblComprehension = sym('{') >> (Exp >> -(sym(',') >> Exp)) >> CompInner >> sym('}'); 264rule comp_value = sym(',') >> Exp;
265rule TblComprehension = sym('{') >> (Exp >> -comp_value) >> CompInner >> sym('}');
254 266
255extern rule CompForEach, CompFor, CompClause; 267extern rule CompForEach, CompFor, CompClause;
256 268
257rule CompInner = (CompForEach | CompFor) >> *CompClause; 269rule CompInner = (CompForEach | CompFor) >> Seperator >> *CompClause;
258rule CompForEach = key("for") >> AssignableNameList >> key("in") >> (sym('*') >> Exp | Exp); 270rule star_exp = sym('*') >> Exp;
259rule CompFor = key("for") >> Name >> sym('=') >> Exp >> sym(',') >> Exp >> (sym(',') >> Exp | Nothing); 271rule CompForEach = key("for") >> AssignableNameList >> key("in") >> (star_exp | Exp);
272rule CompFor = key("for") >> Name >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value;
260rule CompClause = CompFor | CompForEach | key("when") >> Exp; 273rule CompClause = CompFor | CompForEach | key("when") >> Exp;
261 274
262extern rule TableBlock; 275extern rule TableBlock;
263 276
264rule Assign = sym('=') >> (With | If | Switch | TableBlock | ExpListLow); 277rule Assign = sym('=') >> (With | If | Switch | TableBlock | ExpListLow);
265 278
266rule Update = 279rule update_op =
267(
268 sym("..=") | 280 sym("..=") |
269 sym("+=") | 281 sym("+=") |
270 sym("-=") | 282 sym("-=") |
@@ -276,8 +288,9 @@ rule Update =
276 sym("&=") | 288 sym("&=") |
277 sym("|=") | 289 sym("|=") |
278 sym(">>=") | 290 sym(">>=") |
279 sym("<<=") 291 sym("<<=");
280) >> Exp; 292
293rule Update = update_op >> Exp;
281 294
282rule CharOperators = Space >> set("+-*/%^><|&"); 295rule CharOperators = Space >> set("+-*/%^><|&");
283rule WordOperators = 296rule WordOperators =
@@ -301,16 +314,17 @@ rule Assignable = Chain | Name | SelfName;
301 314
302extern rule Value; 315extern rule Value;
303 316
304rule Exp = Value >> *(BinaryOperator >> Value); 317rule exp_op_value = BinaryOperator >> Value;
318rule Exp = Value >> *exp_op_value;
305 319
306extern rule Callable, InvokeArgs; 320extern rule Callable, InvokeArgs;
307 321
308rule ChainValue = (Chain | Callable) >> (InvokeArgs | Nothing); 322rule ChainValue = (Chain | Callable) >> -InvokeArgs;
309 323
310extern rule KeyValueList, String, SimpleValue; 324extern rule KeyValue, String, SimpleValue;
311 325
312rule Value = SimpleValue | KeyValueList | ChainValue | String; 326rule simple_table = Seperator >> KeyValue >> *(sym(',') >> KeyValue);
313rule SliceValue = Exp; 327rule Value = SimpleValue | simple_table | ChainValue | String;
314 328
315extern rule LuaString; 329extern rule LuaString;
316 330
@@ -319,7 +333,8 @@ rule SingleString = symx('\'') >> *single_string_inner >> sym('\'');
319rule interp = symx("#{") >> Exp >> sym('}'); 333rule interp = symx("#{") >> Exp >> sym('}');
320rule double_string_plain = expr("\\\"") | "\\\\" | not_(expr('"')) >> Any; 334rule double_string_plain = expr("\\\"") | "\\\\" | not_(expr('"')) >> Any;
321rule double_string_inner = +(not_(interp) >> double_string_plain); 335rule double_string_inner = +(not_(interp) >> double_string_plain);
322rule DoubleString = symx('"') >> *(double_string_inner | interp) >> sym('"'); 336rule double_string_content = double_string_inner | interp;
337rule DoubleString = symx('"') >> Seperator >> *double_string_content >> sym('"');
323rule String = Space >> (DoubleString | SingleString | LuaString); 338rule String = Space >> (DoubleString | SingleString | LuaString);
324 339
325rule lua_string_open = '[' >> *expr('=') >> '['; 340rule lua_string_open = '[' >> *expr('=') >> '[';
@@ -340,7 +355,7 @@ rule LuaStringClose = user(lua_string_close, [](const item_t& item)
340 return st->stringOpen == count; 355 return st->stringOpen == count;
341}); 356});
342 357
343rule LuaStringContent = *(not_(LuaStringClose) >> Any); 358rule LuaStringContent = *(not_(LuaStringClose) >> (Break | Any));
344 359
345rule LuaString = user(LuaStringOpen >> -Break >> LuaStringContent >> LuaStringClose, [](const item_t& item) 360rule LuaString = user(LuaStringOpen >> -Break >> LuaStringContent >> LuaStringClose, [](const item_t& item)
346{ 361{
@@ -353,18 +368,20 @@ rule Parens = sym('(') >> *SpaceBreak >> Exp >> *SpaceBreak >> sym(')');
353rule Callable = Name | SelfName | VarArg | Parens; 368rule Callable = Name | SelfName | VarArg | Parens;
354rule FnArgsExpList = Exp >> *((Break | sym(',')) >> White >> Exp); 369rule FnArgsExpList = Exp >> *((Break | sym(',')) >> White >> Exp);
355 370
356rule FnArgs = 371rule FnArgs = Seperator >>
357( 372(
358 symx('(') >> *SpaceBreak >> (FnArgsExpList | Nothing) >> *SpaceBreak >> sym(')') 373 (
359) | ( 374 symx('(') >> *SpaceBreak >> -FnArgsExpList >> *SpaceBreak >> sym(')')
360 sym('!') >> not_(expr('=')) >> Nothing 375 ) | (
376 sym('!') >> not_(expr('='))
377 )
361); 378);
362 379
363extern rule ChainItems, DotChainItem, ColonChain; 380extern rule ChainItems, DotChainItem, ColonChain;
364 381
365rule chain_call = (Callable | String) >> ChainItems; 382rule chain_call = (Callable | String) >> ChainItems;
366rule chain_item = not_(set(".\\")) >> ChainItems; 383rule chain_item = not_(set(".\\")) >> ChainItems;
367rule chain_dot_chain = DotChainItem >> (ChainItems | Nothing); 384rule chain_dot_chain = DotChainItem >> -ChainItems;
368 385
369rule Chain = 386rule Chain =
370 chain_call | 387 chain_call |
@@ -373,23 +390,24 @@ rule Chain =
373 390
374extern rule ChainItem; 391extern rule ChainItem;
375 392
376rule chain_items = +ChainItem >> (ColonChain | Nothing); 393rule chain_with_colon = +ChainItem >> -ColonChain;
377rule ChainItems = chain_items | ColonChain; 394rule ChainItems = Seperator >> (chain_with_colon | ColonChain);
378 395
379extern rule Invoke, Slice; 396extern rule Invoke, Slice;
380 397
381rule ChainItem = Invoke | DotChainItem | Slice | symx('[') >> Exp >> sym(']'); 398rule ChainItem = Invoke | DotChainItem | Slice | symx('[') >> Exp >> sym(']');
382rule DotChainItem = symx('.') >> _Name; 399rule DotChainItem = symx('.') >> _Name;
383rule ColonChainItem = symx('\\') >> _Name; 400rule ColonChainItem = symx('\\') >> _Name;
384rule ColonChain = ColonChainItem >> ((Invoke >> (ChainItems | Nothing)) | Nothing >> Nothing); 401rule invoke_chain = Invoke >> -ChainItems;
402rule ColonChain = ColonChainItem >> -invoke_chain;
385 403
404rule default_value = true_();
386rule Slice = 405rule Slice =
387 symx('[') >> 406 symx('[') >>
388 (SliceValue | Nothing) >> 407 (Exp | default_value) >>
389 sym(',') >> 408 sym(',') >>
390 (SliceValue | Nothing) >> 409 (Exp | default_value) >>
391 (sym(',') >> 410 (sym(',') >> Exp | default_value) >>
392 SliceValue | Nothing) >>
393 sym(']'); 411 sym(']');
394 412
395rule Invoke = 413rule Invoke =
@@ -398,17 +416,17 @@ rule Invoke =
398 DoubleString | 416 DoubleString |
399 and_(expr('[')) >> LuaString; 417 and_(expr('[')) >> LuaString;
400 418
401extern rule KeyValue, TableValueList, TableLitLine; 419extern rule TableValueList, TableLitLine;
402 420
403rule TableValue = KeyValue | Exp; 421rule TableValue = KeyValue | Exp;
404 422
405rule table_lit_lines = SpaceBreak >> TableLitLine >> *(-sym(',') >> SpaceBreak >> TableLitLine) >> -sym(','); 423rule table_lit_lines = SpaceBreak >> TableLitLine >> *(-sym(',') >> SpaceBreak >> TableLitLine) >> -sym(',');
406 424
407rule TableLit = 425rule TableLit =
408 sym('{') >> 426 sym('{') >> Seperator >>
409 (TableValueList | Nothing) >> 427 -TableValueList >>
410 -sym(',') >> 428 -sym(',') >>
411 (table_lit_lines | Nothing) >> 429 -table_lit_lines >>
412 White >> sym('}'); 430 White >> sym('}');
413 431
414rule TableValueList = TableValue >> *(sym(',') >> TableValue); 432rule TableValueList = TableValue >> *(sym(',') >> TableValue);
@@ -417,143 +435,732 @@ rule TableLitLine =
417( 435(
418 PushIndent >> (TableValueList >> PopIndent | PopIndent) 436 PushIndent >> (TableValueList >> PopIndent | PopIndent)
419) | ( 437) | (
420 Space >> Nothing 438 Space
421); 439);
422 440
423extern rule KeyValueLine; 441extern rule KeyValueLine;
424 442
425rule TableBlockInner = KeyValueLine >> *(+(SpaceBreak) >> KeyValueLine); 443rule TableBlockInner = Seperator >> KeyValueLine >> *(+(SpaceBreak) >> KeyValueLine);
426rule TableBlock = +(SpaceBreak) >> Advance >> ensure(TableBlockInner, PopIndent); 444rule TableBlock = +(SpaceBreak) >> Advance >> ensure(TableBlockInner, PopIndent);
427 445
428extern rule Statement; 446extern rule Statement;
429 447
430rule ClassLine = CheckIndent >> (KeyValueList | Statement | Exp) >> -sym(','); 448rule class_member_list = Seperator >> KeyValue >> *(sym(',') >> KeyValue);
431rule ClassBlock = +(SpaceBreak) >> Advance >> ClassLine >> *(+(SpaceBreak) >> ClassLine) >> PopIndent; 449rule ClassLine = CheckIndent >> (class_member_list | Statement | Exp) >> -sym(',');
450rule ClassBlock = +(SpaceBreak) >> Advance >>Seperator >> ClassLine >> *(+(SpaceBreak) >> ClassLine) >> PopIndent;
432 451
433rule ClassDecl = 452rule ClassDecl =
434 key("class") >> not_(expr(':')) >> 453 key("class") >> not_(expr(':')) >>
435 (Assignable | Nothing) >> 454 -Assignable >>
436 (key("extends") >> PreventIndent >> ensure(Exp, PopIndent) | Nothing) >> 455 -(key("extends") >> PreventIndent >> ensure(Exp, PopIndent)) >>
437 (ClassBlock | Nothing); 456 -ClassBlock;
457
458rule export_values = NameList >> -(sym('=') >> ExpListLow);
459rule export_op = op('*') | op('^');
460rule Export = key("export") >> (ClassDecl | export_op | export_values);
438 461
439rule export_values = sym('=') >> ExpListLow; 462rule variable_pair = sym(':') >> not_(SomeSpace) >> Name;
440rule Export = key("export") >> (ClassDecl | op('*') | op('^') | NameList >> (export_values | Nothing));
441 463
442rule KeyValue = 464rule normal_pair =
443( 465(
444 sym(':') >> not_(SomeSpace) >> Name 466 KeyName |
445) | ( 467 sym('[') >> Exp >> sym(']') |
446 (KeyName | 468 Space >> DoubleString |
447 sym('[') >> Exp >> sym(']') | 469 Space >> SingleString
448 Space >> DoubleString | 470) >>
449 Space >> SingleString 471symx(':') >>
450 ) >> 472(Exp | TableBlock | +(SpaceBreak) >> Exp);
451 symx(':') >> 473
452 (Exp | TableBlock | +(SpaceBreak) >> Exp) 474rule KeyValue = variable_pair | normal_pair;
453);
454 475
455rule KeyValueList = KeyValue >> *(sym(',') >> KeyValue); 476rule KeyValueList = KeyValue >> *(sym(',') >> KeyValue);
456rule KeyValueLine = CheckIndent >> KeyValueList >> -sym(','); 477rule KeyValueLine = CheckIndent >> KeyValueList >> -sym(',');
457 478
458rule FnArgDef = (Name | SelfName) >> (sym('=') >> Exp | Nothing); 479rule FnArgDef = (Name | SelfName) >> -(sym('=') >> Exp);
459 480
460rule FnArgDefList = 481rule FnArgDefList = Seperator >>
461( 482(
462 FnArgDef >> 483 (
463 *((sym(',') | Break) >> White >> FnArgDef) >> 484 FnArgDef >>
464 ((sym(',') | Break) >> White >> VarArg | Nothing) 485 *((sym(',') | Break) >> White >> FnArgDef) >>
465) | ( 486 -((sym(',') | Break) >> White >> VarArg)
466 VarArg 487 ) | (
488 VarArg
489 )
467); 490);
468 491
469rule outer_value_shadow = key("using") >> (NameList | Space >> expr("nil")); 492rule outer_var_shadow = key("using") >> (NameList | Space >> expr("nil"));
470 493
471rule normal_fn_args_def = 494rule FnArgsDef = sym('(') >> White >> -FnArgDefList >> -outer_var_shadow >> White >> sym(')');
472 sym('(') >> White >> (FnArgDefList | Nothing) >> (outer_value_shadow | Nothing) >> White >> sym(')'); 495rule fn_arrow = sym("->") | sym("=>");
496rule FunLit = -FnArgsDef >> fn_arrow >> -Body;
473 497
474rule FnArgsDef = normal_fn_args_def | Nothing; 498rule NameList = Seperator >> Name >> *(sym(',') >> Name);
475rule fn_arrow = sym("->");
476rule fat_arrow = sym("=>");
477rule FunLit = FnArgsDef >> (fn_arrow | fat_arrow) >> (Body | Nothing);
478
479rule NameList = Name >> *(sym(',') >> Name);
480rule NameOrDestructure = Name | TableLit; 499rule NameOrDestructure = Name | TableLit;
481rule AssignableNameList = NameOrDestructure >> *(sym(',') >> NameOrDestructure); 500rule AssignableNameList = Seperator >> NameOrDestructure >> *(sym(',') >> NameOrDestructure);
482 501
483rule ExpList = Exp >> *(sym(',') >> Exp); 502rule ExpList = Seperator >> Exp >> *(sym(',') >> Exp);
484rule ExpListLow = Exp >> *((sym(',') | sym(';')) >> Exp); 503rule ExpListLow = Seperator >> Exp >> *((sym(',') | sym(';')) >> Exp);
485 504
486rule ArgLine = CheckIndent >> ExpList; 505rule ArgLine = CheckIndent >> Exp >> *(sym(',') >> Exp);
487rule ArgBlock = ArgLine >> *(sym(',') >> SpaceBreak >> ArgLine) >> PopIndent; 506rule ArgBlock = Seperator >> ArgLine >> *(sym(',') >> SpaceBreak >> ArgLine) >> PopIndent;
488 507
489rule invoke_args_with_table = 508rule invoke_args_with_table =
490 sym(',') >> 509 sym(',') >>
491 ( 510 (
492 TableBlock >> Nothing | 511 TableBlock |
493 SpaceBreak>> Advance >> ArgBlock >> (TableBlock | Nothing) 512 SpaceBreak >> Advance >> ArgBlock >> -TableBlock
494 ); 513 );
495 514
496rule InvokeArgs = 515rule InvokeArgs =
497 not_(expr('-')) >> 516 not_(expr('-')) >>
498 ( 517 (
499 ExpList >> (invoke_args_with_table | TableBlock | Nothing) | 518 ExpList >> -(invoke_args_with_table | TableBlock) |
500 TableBlock >> Nothing 519 TableBlock
501 ); 520 );
502 521
522rule const_value = key("nil") | key("true") | key("false");
523rule minus_exp = sym('-') >> not_(SomeSpace) >> Exp;
524rule sharp_exp = sym('#') >> Exp;
525rule tilde_exp = sym('~') >> Exp;
526rule not_exp = key("not") >> Exp;
527rule unary_exp = minus_exp | sharp_exp | tilde_exp | not_exp;
528
503rule SimpleValue = 529rule SimpleValue =
504 key("nil") | key("true") | key("false") | 530 const_value |
505 If | Unless | Switch | With | ClassDecl | ForEach | For | While | Do | 531 If | Unless | Switch | With | ClassDecl | ForEach | For | While | Do |
506 sym('-') >> not_(SomeSpace) >> Exp | 532 unary_exp |
507 sym('#') >> Exp |
508 sym('~') >> Exp |
509 key("not") >> Exp |
510 TblComprehension | TableLit | Comprehension | FunLit | Num; 533 TblComprehension | TableLit | Comprehension | FunLit | Num;
511 534
512rule Assignment = ExpList >> (Update | Assign); 535rule Assignment = ExpList >> (Update | Assign);
513 536
514rule if_else_line = key("if") >> Exp >> (key("else") >> Exp | Nothing); 537rule if_else_line = key("if") >> Exp >> (key("else") >> Exp | default_value);
515rule unless_line = key("unless") >> Exp; 538rule unless_line = key("unless") >> Exp;
516 539
540rule statement_appendix = (if_else_line | unless_line | CompInner) >> Space;
517rule Statement = 541rule Statement =
518( 542(
519 Import | While | With | For | ForEach | 543 Import | While | With | For | ForEach |
520 Switch | Return | Local | Export | BreakLoop | 544 Switch | Return | Local | Export | BreakLoop |
521 Assignment | ExpList 545 Assignment | ExpList
522) >> Space >> 546) >> Space >>
523( 547-statement_appendix;
524 (if_else_line | unless_line | CompInner) >> Space | Nothing
525);
526 548
527rule Body = -Space >> Break >> *EmptyLine >> InBlock | Statement; 549rule Body = -Space >> Break >> *EmptyLine >> InBlock | Statement;
528 550
529rule empty_line_stop = Space >> and_(Stop); 551rule empty_line_stop = Space >> and_(Stop);
530rule Line = CheckIndent >> Statement | empty_line_stop; 552rule Line = CheckIndent >> Statement | empty_line_stop;
531rule Block = Line >> *(+Break >> Line); 553rule Block = Seperator >> Line >> *(+Break >> Line);
532rule BlockWithEnd = Block >> eof(); 554rule BlockEnd = Block >> eof();
533 555
534class AstNode : public ast_container 556#define AST_LEAF(type) \
535{ 557class type##_t : public ast_node \
558{ \
559public:
560
561#define AST_NODE(type) \
562class type##_t : public ast_container \
563{ \
536public: 564public:
537 virtual void construct(ast_stack& st) 565
566#define AST_END(type) \
567}; \
568ast<type##_t> __##type##_t(type);
569
570AST_LEAF(Num)
571 double value;
572 virtual void visit(void* ud) override
573 {
574 stringstream stream;
575 for (input::iterator it = m_begin.m_it; it != m_end.m_it; ++it)
576 {
577 stream << static_cast<char>(*it);
578 }
579 stream >> value;
580 cout << value << '\n';
581 }
582AST_END(Num)
583
584AST_LEAF(_Name)
585 virtual void construct(ast_stack& st) override
538 { 586 {
539 stringstream stream; 587 stringstream stream;
540 for (input::iterator it = m_begin.m_it; it != m_end.m_it; ++it) 588 for (input::iterator it = m_begin.m_it; it != m_end.m_it; ++it)
541 { 589 {
542 stream << (char)*it; 590 stream << (char)*it;
543 } 591 }
544 _value = stream.str(); 592 stream >> value;
593 ast_node::construct(st);
545 } 594 }
546 void print() 595 string value;
596AST_END(_Name)
597
598AST_NODE(Name)
599 ast_ptr<_Name_t> name;
600AST_END(Name)
601
602AST_LEAF(self)
603AST_END(self)
604
605AST_NODE(self_name)
606 ast_ptr<_Name_t> name;
607AST_END(self_name)
608
609AST_LEAF(self_class)
610AST_END(self_class)
611
612AST_NODE(self_class_name)
613 ast_ptr<_Name_t> name;
614AST_END(self_class_name)
615
616AST_NODE(SelfName)
617 ast_ptr<ast_node> name;
618AST_END(SelfName)
619
620AST_NODE(KeyName)
621 ast_ptr<ast_node> name;
622AST_END(KeyName)
623
624AST_LEAF(VarArg)
625AST_END(VarArg)
626
627AST_LEAF(local_flag)
628AST_END(local_flag)
629
630AST_LEAF(Seperator)
631AST_END(Seperator)
632
633AST_NODE(NameList)
634 ast_ptr<Seperator_t> sep;
635 ast_list<Name_t> names;
636AST_END(NameList)
637
638AST_NODE(Local)
639 ast_ptr<ast_node> name; // local_flag_t | NameList_t
640AST_END(Local)
641
642AST_NODE(colon_import_name)
643 ast_ptr<Name_t> name;
644AST_END(colon_import_name)
645
646class Exp_t;
647
648AST_NODE(ImportName)
649 ast_ptr<ast_node> name; // colon_import_name_t | Name_t
650AST_END(ImportName)
651
652AST_NODE(Import)
653 ast_ptr<Seperator_t> sep;
654 ast_list<ImportName_t> names;
655 ast_ptr<Exp_t> exp;
656AST_END(Import)
657
658AST_NODE(ExpListLow)
659 ast_ptr<Seperator_t> sep;
660 ast_list<Exp_t> exprs;
661AST_END(ExpListLow)
662
663AST_NODE(ExpList)
664 ast_ptr<Seperator_t> sep;
665 ast_list<Exp_t> exprs;
666AST_END(ExpList)
667
668AST_NODE(Return)
669 ast_ptr<ExpListLow_t, true> valueList;
670AST_END(Return)
671
672class Assign_t;
673class Body_t;
674
675AST_NODE(With)
676 ast_ptr<ExpList_t> valueList;
677 ast_ptr<Assign_t, true> assigns;
678 ast_ptr<Body_t> body;
679AST_END(With)
680
681AST_NODE(SwitchCase)
682 ast_ptr<ExpList_t> valueList;
683 ast_ptr<Body_t> body;
684AST_END(SwitchCase)
685
686AST_NODE(Switch)
687 ast_ptr<Exp_t> target;
688 ast_ptr<Seperator_t> sep;
689 ast_list<SwitchCase_t> branches;
690 ast_ptr<Body_t, true> lastBranch;
691AST_END(Switch)
692
693AST_NODE(IfCond)
694 ast_ptr<Exp_t> condition;
695 ast_ptr<Assign_t, true> assign;
696AST_END(IfCond)
697
698AST_NODE(IfElseIf)
699 ast_ptr<IfCond_t> condition;
700 ast_ptr<Body_t> body;
701AST_END(IfElseIf)
702
703AST_NODE(If)
704 ast_ptr<IfCond_t> firstCondition;
705 ast_ptr<Body_t> firstBody;
706 ast_ptr<Seperator_t> sep;
707 ast_list<IfElseIf_t> branches;
708 ast_ptr<Body_t, true> lastBranch;
709AST_END(If)
710
711AST_NODE(Unless)
712 ast_ptr<IfCond_t> firstCondition;
713 ast_ptr<Body_t> firstBody;
714 ast_ptr<Seperator_t> sep;
715 ast_list<IfElseIf_t> branches;
716 ast_ptr<Body_t, true> lastBranch;
717AST_END(Unless)
718
719AST_NODE(While)
720 ast_ptr<Exp_t> condition;
721 ast_ptr<Body_t> body;
722AST_END(While)
723
724AST_NODE(for_step_value)
725 ast_ptr<Exp_t> value;
726AST_END(for_step_value)
727
728AST_NODE(For)
729 ast_ptr<Name_t> varName;
730 ast_ptr<Exp_t> startValue;
731 ast_ptr<Exp_t> stopValue;
732 ast_ptr<for_step_value_t, true> stepValue;
733 ast_ptr<Body_t> body;
734AST_END(For)
735
736class AssignableNameList_t;
737
738AST_NODE(ForEach)
739 ast_ptr<AssignableNameList_t> nameList;
740 ast_ptr<ast_node> loopValue; // Exp_t | ExpList_t
741 ast_ptr<Body_t> body;
742AST_END(ForEach)
743
744AST_NODE(Do)
745 ast_ptr<Body_t> body;
746AST_END(Do)
747
748class CompInner_t;
749
750AST_NODE(Comprehension)
751 ast_ptr<Exp_t> value;
752 ast_ptr<CompInner_t> forLoop;
753AST_END(Comprehension)
754
755AST_NODE(comp_value)
756 ast_ptr<Exp_t> value;
757AST_END(comp_value)
758
759AST_NODE(TblComprehension)
760 ast_ptr<Exp_t> key;
761 ast_ptr<comp_value_t, true> value;
762 ast_ptr<CompInner_t> forLoop;
763AST_END(TblComprehension)
764
765AST_NODE(star_exp)
766 ast_ptr<Exp_t> value;
767AST_END(star_exp)
768
769AST_NODE(CompForEach)
770 ast_ptr<AssignableNameList_t> nameList;
771 ast_ptr<ast_node> loopValue; // star_exp_t | Exp_t
772AST_END(CompForEach)
773
774AST_NODE(CompFor)
775 ast_ptr<Name_t> varName;
776 ast_ptr<Exp_t> startValue;
777 ast_ptr<Exp_t> stopValue;
778 ast_ptr<for_step_value_t, true> stepValue;
779AST_END(CompFor)
780
781AST_NODE(CompClause)
782 ast_ptr<ast_node> nestExp; // CompFor_t | CompForEach_t | Exp_t
783AST_END(CompClause)
784
785AST_NODE(CompInner)
786 ast_ptr<ast_node> compFor; // CompFor_t | CompForEach_t
787 ast_ptr<Seperator_t> sep;
788 ast_list<CompClause_t> clauses;
789AST_END(CompInner)
790
791class TableBlock_t;
792
793AST_NODE(Assign)
794 ast_ptr<ast_node> value; // With_t | If_t | Switch_t | TableBlock_t | ExpListLow_t
795AST_END(Assign)
796
797AST_LEAF(update_op)
798AST_END(update_op)
799
800AST_NODE(Update)
801 ast_ptr<update_op_t> op;
802 ast_ptr<Exp_t> value;
803AST_END(Update)
804
805AST_LEAF(BinaryOperator)
806AST_END(BinaryOperator)
807
808class Chain_t;
809
810AST_NODE(Assignable)
811 ast_ptr<ast_node> item; // Chain_t | Name_t | SelfName_t
812AST_END(Assignable)
813
814class Value_t;
815
816AST_NODE(exp_op_value)
817 ast_ptr<BinaryOperator_t> op;
818 ast_ptr<Value_t> value;
819AST_END(exp_op_value)
820
821AST_NODE(Exp)
822 ast_ptr<Value_t> value;
823 ast_list<exp_op_value_t> opValues;
824AST_END(Exp)
825
826AST_NODE(Callable)
827 ast_ptr<ast_node> item; // Name_t | SelfName_t | VarArg_t | Parens_t
828AST_END(Callable)
829
830class InvokeArgs_t;
831
832AST_NODE(ChainValue)
833 ast_ptr<ast_node> caller; // Chain_t | Callable_t
834 ast_ptr<InvokeArgs_t, true> arguments;
835AST_END(ChainValue)
836
837class KeyValue_t;
838
839AST_NODE(simple_table)
840 ast_ptr<Seperator_t> sep;
841 ast_list<KeyValue_t> pairs;
842AST_END(simple_table)
843
844class String_t;
845class SimpleValue_t;
846
847AST_NODE(Value)
848 ast_ptr<ast_node> item; // SimpleValue_t | simple_table_t | ChainValue_t | String_t
849AST_END(Value)
850
851AST_LEAF(LuaString)
852AST_END(LuaString)
853
854AST_LEAF(SingleString)
855AST_END(SingleString)
856
857AST_LEAF(double_string_inner)
858AST_END(double_string_inner)
859
860AST_NODE(double_string_content)
861 ast_ptr<ast_node> content; // double_string_inner_t | Exp_t
862AST_END(double_string_content)
863
864AST_NODE(DoubleString)
865 ast_ptr<Seperator_t> sep;
866 ast_list<double_string_content_t> segments;
867AST_END(DoubleString)
868
869AST_NODE(String)
870 ast_ptr<ast_node> str; // DoubleString_t | SingleString_t | LuaString_t
871AST_END(String)
872
873AST_NODE(Parens)
874 ast_ptr<Exp_t> expr;
875AST_END(Parens)
876
877AST_NODE(FnArgs)
878 ast_ptr<Seperator_t> sep;
879 ast_list<Exp_t> args;
880AST_END(FnArgs)
881
882class ChainItems_t;
883
884AST_NODE(chain_call)
885 ast_ptr<ast_node> caller; // Callable_t | String_t
886 ast_ptr<ChainItems_t> chain;
887AST_END(chain_call)
888
889AST_NODE(chain_item)
890 ast_ptr<ChainItems_t> chain;
891AST_END(chain_item)
892
893AST_NODE(DotChainItem)
894 ast_ptr<_Name_t> name;
895AST_END(DotChainItem)
896
897AST_NODE(ColonChainItem)
898 ast_ptr<_Name_t> name;
899AST_END(ColonChainItem)
900
901AST_NODE(chain_dot_chain)
902 ast_ptr<DotChainItem_t> caller;
903 ast_ptr<ChainItems_t, true> chain;
904AST_END(chain_dot_chain)
905
906class ColonChain_t;
907
908AST_NODE(Chain)
909 ast_ptr<ast_node> item; // chain_call_t | chain_item_t | chain_dot_chain_t | ColonChain_t
910AST_END(Chain)
911
912class Invoke_t;
913class Slice_t;
914
915AST_NODE(ChainItem)
916 ast_ptr<ast_node> item; // Invoke_t | DotChainItem_t | Slice_t | [Exp_t]
917AST_END(ChainItem)
918
919AST_NODE(ChainItems)
920 ast_ptr<Seperator_t> sep;
921 ast_list<ChainItem_t> simpleChain;
922 ast_ptr<ColonChain_t, true> colonChain;
923AST_END(ChainItems)
924
925AST_NODE(invoke_chain)
926 ast_ptr<Invoke_t> invoke;
927 ast_ptr<ChainItems_t, true> chain;
928AST_END(invoke_chain)
929
930AST_NODE(ColonChain)
931 ast_ptr<ColonChainItem_t> colonChain;
932 ast_ptr<invoke_chain_t, true> invokeChain;
933AST_END(ColonChain)
934
935AST_LEAF(default_value)
936AST_END(default_value)
937
938AST_NODE(Slice)
939 ast_ptr<ast_node> startValue; // Exp_t | default_value_t
940 ast_ptr<ast_node> stopValue; // Exp_t | default_value_t
941 ast_ptr<ast_node> stepValue; // Exp_t | default_value_t
942AST_END(Slice)
943
944AST_NODE(Invoke)
945 ast_ptr<ast_node> argument; // FnArgs_t | SingleString_t | DoubleString_t | LuaString_t
946AST_END(Invoke)
947
948class KeyValue_t;
949
950AST_NODE(TableValue)
951 ast_ptr<ast_node> value; // KeyValue_t | Exp_t
952AST_END(TableValue)
953
954AST_NODE(TableLit)
955 ast_ptr<Seperator_t> sep;
956 ast_list<TableValue_t> values;
957AST_END(TableLit)
958
959AST_NODE(TableBlock)
960 ast_ptr<Seperator_t> sep;
961 ast_list<KeyValue_t> values;
962AST_END(TableBlock)
963
964AST_NODE(class_member_list)
965 ast_ptr<Seperator_t> sep;
966 ast_list<KeyValue_t> values;
967AST_END(class_member_list)
968
969AST_NODE(ClassLine)
970 ast_ptr<ast_node> content; // class_member_list_t | Statement_t | Exp_t
971AST_END(ClassLine)
972
973AST_NODE(ClassBlock)
974 ast_ptr<Seperator_t> sep;
975 ast_list<ClassLine_t> lines;
976AST_END(ClassBlock)
977
978AST_NODE(ClassDecl)
979 ast_ptr<Assignable_t, true> name;
980 ast_ptr<Exp_t, true> extend;
981 ast_ptr<ClassBlock_t, true> body;
982AST_END(ClassDecl)
983
984AST_NODE(export_values)
985 ast_ptr<NameList_t> nameList;
986 ast_ptr<ExpListLow_t, true> valueList;
987AST_END(export_values)
988
989AST_LEAF(export_op)
990AST_END(export_op)
991
992AST_NODE(Export)
993 ast_ptr<ast_node> item; // ClassDecl_t | export_op_t | export_values_t
994AST_END(Export)
995
996AST_NODE(variable_pair)
997 ast_ptr<Name_t> name;
998AST_END(variable_pair)
999
1000AST_NODE(normal_pair)
1001 ast_ptr<ast_node> key; // KeyName_t | [Exp_t] | DoubleString_t | SingleString_t
1002 ast_ptr<ast_node> value; // Exp_t | TableBlock_t
1003AST_END(normal_pair)
1004
1005AST_NODE(KeyValue)
1006 ast_ptr<ast_node> item; // variable_pair_t | normal_pair_t
1007AST_END(KeyValue)
1008
1009AST_NODE(FnArgDef)
1010 ast_ptr<ast_node> name; // Name_t | SelfName_t
1011 ast_ptr<Exp_t, true> defaultValue;
1012AST_END(FnArgDef)
1013
1014AST_NODE(FnArgDefList)
1015 ast_ptr<Seperator_t> sep;
1016 ast_list<FnArgDef_t> definitions;
1017 ast_ptr<VarArg_t, true> varArg;
1018AST_END(FnArgDefList)
1019
1020AST_NODE(outer_var_shadow)
1021 ast_ptr<NameList_t, true> varList;
1022AST_END(outer_var_shadow)
1023
1024AST_NODE(FnArgsDef)
1025 ast_ptr<FnArgDefList_t, true> defList;
1026 ast_ptr<outer_var_shadow_t, true> shadowOption;
1027AST_END(FnArgsDef)
1028
1029AST_LEAF(fn_arrow)
1030AST_END(fn_arrow)
1031
1032AST_NODE(FunLit)
1033 ast_ptr<FnArgsDef_t, true> argsDef;
1034 ast_ptr<fn_arrow_t> arrow;
1035 ast_ptr<Body_t, true> body;
1036AST_END(FunLit)
1037
1038AST_NODE(NameOrDestructure)
1039 ast_ptr<ast_node> item; // Name_t | TableLit_t
1040AST_END(NameOrDestructure)
1041
1042AST_NODE(AssignableNameList)
1043 ast_ptr<Seperator_t> sep;
1044 ast_list<NameOrDestructure_t> items;
1045AST_END(AssignableNameList)
1046
1047AST_NODE(ArgBlock)
1048 ast_ptr<Seperator_t> sep;
1049 ast_list<Exp_t> arguments;
1050AST_END(ArgBlock)
1051
1052AST_NODE(invoke_args_with_table)
1053 ast_ptr<ArgBlock_t, true> argBlock;
1054 ast_ptr<TableBlock_t, true> tableBlock;
1055AST_END(invoke_args_with_table)
1056
1057AST_NODE(InvokeArgs)
1058 ast_ptr<ExpList_t, true> argsList;
1059 ast_ptr<invoke_args_with_table_t, true> argsTableBlock;
1060 ast_ptr<TableBlock_t, true> tableBlock;
1061AST_END(InvokeArgs)
1062
1063AST_LEAF(const_value)
1064AST_END(const_value)
1065
1066AST_NODE(unary_exp)
1067 ast_ptr<Exp_t> item;
1068AST_END(unary_exp)
1069
1070AST_NODE(SimpleValue)
1071 ast_ptr<ast_node> value; /*
1072 const_value_t |
1073 If_t | Unless_t | Switch_t | With_t | ClassDecl_t | ForEach_t | For_t | While_t | Do_t |
1074 unary_exp_t |
1075 TblComprehension_t | TableLit_t | Comprehension_t | FunLit_t | Num_t;
1076 */
1077AST_END(SimpleValue)
1078
1079AST_NODE(Assignment)
1080 ast_ptr<ExpList_t> assignable;
1081 ast_ptr<ast_node> target; // Update_t | Assign_t
1082AST_END(Assignment)
1083
1084AST_NODE(if_else_line)
1085 ast_ptr<Exp_t> condition;
1086 ast_ptr<ast_node> elseExpr; // Exp_t | default_value_t
1087AST_END(if_else_line)
1088
1089AST_NODE(unless_line)
1090 ast_ptr<Exp_t> condition;
1091AST_END(unless_line)
1092
1093AST_NODE(statement_appendix)
1094 ast_ptr<ast_node> item; // if_else_line_t | unless_line_t | CompInner_t
1095AST_END(statement_appendix)
1096
1097AST_LEAF(BreakLoop)
1098AST_END(BreakLoop)
1099
1100AST_NODE(Statement)
1101 ast_ptr<ast_node> body; /*
1102 Import_t | While_t | With_t | For_t | ForEach_t |
1103 Switch_t | Return_t | Local_t | Export_t | BreakLoop_t |
1104 Assignment_t | ExpList_t
1105 */
1106 ast_ptr<statement_appendix_t, true> appendix;
1107
1108 virtual void construct(ast_stack& st) override
1109 {
1110 stringstream stream;
1111 for (input::iterator it = m_begin.m_it; it != m_end.m_it; ++it)
1112 {
1113 stream << (char)*it;
1114 }
1115 value = stream.str();
1116 ast_container::construct(st);
1117 }
1118
1119 virtual void visit(void* ud) override
547 { 1120 {
548 cout << _value << '\n'; 1121 cout << value << '\n';
549 } 1122 }
550private: 1123 string value;
551 string _value; 1124AST_END(Statement)
552};
553 1125
554rule ExprEnd = Block >> eof(); 1126class Block_t;
1127
1128AST_NODE(Body)
1129 ast_ptr<ast_node> content; // Block | Statement
1130AST_END(Body)
1131
1132AST_NODE(Line)
1133 ast_ptr<Statement_t, true> statment;
1134 int line;
1135
1136 virtual void construct(ast_stack& st) override
1137 {
1138 ast_container::construct(st);
1139 line = m_begin.m_line;
1140 }
555 1141
556ast<AstNode> testNode(ExprEnd); 1142 virtual void visit(void* ud) override
1143 {
1144 if (statment)
1145 {
1146 cout << line << ": ";
1147 statment->visit(ud);
1148 }
1149 }
1150AST_END(Line)
1151
1152AST_NODE(Block)
1153 ast_ptr<Seperator_t> sep;
1154 ast_list<Line_t> lines;
1155
1156 virtual void visit(void* ud) override
1157 {
1158 for (auto item : lines.objects())
1159 {
1160 item->visit(ud);
1161 }
1162 }
1163AST_END(Block)
557 1164
558int main() 1165int main()
559{ 1166{
@@ -561,11 +1168,13 @@ int main()
561 input i(s.begin(), s.end()); 1168 input i(s.begin(), s.end());
562 1169
563 error_list el; 1170 error_list el;
564 AstNode* root = nullptr; 1171 Block_t* root = nullptr;
565 State st; 1172 State st;
566 if (parse(i, ExprEnd, el, root, &st)) 1173 if (parse(i, BlockEnd, el, root, &st))
567 { 1174 {
568 cout << "matched!\n"; 1175 cout << "matched!\n";
1176 Data data;
1177 root->visit(&data);
569 } 1178 }
570 else 1179 else
571 { 1180 {
diff --git a/MoonParser/parser.hpp b/MoonParser/parser.hpp
index 540a51c..5ec92af 100644
--- a/MoonParser/parser.hpp
+++ b/MoonParser/parser.hpp
@@ -140,6 +140,7 @@ public:
140 140
141 ///empty constructor. 141 ///empty constructor.
142 input_range() {} 142 input_range() {}
143 virtual ~input_range() {}
143 144
144 /** constructor. 145 /** constructor.
145 @param b begin position. 146 @param b begin position.