From 6ba888e44513f82acb06870bbf07476949eef6da Mon Sep 17 00:00:00 2001 From: Valk Richard Li <48872266+ValKmjolnir@users.noreply.github.com> Date: Wed, 15 Jul 2020 01:59:38 -0700 Subject: [PATCH] update --- version3.0/main.cpp | 21 ++++- version3.0/nasal_ast.h | 21 +++++ version3.0/nasal_enum.h | 74 ++++++++++++++++- version3.0/nasal_parse.h | 175 +++++++++++++++++++++++++++++++++++++-- 4 files changed, 279 insertions(+), 12 deletions(-) diff --git a/version3.0/main.cpp b/version3.0/main.cpp index cf8c1ea..1186cfb 100644 --- a/version3.0/main.cpp +++ b/version3.0/main.cpp @@ -65,6 +65,23 @@ void par_func() return; } +void ast_func() +{ + lexer.scanner(resource.get_file()); + if(!lexer.get_error()) + { + parse.set_toklist(lexer.get_token_list()); + parse.main_process(); + if(parse.get_error()) + std::cout<<">> [parse] error(s) occurred,stop.\n"; + else + parse.get_root().print_ast(0); + } + else + std::cout<<">> [lexer] error(s) occurred,stop.\n"; + return; +} + int main() { #ifdef _WIN32 @@ -116,9 +133,7 @@ int main() else if(command=="par") par_func(); else if(command=="ast") - { - ; - } + ast_func(); else if(command=="run") { ; diff --git a/version3.0/nasal_ast.h b/version3.0/nasal_ast.h index 84f64bb..3f496c8 100644 --- a/version3.0/nasal_ast.h +++ b/version3.0/nasal_ast.h @@ -22,6 +22,7 @@ public: int get_type(); std::string get_str(); std::vector& get_children(); + void print_ast(int); }; nasal_ast::nasal_ast() @@ -110,4 +111,24 @@ std::vector& nasal_ast::get_children() return this->children; } +void nasal_ast::print_ast(int depth) +{ + std::string indentation=""; + for(int i=0;itype); + std::cout<type) + { + case ast_number: std::cout<<":"<str;break; + case ast_string: std::cout<<":"<str;break; + case ast_identifier:std::cout<<":"<str;break; + case ast_call_hash: std::cout<<":"<str;break; + } + std::cout<children.size(); + for(int i=0;ichildren[i].print_ast(depth+1); + return; +} + #endif \ No newline at end of file diff --git a/version3.0/nasal_enum.h b/version3.0/nasal_enum.h index 76d63df..de43987 100644 --- a/version3.0/nasal_enum.h +++ b/version3.0/nasal_enum.h @@ -31,13 +31,79 @@ enum ast_node ast_add,ast_sub,ast_mult,ast_div,ast_link, ast_unary_sub,ast_unary_not, ast_trinocular, - ast_for,ast_forindex,ast_foreach,ast_while, + ast_for,ast_forindex,ast_foreach,ast_while,ast_new_iter, ast_conditional,ast_if,ast_elsif,ast_else, ast_multi_id,ast_multi_scalar, ast_definition,ast_multi_assign, ast_continue,ast_break,ast_return, }; +std::string ast_str(int type) +{ + std::string str=""; + switch(type) + { + case ast_null: str="null";break; + case ast_root: str="root";break; + case ast_block: str="block";break; + case ast_nil: str="nil";break; + case ast_number: str="number";break; + case ast_string: str="string";break; + case ast_identifier: str="id";break; + case ast_function: str="function";break; + case ast_hash: str="hash";break; + case ast_vector: str="vector";break; + case ast_hashmember: str="hashmember";break; + case ast_call: str="call";break; + case ast_call_hash: str="call_hash";break; + case ast_call_vec: str="call_vector";break; + case ast_call_func: str="call_func";break; + case ast_subvec: str="subvec";break; + case ast_args: str="arguments";break; + case ast_default_arg: str="default_arg";break; + case ast_dynamic_id: str="dynamic_id";break; + case ast_and: str="and";break; + case ast_or: str="or";break; + case ast_equal: str="=";break; + case ast_add_equal: str="+=";break; + case ast_sub_equal: str="-=";break; + case ast_mult_equal: str="*=";break; + case ast_div_equal: str="/=";break; + case ast_link_equal: str="~=";break; + case ast_cmp_equal: str="==";break; + case ast_cmp_not_equal:str="!=";break; + case ast_less_than: str="<";break; + case ast_less_equal: str="<=";break; + case ast_greater_than: str=">";break; + case ast_greater_equal:str=">=";break; + case ast_add: str="+";break; + case ast_sub: str="-";break; + case ast_mult: str="*";break; + case ast_div: str="/";break; + case ast_link: str="~";break; + case ast_unary_sub: str="unary-";break; + case ast_unary_not: str="unary!";break; + case ast_trinocular: str="trinocular";break; + case ast_for: str="for";break; + case ast_forindex: str="forindex";break; + case ast_foreach: str="foreach";break; + case ast_while: str="while";break; + case ast_new_iter: str="new_iterator";break; + case ast_conditional: str="conditional";break; + case ast_if: str="if";break; + case ast_elsif: str="elsif";break; + case ast_else: str="else";break; + case ast_multi_id: str="multi_id";break; + case ast_multi_scalar: str="multi_scalar";break; + case ast_definition: str="definition";break; + case ast_multi_assign: str="multi_assignment";break; + case ast_continue: str="continue";break; + case ast_break: str="break";break; + case ast_return: str="return";break; + } + return str; +} + enum parse_error { unknown, @@ -61,7 +127,9 @@ enum parse_error lack_args, default_arg_not_end, dynamic_id_not_end, - multi_assign_lack_val + multi_assign_lack_val, + lack_definition, + lack_loop_iter }; void error_info(int line,int error_type,std::string error_str="") @@ -93,6 +161,8 @@ void error_info(int line,int error_type,std::string error_str="") case default_arg_not_end: detail="default argument missing for parameter of "+error_str+".";break; case dynamic_id_not_end: detail="dynamic id must be the end of "+error_str+".";break; case multi_assign_lack_val:detail="multi-assignment lacks value list.";break; + case lack_definition: detail="expected a definition expression here.";break; + case lack_loop_iter: detail="expected an iterator to loop through.";break; } std::cout<&); void main_process(); + nasal_ast& get_root(); }; int nasal_parse::get_error() @@ -130,8 +134,9 @@ void nasal_parse::main_process() { root.add_child(expr()); ++ptr; - if(ptrptr=0; @@ -214,6 +224,22 @@ bool nasal_parse::check_special_call() return ret; } +bool nasal_parse::need_semi_check(nasal_ast& node) +{ + int type=node.get_type(); + if(type==ast_for || type==ast_foreach || type==ast_forindex || type==ast_while || type==ast_conditional) + return false; + return !check_function_end(node); +} + +nasal_ast nasal_parse::null_node_gen() +{ + nasal_ast node; + node.set_line(tok_list[ptr].line); + node.set_type(ast_null); + return node; +} + nasal_ast nasal_parse::nil_gen() { nasal_ast node; @@ -500,9 +526,9 @@ nasal_ast nasal_parse::exprs_gen() { node.add_child(expr()); ++ptr; - if(ptr>=tok_list_size) break; - if(tok_list[ptr].type==tok_semi) ++ptr; - else if(node.get_children().empty() || !check_function_end(node.get_children().back())) + if(ptr=tok_list_size) + { + ++error; + error_info(error_line,lack_definition); + return node; + } + if(tok_list[ptr].type==tok_semi) + { + node.add_child(null_node_gen()); + --ptr; + } + else if(tok_list[ptr].type==tok_var) + node.add_child(definition()); + else + node.add_child(calculation()); + ++ptr; + if(ptr>=tok_list_size || tok_list[ptr].type!=tok_semi) + { + ++error; + error_info(error_line,lack_semi); + return node; + } + // conditional expression + ++ptr; + if(ptr>=tok_list_size) + { + ++error; + error_info(error_line,lack_calculation); + return node; + } + if(tok_list[ptr].type==tok_semi) + { + node.add_child(null_node_gen()); + --ptr; + } + else + node.add_child(calculation()); + ++ptr; + if(ptr>=tok_list_size || tok_list[ptr].type!=tok_semi) + { + ++error; + error_info(error_line,lack_semi); + return node; + } + //after loop expression + ++ptr; + if(ptr>=tok_list_size) + { + ++error; + error_info(error_line,lack_calculation); + return node; + } + if(tok_list[ptr].type==tok_right_curve) + { + node.add_child(null_node_gen()); + --ptr; + } + else + node.add_child(calculation()); + ++ptr; + if(ptr>=tok_list_size || tok_list[ptr].type!=tok_right_curve) + { + ++error; + error_info(error_line,lack_right_curve); + return node; + } + ++ptr; + node.add_child(exprs_gen()); return node; } nasal_ast nasal_parse::forei_loop() @@ -1142,10 +1236,75 @@ nasal_ast nasal_parse::forei_loop() error_info(error_line,lack_left_curve); return node; } + // first expression + // foreach/forindex must have an iterator to loop through ++ptr; - // unfinished + if(ptr>=tok_list_size || (tok_list[ptr].type!=tok_var && tok_list[ptr].type!=tok_identifier)) + { + ++error; + error_info(error_line,lack_loop_iter); + return node; + } + node.add_child(new_iter_gen()); + ++ptr; + if(ptr>=tok_list_size || tok_list[ptr].type!=tok_semi) + { + ++error; + error_info(error_line,lack_semi); + return node; + } + ++ptr; + if(ptr>=tok_list_size) + { + ++error; + error_info(error_line,lack_calculation); + return node; + } + node.add_child(calculation()); + ++ptr; + if(ptr>=tok_list_size || tok_list[ptr].type!=tok_right_curve) + { + ++error; + error_info(error_line,lack_right_curve); + return node; + } + ++ptr; + node.add_child(exprs_gen()); return node; } + +nasal_ast nasal_parse::new_iter_gen() +{ + nasal_ast node; + if(tok_list[ptr].type==tok_var) + { + node.set_line(tok_list[ptr].line); + node.set_type(ast_new_iter); + ++ptr; + if(ptr>=tok_list_size || tok_list[ptr].type!=tok_identifier) + { + ++error; + error_info(error_line,lack_identifier); + return node; + } + node.add_child(id_gen()); + } + else + { + node.set_line(tok_list[ptr].line); + node.set_type(ast_call); + node.add_child(id_gen()); + ++ptr; + while(ptr