From 9e63302e5906d53d9f39f64c549b9aa7e806b669 Mon Sep 17 00:00:00 2001 From: Li Jin Date: Sun, 16 Jul 2017 17:05:31 +0800 Subject: AST generating succeeded. --- MoonParser/ast.cpp | 1 - MoonParser/ast.hpp | 83 ++++- MoonParser/main.cpp | 835 +++++++++++++++++++++++++++++++++++++++++++------- MoonParser/parser.hpp | 1 + 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() { /** parses the given input. @param i input. @param g root rule of grammar. - @param ws whitespace rule. @param el list of errors. @param ud user data, passed to the parse procedures. @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: @param st stack. */ virtual void construct(ast_stack &st) {} - + + /** interface for visiting AST tree use. + @param user_data vector for storing user data. + */ + virtual void visit(void* user_data) {} private: //parent ast_node *m_parent; template friend class ast_ptr; + template friend class ast_choice; template friend class ast_list; template friend class ast; }; @@ -240,7 +245,10 @@ public: */ virtual void construct(ast_stack &st) { //check the stack node - if (st.empty()) throw std::logic_error("invalid AST stack"); + if (st.empty()) { + if (OPT) return; + else throw std::logic_error("invalid AST stack"); + } //get the node ast_node *node = st.back(); @@ -277,6 +285,77 @@ private: } }; +template class ast_choice : public ast_member { +public: + ast_choice(ast_node *obj = 0) : m_ptr(obj) { + _set_parent(); + } + + ast_choice(const ast_choice &src) : + m_ptr(src.m_ptr ? new ast_node(*src.m_ptr) : 0) + { + _set_parent(); + } + + ~ast_choice() { + delete m_ptr; + } + + ast_choice &operator = (const ast_node *obj) { + delete m_ptr; + m_ptr = obj ? new ast_node(*obj) : 0; + _set_parent(); + return *this; + } + + ast_choice &operator = (const ast_choice &src) { + delete m_ptr; + m_ptr = src.m_ptr ? new ast_node(*src.m_ptr) : 0; + _set_parent(); + return *this; + } + + ast_node *get() const { + return m_ptr; + } + + operator ast_node *() const { + return m_ptr; + } + + ast_node *operator ->() const { + assert(m_ptr); + return m_ptr; + } + + virtual void construct(ast_stack &st) { + if (st.empty()) { + throw std::logic_error("invalid AST stack"); + } + + ast_node *node = st.back(); + ast_node *obj = nullptr; + + using swallow = bool[]; + (void)swallow{obj || (obj = dynamic_cast(node))...}; + + if (!obj) throw std::logic_error("invalid AST node"); + + st.pop_back(); + + delete m_ptr; + m_ptr = obj; + _set_parent(); + } + +private: + //ptr + ast_node *m_ptr; + + void _set_parent() { + if (m_ptr) m_ptr->m_parent = container(); + } +}; /** A list of objects. 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; #include #include using std::stringstream; +#include +using std::vector; #include "parserlib.hpp" using namespace parserlib; @@ -27,6 +29,7 @@ struct State indents.push(0); stringOpen = -1; } + stringstream buffer; size_t stringOpen; stack indents; stack doStack; @@ -39,10 +42,15 @@ struct State }; }; +struct Data +{ + vector bytes; +}; + rule Any = any(); -rule White = *set(" \t\r\n"); rule plain_space = *set(" \t"); rule Break = nl(-expr('\r') >> '\n'); +rule White = *(set(" \t\r") | Break); rule Stop = Break | eof(); rule Comment = "--" >> *(not_(set("\r\n")) >> Any) >> and_(Stop); rule Indent = *set(" \t"); @@ -68,7 +76,7 @@ rule _Num = ); rule Num = Space >> _Num; rule Cut = false_(); -rule Nothing = true_(); +rule Seperator = true_(); #define sym(str) (Space >> str) #define symx(str) expr(str) @@ -79,11 +87,12 @@ rule Nothing = true_(); rule Name = user(SpaceName, [](const item_t& item) { - stringstream stream; - for (input_it i = item.begin; i != item.end; ++i) stream << static_cast(*i); - string name; - stream >> name; State* st = reinterpret_cast(item.user_data); + for (input_it i = item.begin; i != item.end; ++i) st->buffer << static_cast(*i); + string name; + st->buffer >> name; + st->buffer.str(""); + st->buffer.clear(); auto it = st->keywords.find(name); return it == st->keywords.end(); }); @@ -172,11 +181,12 @@ rule InBlock = Advance >> Block >> PopIndent; extern rule NameList; -rule Local = key("local") >> (op('*') | op('^') | NameList); +rule local_flag = op('*') | op('^'); +rule Local = key("local") >> (local_flag | NameList); rule colon_import_name = sym('\\') >> Name; rule ImportName = colon_import_name | Name; -rule ImportNameList = *SpaceBreak >> ImportName >> *((+SpaceBreak | sym(',') >> *SpaceBreak) >> ImportName); +rule ImportNameList = Seperator >> *SpaceBreak >> ImportName >> *((+SpaceBreak | sym(',') >> *SpaceBreak) >> ImportName); extern rule Exp; @@ -185,7 +195,7 @@ rule BreakLoop = key("break") | key("continue"); extern rule ExpListLow, ExpList, Assign; -rule Return = key("return") >> (ExpListLow | Nothing); +rule Return = key("return") >> -ExpListLow; rule WithExp = ExpList >> -Assign; extern rule DisableDo, PopDo, Body; @@ -195,7 +205,7 @@ rule SwitchCase = key("when") >> ExpList >> -key("then") >> Body; rule SwitchElse = key("else") >> Body; rule SwitchBlock = *EmptyLine >> - Advance >> + Advance >> Seperator >> SwitchCase >> *(+Break >> SwitchCase) >> -(+Break >> SwitchElse) >> @@ -208,12 +218,13 @@ rule Switch = key("switch") >> rule IfCond = Exp >> -Assign; rule IfElseIf = -(Break >> *EmptyLine >> CheckIndent) >> key("elseif") >> IfCond >> -key("then") >> Body; rule IfElse = -(Break >> *EmptyLine >> CheckIndent) >> key("else") >> Body; -rule If = key("if") >> IfCond >> -key("then") >> Body >> *IfElseIf >> -IfElse; -rule Unless = key("unless") >> IfCond >> -key("then") >> Body >> *IfElseIf >> -IfElse; +rule If = key("if") >> IfCond >> -key("then") >> Body >> Seperator >> *IfElseIf >> -IfElse; +rule Unless = key("unless") >> IfCond >> -key("then") >> Body >> Seperator >> *IfElseIf >> -IfElse; rule While = key("while") >> DisableDo >> ensure(Exp, PopDo) >> -key("do") >> Body; -rule for_args = Name >> sym('=') >> Exp >> sym(',') >> Exp >> (sym(',') >> Exp | Nothing); +rule for_step_value = sym(',') >> Exp; +rule for_args = Name >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value; rule For = key("for") >> DisableDo >> ensure(for_args, PopDo) >> @@ -250,21 +261,22 @@ rule PopDo = user(true_(), [](const item_t& item) extern rule CompInner; rule Comprehension = sym('[') >> Exp >> CompInner >> sym(']'); -rule TblComprehension = sym('{') >> (Exp >> -(sym(',') >> Exp)) >> CompInner >> sym('}'); +rule comp_value = sym(',') >> Exp; +rule TblComprehension = sym('{') >> (Exp >> -comp_value) >> CompInner >> sym('}'); extern rule CompForEach, CompFor, CompClause; -rule CompInner = (CompForEach | CompFor) >> *CompClause; -rule CompForEach = key("for") >> AssignableNameList >> key("in") >> (sym('*') >> Exp | Exp); -rule CompFor = key("for") >> Name >> sym('=') >> Exp >> sym(',') >> Exp >> (sym(',') >> Exp | Nothing); +rule CompInner = (CompForEach | CompFor) >> Seperator >> *CompClause; +rule star_exp = sym('*') >> Exp; +rule CompForEach = key("for") >> AssignableNameList >> key("in") >> (star_exp | Exp); +rule CompFor = key("for") >> Name >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value; rule CompClause = CompFor | CompForEach | key("when") >> Exp; extern rule TableBlock; rule Assign = sym('=') >> (With | If | Switch | TableBlock | ExpListLow); -rule Update = -( +rule update_op = sym("..=") | sym("+=") | sym("-=") | @@ -276,8 +288,9 @@ rule Update = sym("&=") | sym("|=") | sym(">>=") | - sym("<<=") -) >> Exp; + sym("<<="); + +rule Update = update_op >> Exp; rule CharOperators = Space >> set("+-*/%^><|&"); rule WordOperators = @@ -301,16 +314,17 @@ rule Assignable = Chain | Name | SelfName; extern rule Value; -rule Exp = Value >> *(BinaryOperator >> Value); +rule exp_op_value = BinaryOperator >> Value; +rule Exp = Value >> *exp_op_value; extern rule Callable, InvokeArgs; -rule ChainValue = (Chain | Callable) >> (InvokeArgs | Nothing); +rule ChainValue = (Chain | Callable) >> -InvokeArgs; -extern rule KeyValueList, String, SimpleValue; +extern rule KeyValue, String, SimpleValue; -rule Value = SimpleValue | KeyValueList | ChainValue | String; -rule SliceValue = Exp; +rule simple_table = Seperator >> KeyValue >> *(sym(',') >> KeyValue); +rule Value = SimpleValue | simple_table | ChainValue | String; extern rule LuaString; @@ -319,7 +333,8 @@ rule SingleString = symx('\'') >> *single_string_inner >> sym('\''); rule interp = symx("#{") >> Exp >> sym('}'); rule double_string_plain = expr("\\\"") | "\\\\" | not_(expr('"')) >> Any; rule double_string_inner = +(not_(interp) >> double_string_plain); -rule DoubleString = symx('"') >> *(double_string_inner | interp) >> sym('"'); +rule double_string_content = double_string_inner | interp; +rule DoubleString = symx('"') >> Seperator >> *double_string_content >> sym('"'); rule String = Space >> (DoubleString | SingleString | LuaString); rule lua_string_open = '[' >> *expr('=') >> '['; @@ -340,7 +355,7 @@ rule LuaStringClose = user(lua_string_close, [](const item_t& item) return st->stringOpen == count; }); -rule LuaStringContent = *(not_(LuaStringClose) >> Any); +rule LuaStringContent = *(not_(LuaStringClose) >> (Break | Any)); rule LuaString = user(LuaStringOpen >> -Break >> LuaStringContent >> LuaStringClose, [](const item_t& item) { @@ -353,18 +368,20 @@ rule Parens = sym('(') >> *SpaceBreak >> Exp >> *SpaceBreak >> sym(')'); rule Callable = Name | SelfName | VarArg | Parens; rule FnArgsExpList = Exp >> *((Break | sym(',')) >> White >> Exp); -rule FnArgs = +rule FnArgs = Seperator >> ( - symx('(') >> *SpaceBreak >> (FnArgsExpList | Nothing) >> *SpaceBreak >> sym(')') -) | ( - sym('!') >> not_(expr('=')) >> Nothing + ( + symx('(') >> *SpaceBreak >> -FnArgsExpList >> *SpaceBreak >> sym(')') + ) | ( + sym('!') >> not_(expr('=')) + ) ); extern rule ChainItems, DotChainItem, ColonChain; rule chain_call = (Callable | String) >> ChainItems; rule chain_item = not_(set(".\\")) >> ChainItems; -rule chain_dot_chain = DotChainItem >> (ChainItems | Nothing); +rule chain_dot_chain = DotChainItem >> -ChainItems; rule Chain = chain_call | @@ -373,23 +390,24 @@ rule Chain = extern rule ChainItem; -rule chain_items = +ChainItem >> (ColonChain | Nothing); -rule ChainItems = chain_items | ColonChain; +rule chain_with_colon = +ChainItem >> -ColonChain; +rule ChainItems = Seperator >> (chain_with_colon | ColonChain); extern rule Invoke, Slice; rule ChainItem = Invoke | DotChainItem | Slice | symx('[') >> Exp >> sym(']'); rule DotChainItem = symx('.') >> _Name; rule ColonChainItem = symx('\\') >> _Name; -rule ColonChain = ColonChainItem >> ((Invoke >> (ChainItems | Nothing)) | Nothing >> Nothing); +rule invoke_chain = Invoke >> -ChainItems; +rule ColonChain = ColonChainItem >> -invoke_chain; +rule default_value = true_(); rule Slice = symx('[') >> - (SliceValue | Nothing) >> + (Exp | default_value) >> sym(',') >> - (SliceValue | Nothing) >> - (sym(',') >> - SliceValue | Nothing) >> + (Exp | default_value) >> + (sym(',') >> Exp | default_value) >> sym(']'); rule Invoke = @@ -398,17 +416,17 @@ rule Invoke = DoubleString | and_(expr('[')) >> LuaString; -extern rule KeyValue, TableValueList, TableLitLine; +extern rule TableValueList, TableLitLine; rule TableValue = KeyValue | Exp; rule table_lit_lines = SpaceBreak >> TableLitLine >> *(-sym(',') >> SpaceBreak >> TableLitLine) >> -sym(','); rule TableLit = - sym('{') >> - (TableValueList | Nothing) >> + sym('{') >> Seperator >> + -TableValueList >> -sym(',') >> - (table_lit_lines | Nothing) >> + -table_lit_lines >> White >> sym('}'); rule TableValueList = TableValue >> *(sym(',') >> TableValue); @@ -417,143 +435,732 @@ rule TableLitLine = ( PushIndent >> (TableValueList >> PopIndent | PopIndent) ) | ( - Space >> Nothing + Space ); extern rule KeyValueLine; -rule TableBlockInner = KeyValueLine >> *(+(SpaceBreak) >> KeyValueLine); +rule TableBlockInner = Seperator >> KeyValueLine >> *(+(SpaceBreak) >> KeyValueLine); rule TableBlock = +(SpaceBreak) >> Advance >> ensure(TableBlockInner, PopIndent); extern rule Statement; -rule ClassLine = CheckIndent >> (KeyValueList | Statement | Exp) >> -sym(','); -rule ClassBlock = +(SpaceBreak) >> Advance >> ClassLine >> *(+(SpaceBreak) >> ClassLine) >> PopIndent; +rule class_member_list = Seperator >> KeyValue >> *(sym(',') >> KeyValue); +rule ClassLine = CheckIndent >> (class_member_list | Statement | Exp) >> -sym(','); +rule ClassBlock = +(SpaceBreak) >> Advance >>Seperator >> ClassLine >> *(+(SpaceBreak) >> ClassLine) >> PopIndent; rule ClassDecl = key("class") >> not_(expr(':')) >> - (Assignable | Nothing) >> - (key("extends") >> PreventIndent >> ensure(Exp, PopIndent) | Nothing) >> - (ClassBlock | Nothing); + -Assignable >> + -(key("extends") >> PreventIndent >> ensure(Exp, PopIndent)) >> + -ClassBlock; + +rule export_values = NameList >> -(sym('=') >> ExpListLow); +rule export_op = op('*') | op('^'); +rule Export = key("export") >> (ClassDecl | export_op | export_values); -rule export_values = sym('=') >> ExpListLow; -rule Export = key("export") >> (ClassDecl | op('*') | op('^') | NameList >> (export_values | Nothing)); +rule variable_pair = sym(':') >> not_(SomeSpace) >> Name; -rule KeyValue = +rule normal_pair = ( - sym(':') >> not_(SomeSpace) >> Name -) | ( - (KeyName | - sym('[') >> Exp >> sym(']') | - Space >> DoubleString | - Space >> SingleString - ) >> - symx(':') >> - (Exp | TableBlock | +(SpaceBreak) >> Exp) -); + KeyName | + sym('[') >> Exp >> sym(']') | + Space >> DoubleString | + Space >> SingleString +) >> +symx(':') >> +(Exp | TableBlock | +(SpaceBreak) >> Exp); + +rule KeyValue = variable_pair | normal_pair; rule KeyValueList = KeyValue >> *(sym(',') >> KeyValue); rule KeyValueLine = CheckIndent >> KeyValueList >> -sym(','); -rule FnArgDef = (Name | SelfName) >> (sym('=') >> Exp | Nothing); +rule FnArgDef = (Name | SelfName) >> -(sym('=') >> Exp); -rule FnArgDefList = +rule FnArgDefList = Seperator >> ( - FnArgDef >> - *((sym(',') | Break) >> White >> FnArgDef) >> - ((sym(',') | Break) >> White >> VarArg | Nothing) -) | ( - VarArg + ( + FnArgDef >> + *((sym(',') | Break) >> White >> FnArgDef) >> + -((sym(',') | Break) >> White >> VarArg) + ) | ( + VarArg + ) ); -rule outer_value_shadow = key("using") >> (NameList | Space >> expr("nil")); +rule outer_var_shadow = key("using") >> (NameList | Space >> expr("nil")); -rule normal_fn_args_def = - sym('(') >> White >> (FnArgDefList | Nothing) >> (outer_value_shadow | Nothing) >> White >> sym(')'); +rule FnArgsDef = sym('(') >> White >> -FnArgDefList >> -outer_var_shadow >> White >> sym(')'); +rule fn_arrow = sym("->") | sym("=>"); +rule FunLit = -FnArgsDef >> fn_arrow >> -Body; -rule FnArgsDef = normal_fn_args_def | Nothing; -rule fn_arrow = sym("->"); -rule fat_arrow = sym("=>"); -rule FunLit = FnArgsDef >> (fn_arrow | fat_arrow) >> (Body | Nothing); - -rule NameList = Name >> *(sym(',') >> Name); +rule NameList = Seperator >> Name >> *(sym(',') >> Name); rule NameOrDestructure = Name | TableLit; -rule AssignableNameList = NameOrDestructure >> *(sym(',') >> NameOrDestructure); +rule AssignableNameList = Seperator >> NameOrDestructure >> *(sym(',') >> NameOrDestructure); -rule ExpList = Exp >> *(sym(',') >> Exp); -rule ExpListLow = Exp >> *((sym(',') | sym(';')) >> Exp); +rule ExpList = Seperator >> Exp >> *(sym(',') >> Exp); +rule ExpListLow = Seperator >> Exp >> *((sym(',') | sym(';')) >> Exp); -rule ArgLine = CheckIndent >> ExpList; -rule ArgBlock = ArgLine >> *(sym(',') >> SpaceBreak >> ArgLine) >> PopIndent; +rule ArgLine = CheckIndent >> Exp >> *(sym(',') >> Exp); +rule ArgBlock = Seperator >> ArgLine >> *(sym(',') >> SpaceBreak >> ArgLine) >> PopIndent; rule invoke_args_with_table = sym(',') >> ( - TableBlock >> Nothing | - SpaceBreak>> Advance >> ArgBlock >> (TableBlock | Nothing) + TableBlock | + SpaceBreak >> Advance >> ArgBlock >> -TableBlock ); rule InvokeArgs = not_(expr('-')) >> ( - ExpList >> (invoke_args_with_table | TableBlock | Nothing) | - TableBlock >> Nothing + ExpList >> -(invoke_args_with_table | TableBlock) | + TableBlock ); +rule const_value = key("nil") | key("true") | key("false"); +rule minus_exp = sym('-') >> not_(SomeSpace) >> Exp; +rule sharp_exp = sym('#') >> Exp; +rule tilde_exp = sym('~') >> Exp; +rule not_exp = key("not") >> Exp; +rule unary_exp = minus_exp | sharp_exp | tilde_exp | not_exp; + rule SimpleValue = - key("nil") | key("true") | key("false") | + const_value | If | Unless | Switch | With | ClassDecl | ForEach | For | While | Do | - sym('-') >> not_(SomeSpace) >> Exp | - sym('#') >> Exp | - sym('~') >> Exp | - key("not") >> Exp | + unary_exp | TblComprehension | TableLit | Comprehension | FunLit | Num; rule Assignment = ExpList >> (Update | Assign); -rule if_else_line = key("if") >> Exp >> (key("else") >> Exp | Nothing); +rule if_else_line = key("if") >> Exp >> (key("else") >> Exp | default_value); rule unless_line = key("unless") >> Exp; +rule statement_appendix = (if_else_line | unless_line | CompInner) >> Space; rule Statement = ( Import | While | With | For | ForEach | Switch | Return | Local | Export | BreakLoop | Assignment | ExpList ) >> Space >> -( - (if_else_line | unless_line | CompInner) >> Space | Nothing -); +-statement_appendix; rule Body = -Space >> Break >> *EmptyLine >> InBlock | Statement; rule empty_line_stop = Space >> and_(Stop); rule Line = CheckIndent >> Statement | empty_line_stop; -rule Block = Line >> *(+Break >> Line); -rule BlockWithEnd = Block >> eof(); +rule Block = Seperator >> Line >> *(+Break >> Line); +rule BlockEnd = Block >> eof(); -class AstNode : public ast_container -{ +#define AST_LEAF(type) \ +class type##_t : public ast_node \ +{ \ +public: + +#define AST_NODE(type) \ +class type##_t : public ast_container \ +{ \ public: - virtual void construct(ast_stack& st) + +#define AST_END(type) \ +}; \ +ast __##type##_t(type); + +AST_LEAF(Num) + double value; + virtual void visit(void* ud) override + { + stringstream stream; + for (input::iterator it = m_begin.m_it; it != m_end.m_it; ++it) + { + stream << static_cast(*it); + } + stream >> value; + cout << value << '\n'; + } +AST_END(Num) + +AST_LEAF(_Name) + virtual void construct(ast_stack& st) override { stringstream stream; for (input::iterator it = m_begin.m_it; it != m_end.m_it; ++it) { stream << (char)*it; } - _value = stream.str(); + stream >> value; + ast_node::construct(st); } - void print() + string value; +AST_END(_Name) + +AST_NODE(Name) + ast_ptr<_Name_t> name; +AST_END(Name) + +AST_LEAF(self) +AST_END(self) + +AST_NODE(self_name) + ast_ptr<_Name_t> name; +AST_END(self_name) + +AST_LEAF(self_class) +AST_END(self_class) + +AST_NODE(self_class_name) + ast_ptr<_Name_t> name; +AST_END(self_class_name) + +AST_NODE(SelfName) + ast_ptr name; +AST_END(SelfName) + +AST_NODE(KeyName) + ast_ptr name; +AST_END(KeyName) + +AST_LEAF(VarArg) +AST_END(VarArg) + +AST_LEAF(local_flag) +AST_END(local_flag) + +AST_LEAF(Seperator) +AST_END(Seperator) + +AST_NODE(NameList) + ast_ptr sep; + ast_list names; +AST_END(NameList) + +AST_NODE(Local) + ast_ptr name; // local_flag_t | NameList_t +AST_END(Local) + +AST_NODE(colon_import_name) + ast_ptr name; +AST_END(colon_import_name) + +class Exp_t; + +AST_NODE(ImportName) + ast_ptr name; // colon_import_name_t | Name_t +AST_END(ImportName) + +AST_NODE(Import) + ast_ptr sep; + ast_list names; + ast_ptr exp; +AST_END(Import) + +AST_NODE(ExpListLow) + ast_ptr sep; + ast_list exprs; +AST_END(ExpListLow) + +AST_NODE(ExpList) + ast_ptr sep; + ast_list exprs; +AST_END(ExpList) + +AST_NODE(Return) + ast_ptr valueList; +AST_END(Return) + +class Assign_t; +class Body_t; + +AST_NODE(With) + ast_ptr valueList; + ast_ptr assigns; + ast_ptr body; +AST_END(With) + +AST_NODE(SwitchCase) + ast_ptr valueList; + ast_ptr body; +AST_END(SwitchCase) + +AST_NODE(Switch) + ast_ptr target; + ast_ptr sep; + ast_list branches; + ast_ptr lastBranch; +AST_END(Switch) + +AST_NODE(IfCond) + ast_ptr condition; + ast_ptr assign; +AST_END(IfCond) + +AST_NODE(IfElseIf) + ast_ptr condition; + ast_ptr body; +AST_END(IfElseIf) + +AST_NODE(If) + ast_ptr firstCondition; + ast_ptr firstBody; + ast_ptr sep; + ast_list branches; + ast_ptr lastBranch; +AST_END(If) + +AST_NODE(Unless) + ast_ptr firstCondition; + ast_ptr firstBody; + ast_ptr sep; + ast_list branches; + ast_ptr lastBranch; +AST_END(Unless) + +AST_NODE(While) + ast_ptr condition; + ast_ptr body; +AST_END(While) + +AST_NODE(for_step_value) + ast_ptr value; +AST_END(for_step_value) + +AST_NODE(For) + ast_ptr varName; + ast_ptr startValue; + ast_ptr stopValue; + ast_ptr stepValue; + ast_ptr body; +AST_END(For) + +class AssignableNameList_t; + +AST_NODE(ForEach) + ast_ptr nameList; + ast_ptr loopValue; // Exp_t | ExpList_t + ast_ptr body; +AST_END(ForEach) + +AST_NODE(Do) + ast_ptr body; +AST_END(Do) + +class CompInner_t; + +AST_NODE(Comprehension) + ast_ptr value; + ast_ptr forLoop; +AST_END(Comprehension) + +AST_NODE(comp_value) + ast_ptr value; +AST_END(comp_value) + +AST_NODE(TblComprehension) + ast_ptr key; + ast_ptr value; + ast_ptr forLoop; +AST_END(TblComprehension) + +AST_NODE(star_exp) + ast_ptr value; +AST_END(star_exp) + +AST_NODE(CompForEach) + ast_ptr nameList; + ast_ptr loopValue; // star_exp_t | Exp_t +AST_END(CompForEach) + +AST_NODE(CompFor) + ast_ptr varName; + ast_ptr startValue; + ast_ptr stopValue; + ast_ptr stepValue; +AST_END(CompFor) + +AST_NODE(CompClause) + ast_ptr nestExp; // CompFor_t | CompForEach_t | Exp_t +AST_END(CompClause) + +AST_NODE(CompInner) + ast_ptr compFor; // CompFor_t | CompForEach_t + ast_ptr sep; + ast_list clauses; +AST_END(CompInner) + +class TableBlock_t; + +AST_NODE(Assign) + ast_ptr value; // With_t | If_t | Switch_t | TableBlock_t | ExpListLow_t +AST_END(Assign) + +AST_LEAF(update_op) +AST_END(update_op) + +AST_NODE(Update) + ast_ptr op; + ast_ptr value; +AST_END(Update) + +AST_LEAF(BinaryOperator) +AST_END(BinaryOperator) + +class Chain_t; + +AST_NODE(Assignable) + ast_ptr item; // Chain_t | Name_t | SelfName_t +AST_END(Assignable) + +class Value_t; + +AST_NODE(exp_op_value) + ast_ptr op; + ast_ptr value; +AST_END(exp_op_value) + +AST_NODE(Exp) + ast_ptr value; + ast_list opValues; +AST_END(Exp) + +AST_NODE(Callable) + ast_ptr item; // Name_t | SelfName_t | VarArg_t | Parens_t +AST_END(Callable) + +class InvokeArgs_t; + +AST_NODE(ChainValue) + ast_ptr caller; // Chain_t | Callable_t + ast_ptr arguments; +AST_END(ChainValue) + +class KeyValue_t; + +AST_NODE(simple_table) + ast_ptr sep; + ast_list pairs; +AST_END(simple_table) + +class String_t; +class SimpleValue_t; + +AST_NODE(Value) + ast_ptr item; // SimpleValue_t | simple_table_t | ChainValue_t | String_t +AST_END(Value) + +AST_LEAF(LuaString) +AST_END(LuaString) + +AST_LEAF(SingleString) +AST_END(SingleString) + +AST_LEAF(double_string_inner) +AST_END(double_string_inner) + +AST_NODE(double_string_content) + ast_ptr content; // double_string_inner_t | Exp_t +AST_END(double_string_content) + +AST_NODE(DoubleString) + ast_ptr sep; + ast_list segments; +AST_END(DoubleString) + +AST_NODE(String) + ast_ptr str; // DoubleString_t | SingleString_t | LuaString_t +AST_END(String) + +AST_NODE(Parens) + ast_ptr expr; +AST_END(Parens) + +AST_NODE(FnArgs) + ast_ptr sep; + ast_list args; +AST_END(FnArgs) + +class ChainItems_t; + +AST_NODE(chain_call) + ast_ptr caller; // Callable_t | String_t + ast_ptr chain; +AST_END(chain_call) + +AST_NODE(chain_item) + ast_ptr chain; +AST_END(chain_item) + +AST_NODE(DotChainItem) + ast_ptr<_Name_t> name; +AST_END(DotChainItem) + +AST_NODE(ColonChainItem) + ast_ptr<_Name_t> name; +AST_END(ColonChainItem) + +AST_NODE(chain_dot_chain) + ast_ptr caller; + ast_ptr chain; +AST_END(chain_dot_chain) + +class ColonChain_t; + +AST_NODE(Chain) + ast_ptr item; // chain_call_t | chain_item_t | chain_dot_chain_t | ColonChain_t +AST_END(Chain) + +class Invoke_t; +class Slice_t; + +AST_NODE(ChainItem) + ast_ptr item; // Invoke_t | DotChainItem_t | Slice_t | [Exp_t] +AST_END(ChainItem) + +AST_NODE(ChainItems) + ast_ptr sep; + ast_list simpleChain; + ast_ptr colonChain; +AST_END(ChainItems) + +AST_NODE(invoke_chain) + ast_ptr invoke; + ast_ptr chain; +AST_END(invoke_chain) + +AST_NODE(ColonChain) + ast_ptr colonChain; + ast_ptr invokeChain; +AST_END(ColonChain) + +AST_LEAF(default_value) +AST_END(default_value) + +AST_NODE(Slice) + ast_ptr startValue; // Exp_t | default_value_t + ast_ptr stopValue; // Exp_t | default_value_t + ast_ptr stepValue; // Exp_t | default_value_t +AST_END(Slice) + +AST_NODE(Invoke) + ast_ptr argument; // FnArgs_t | SingleString_t | DoubleString_t | LuaString_t +AST_END(Invoke) + +class KeyValue_t; + +AST_NODE(TableValue) + ast_ptr value; // KeyValue_t | Exp_t +AST_END(TableValue) + +AST_NODE(TableLit) + ast_ptr sep; + ast_list values; +AST_END(TableLit) + +AST_NODE(TableBlock) + ast_ptr sep; + ast_list values; +AST_END(TableBlock) + +AST_NODE(class_member_list) + ast_ptr sep; + ast_list values; +AST_END(class_member_list) + +AST_NODE(ClassLine) + ast_ptr content; // class_member_list_t | Statement_t | Exp_t +AST_END(ClassLine) + +AST_NODE(ClassBlock) + ast_ptr sep; + ast_list lines; +AST_END(ClassBlock) + +AST_NODE(ClassDecl) + ast_ptr name; + ast_ptr extend; + ast_ptr body; +AST_END(ClassDecl) + +AST_NODE(export_values) + ast_ptr nameList; + ast_ptr valueList; +AST_END(export_values) + +AST_LEAF(export_op) +AST_END(export_op) + +AST_NODE(Export) + ast_ptr item; // ClassDecl_t | export_op_t | export_values_t +AST_END(Export) + +AST_NODE(variable_pair) + ast_ptr name; +AST_END(variable_pair) + +AST_NODE(normal_pair) + ast_ptr key; // KeyName_t | [Exp_t] | DoubleString_t | SingleString_t + ast_ptr value; // Exp_t | TableBlock_t +AST_END(normal_pair) + +AST_NODE(KeyValue) + ast_ptr item; // variable_pair_t | normal_pair_t +AST_END(KeyValue) + +AST_NODE(FnArgDef) + ast_ptr name; // Name_t | SelfName_t + ast_ptr defaultValue; +AST_END(FnArgDef) + +AST_NODE(FnArgDefList) + ast_ptr sep; + ast_list definitions; + ast_ptr varArg; +AST_END(FnArgDefList) + +AST_NODE(outer_var_shadow) + ast_ptr varList; +AST_END(outer_var_shadow) + +AST_NODE(FnArgsDef) + ast_ptr defList; + ast_ptr shadowOption; +AST_END(FnArgsDef) + +AST_LEAF(fn_arrow) +AST_END(fn_arrow) + +AST_NODE(FunLit) + ast_ptr argsDef; + ast_ptr arrow; + ast_ptr body; +AST_END(FunLit) + +AST_NODE(NameOrDestructure) + ast_ptr item; // Name_t | TableLit_t +AST_END(NameOrDestructure) + +AST_NODE(AssignableNameList) + ast_ptr sep; + ast_list items; +AST_END(AssignableNameList) + +AST_NODE(ArgBlock) + ast_ptr sep; + ast_list arguments; +AST_END(ArgBlock) + +AST_NODE(invoke_args_with_table) + ast_ptr argBlock; + ast_ptr tableBlock; +AST_END(invoke_args_with_table) + +AST_NODE(InvokeArgs) + ast_ptr argsList; + ast_ptr argsTableBlock; + ast_ptr tableBlock; +AST_END(InvokeArgs) + +AST_LEAF(const_value) +AST_END(const_value) + +AST_NODE(unary_exp) + ast_ptr item; +AST_END(unary_exp) + +AST_NODE(SimpleValue) + ast_ptr value; /* + const_value_t | + If_t | Unless_t | Switch_t | With_t | ClassDecl_t | ForEach_t | For_t | While_t | Do_t | + unary_exp_t | + TblComprehension_t | TableLit_t | Comprehension_t | FunLit_t | Num_t; + */ +AST_END(SimpleValue) + +AST_NODE(Assignment) + ast_ptr assignable; + ast_ptr target; // Update_t | Assign_t +AST_END(Assignment) + +AST_NODE(if_else_line) + ast_ptr condition; + ast_ptr elseExpr; // Exp_t | default_value_t +AST_END(if_else_line) + +AST_NODE(unless_line) + ast_ptr condition; +AST_END(unless_line) + +AST_NODE(statement_appendix) + ast_ptr item; // if_else_line_t | unless_line_t | CompInner_t +AST_END(statement_appendix) + +AST_LEAF(BreakLoop) +AST_END(BreakLoop) + +AST_NODE(Statement) + ast_ptr body; /* + Import_t | While_t | With_t | For_t | ForEach_t | + Switch_t | Return_t | Local_t | Export_t | BreakLoop_t | + Assignment_t | ExpList_t + */ + ast_ptr appendix; + + virtual void construct(ast_stack& st) override + { + stringstream stream; + for (input::iterator it = m_begin.m_it; it != m_end.m_it; ++it) + { + stream << (char)*it; + } + value = stream.str(); + ast_container::construct(st); + } + + virtual void visit(void* ud) override { - cout << _value << '\n'; + cout << value << '\n'; } -private: - string _value; -}; + string value; +AST_END(Statement) -rule ExprEnd = Block >> eof(); +class Block_t; + +AST_NODE(Body) + ast_ptr content; // Block | Statement +AST_END(Body) + +AST_NODE(Line) + ast_ptr statment; + int line; + + virtual void construct(ast_stack& st) override + { + ast_container::construct(st); + line = m_begin.m_line; + } -ast testNode(ExprEnd); + virtual void visit(void* ud) override + { + if (statment) + { + cout << line << ": "; + statment->visit(ud); + } + } +AST_END(Line) + +AST_NODE(Block) + ast_ptr sep; + ast_list lines; + + virtual void visit(void* ud) override + { + for (auto item : lines.objects()) + { + item->visit(ud); + } + } +AST_END(Block) int main() { @@ -561,11 +1168,13 @@ int main() input i(s.begin(), s.end()); error_list el; - AstNode* root = nullptr; + Block_t* root = nullptr; State st; - if (parse(i, ExprEnd, el, root, &st)) + if (parse(i, BlockEnd, el, root, &st)) { cout << "matched!\n"; + Data data; + root->visit(&data); } else { 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: ///empty constructor. input_range() {} + virtual ~input_range() {} /** constructor. @param b begin position. -- cgit v1.2.3-55-g6feb