From 772cf253da14c7e071b8679acc413cbe4719e720 Mon Sep 17 00:00:00 2001 From: Valk Richard Li <48872266+ValKmjolnir@users.noreply.github.com> Date: Tue, 21 Jan 2020 17:35:50 +0800 Subject: [PATCH] update --- version2.0/main.cpp | 2 + version2.0/nasal_lexer.h | 7 + version2.0/nasal_parse.h | 275 ++++++++++++++++++++++++++++--------- version2.0/test/scalar.nas | 8 ++ 4 files changed, 230 insertions(+), 62 deletions(-) diff --git a/version2.0/main.cpp b/version2.0/main.cpp index 01a3242..46af052 100644 --- a/version2.0/main.cpp +++ b/version2.0/main.cpp @@ -55,6 +55,8 @@ int main() else if(command=="del") { resource.delete_all_source(); + lexer.delete_all_tokens(); + parser.delete_all_elements(); std::cout<<">>[Delete] complete."<::iterator i=token_list.begin();i!=token_list.end();++i) diff --git a/version2.0/nasal_parse.h b/version2.0/nasal_parse.h index ea87895..07f2639 100644 --- a/version2.0/nasal_parse.h +++ b/version2.0/nasal_parse.h @@ -13,6 +13,15 @@ class nasal_parse abstract_syntax_tree root; public: // basic + void delete_all_elements() + { + while(!parse_token_stream.empty()) + parse_token_stream.pop(); + while(!checked_tokens.empty()) + checked_tokens.pop(); + root.set_clear(); + return; + } void print_detail_token(); void get_token_list(std::list&); void get_token(); @@ -23,9 +32,23 @@ class nasal_parse // abstract_syntax_tree generation bool check_multi_assignment(); bool check_comma_in_curve(); + bool check_var_in_curve(); void main_generate(); - void statements_block_generate(abstract_syntax_tree&); + abstract_syntax_tree statements_block_generate(); abstract_syntax_tree multi_scalar_assignment(); +/* + calculation() will get elements generated by and_calculation() + and_calculation() will get elements generated by or_calculation() + or_calculation() will get elements generated by cmp_calculation() + cmp_calculation() will get elements generated by additive_calculation() + additive_calculation() will get elements generated by multive_calculation() + multive_calculation() will get elements generated by assign_calculation()(assignment '=' ) and scalar_generate() + assign_calculation() get elements from scalar_generate() + please notice that: + if the elements begin with '!' or '-',multive_calculation() gets them from scalar_generate() + if not,multive_calculation() gets them from assign_calculation() + because '!' and '-' cannot be used with assignment together such as: -a=1 +*/ abstract_syntax_tree calculation(); abstract_syntax_tree and_calculation(); abstract_syntax_tree or_calculation(); @@ -34,9 +57,11 @@ class nasal_parse abstract_syntax_tree multive_calculation(); abstract_syntax_tree assign_calculation(); abstract_syntax_tree scalar_generate(); + abstract_syntax_tree hash_generate(); abstract_syntax_tree vector_generate(); abstract_syntax_tree function_generate(); + abstract_syntax_tree return_expr(); abstract_syntax_tree definition(); abstract_syntax_tree loop_expr(); @@ -151,7 +176,6 @@ bool nasal_parse::check_multi_assignment() { } - return ret; } @@ -184,6 +208,17 @@ bool nasal_parse::check_comma_in_curve() return ret; } +bool nasal_parse::check_var_in_curve() +{ + bool ret=false; + this->get_token();// get '(' + this->get_token(); + ret=(this_token.type==__var); + this->push_token(); + this->push_token(); + return ret; +} + void nasal_parse::main_generate() { statement_generate_state=stat_null; @@ -213,7 +248,9 @@ void nasal_parse::main_generate() break; case __left_curve: this->push_token(); - if(check_comma_in_curve()) + if(check_var_in_curve()) + root.add_children(definition()); + else if(check_comma_in_curve()) root.add_children(multi_scalar_assignment()); else root.add_children(calculation()); @@ -243,31 +280,36 @@ void nasal_parse::main_generate() return; } -void nasal_parse::statements_block_generate(abstract_syntax_tree& tmp_node) +abstract_syntax_tree nasal_parse::statements_block_generate() { + abstract_syntax_tree block_node; abstract_syntax_tree continue_break_node; this->get_token(); + block_node.set_node_line(this_token.line); + block_node.set_node_type(__normal_statement_block); if(this_token.type!=__left_brace) { switch(this_token.type) { case __var: this->push_token(); - tmp_node.get_children().push_back(definition()); + block_node.get_children().push_back(definition()); break; case __nor_operator: case __sub_operator: case __number: case __nil: case __string: case __id: case __left_bracket: case __left_brace: case __func: this->push_token(); - tmp_node.add_children(calculation()); + block_node.add_children(calculation()); break; case __left_curve: this->push_token(); - if(check_comma_in_curve()) - tmp_node.add_children(multi_scalar_assignment()); + if(check_var_in_curve()) + block_node.add_children(definition()); + else if(check_comma_in_curve()) + block_node.add_children(multi_scalar_assignment()); else - tmp_node.add_children(calculation()); + block_node.add_children(calculation()); // '(' is the beginning of too many statements // '(' var id,id,id ')' // '(' calculation ')' @@ -275,21 +317,21 @@ void nasal_parse::statements_block_generate(abstract_syntax_tree& tmp_node) break; case __if: this->push_token(); - tmp_node.add_children(choose_expr()); + block_node.add_children(choose_expr()); break; case __while: case __for: case __foreach: case __forindex: this->push_token(); - tmp_node.add_children(loop_expr()); + block_node.add_children(loop_expr()); break; case __return: this->push_token(); - tmp_node.add_children(return_expr()); + block_node.add_children(return_expr()); break; case __continue: case __break: continue_break_node.set_node_line(this_token.line); continue_break_node.set_node_type(this_token.type); - tmp_node.add_children(continue_break_node); + block_node.add_children(continue_break_node); break; case __semi:this->push_token();break; case __stack_end:break; @@ -298,6 +340,9 @@ void nasal_parse::statements_block_generate(abstract_syntax_tree& tmp_node) print_parse_error(error_token_in_block,this_token.line,this_token.type); break; } + this->get_token(); + if(this_token.type!=__semi) + this->push_token(); } else { @@ -308,21 +353,23 @@ void nasal_parse::statements_block_generate(abstract_syntax_tree& tmp_node) { case __var: this->push_token(); - tmp_node.get_children().push_back(definition()); + block_node.get_children().push_back(definition()); break; case __nor_operator: case __sub_operator: case __number: case __nil: case __string: case __id: case __left_bracket: case __left_brace: case __func: this->push_token(); - tmp_node.add_children(calculation()); + block_node.add_children(calculation()); break; case __left_curve: this->push_token(); - if(check_comma_in_curve()) - tmp_node.add_children(multi_scalar_assignment()); + if(check_var_in_curve()) + block_node.add_children(definition()); + else if(check_comma_in_curve()) + block_node.add_children(multi_scalar_assignment()); else - tmp_node.add_children(calculation()); + block_node.add_children(calculation()); // '(' is the beginning of too many statements // '(' var id,id,id ')' // '(' calculation ')' @@ -330,21 +377,21 @@ void nasal_parse::statements_block_generate(abstract_syntax_tree& tmp_node) break; case __if: this->push_token(); - tmp_node.add_children(choose_expr()); + block_node.add_children(choose_expr()); break; case __while: case __for: case __foreach: case __forindex: this->push_token(); - tmp_node.add_children(loop_expr()); + block_node.add_children(loop_expr()); break; case __return: this->push_token(); - tmp_node.add_children(return_expr()); + block_node.add_children(return_expr()); break; case __continue: case __break: continue_break_node.set_node_line(this_token.line); continue_break_node.set_node_type(this_token.type); - tmp_node.add_children(continue_break_node); + block_node.add_children(continue_break_node); break; case __semi:break; case __stack_end:break; @@ -358,7 +405,7 @@ void nasal_parse::statements_block_generate(abstract_syntax_tree& tmp_node) this->push_token(); } } - return; + return block_node; } abstract_syntax_tree nasal_parse::multi_scalar_assignment() @@ -1009,7 +1056,7 @@ abstract_syntax_tree nasal_parse::function_generate() } else this->push_token(); - statements_block_generate(function_node); + function_node.add_children(statements_block_generate()); return function_node; } @@ -1034,32 +1081,13 @@ abstract_syntax_tree nasal_parse::return_expr() abstract_syntax_tree nasal_parse::definition() { - abstract_syntax_tree var_outsied_definition_node; - var_outsied_definition_node.set_node_type(__definition); - this->get_token();// get 'var' - var_outsied_definition_node.set_node_line(this_token.line); - this->get_token(); - if(this_token.type==__id) - { - abstract_syntax_tree new_var_identifier; - new_var_identifier.set_node_type(__id); - new_var_identifier.set_node_line(this_token.line); - new_var_identifier.set_var_name(this_token.str); - var_outsied_definition_node.add_children(new_var_identifier); - this->get_token(); - if(this_token.type==__semi) - this->push_token();// var id - else if(this_token.type==__equal) - var_outsied_definition_node.add_children(calculation());// var id = scalar - else - { - this->push_token(); - ++error; - print_parse_error(definition_lack_equal,this_token.line,this_token.type); - } - } - else if(this_token.type==__left_curve) + abstract_syntax_tree definition_node; + definition_node.set_node_type(__definition); + this->get_token();// get 'var' or '(' + definition_node.set_node_line(this_token.line); + if(this_token.type==__left_curve) { + this->get_token();// get 'var' abstract_syntax_tree multi_identifier; multi_identifier.set_node_type(__multi_id); multi_identifier.set_node_line(this_token.line); @@ -1068,9 +1096,8 @@ abstract_syntax_tree nasal_parse::definition() this->get_token(); if(this_token.type!=__id) { - this->push_token(); ++error; - print_parse_error(definition_wrong_type,this_token.line); + print_parse_error(definition_lack_id,this_token.line,this_token.type); break; } else @@ -1082,7 +1109,7 @@ abstract_syntax_tree nasal_parse::definition() multi_identifier.add_children(id_node); } this->get_token(); - if(this_token.type!=__semi && this_token.type!=__right_curve) + if((this_token.type!=__semi) && (this_token.type!=__right_curve)) { this->push_token(); ++error; @@ -1090,9 +1117,9 @@ abstract_syntax_tree nasal_parse::definition() break; } } - var_outsied_definition_node.add_children(multi_identifier); + definition_node.add_children(multi_identifier); this->get_token(); - if(this_token.type==__equal)// var (id,id,id)= + if(this_token.type==__equal)// (var id,id,id)= { ; } @@ -1105,11 +1132,79 @@ abstract_syntax_tree nasal_parse::definition() } else { - this->push_token(); - ++error; - print_parse_error(definition_lack_id,this_token.line); + this->get_token(); + if(this_token.type==__id) + { + abstract_syntax_tree new_var_identifier; + new_var_identifier.set_node_type(__id); + new_var_identifier.set_node_line(this_token.line); + new_var_identifier.set_var_name(this_token.str); + definition_node.add_children(new_var_identifier); + this->get_token(); + if(this_token.type==__semi) + this->push_token();// var id + else if(this_token.type==__equal) + definition_node.add_children(calculation());// var id = scalar + else + { + this->push_token(); + ++error; + print_parse_error(definition_lack_equal,this_token.line,this_token.type); + } + } + else if(this_token.type==__left_curve) + { + abstract_syntax_tree multi_identifier; + multi_identifier.set_node_type(__multi_id); + multi_identifier.set_node_line(this_token.line); + while(this_token.type!=__right_curve) + { + this->get_token(); + if(this_token.type!=__id) + { + this->push_token(); + ++error; + print_parse_error(definition_wrong_type,this_token.line); + break; + } + else + { + abstract_syntax_tree id_node; + id_node.set_node_line(this_token.line); + id_node.set_node_type(__id); + id_node.set_var_name(this_token.str); + multi_identifier.add_children(id_node); + } + this->get_token(); + if(this_token.type!=__semi && this_token.type!=__right_curve) + { + this->push_token(); + ++error; + print_parse_error(multi_definition_need_curve,this_token.line); + break; + } + } + definition_node.add_children(multi_identifier); + this->get_token(); + if(this_token.type==__equal)// var (id,id,id)= + { + ; + } + else + { + this->push_token(); + ++error; + print_parse_error(definition_lack_equal,this_token.line,this_token.type); + } + } + else + { + this->push_token(); + ++error; + print_parse_error(definition_lack_id,this_token.line); + } } - return var_outsied_definition_node; + return definition_node; } abstract_syntax_tree nasal_parse::loop_expr() @@ -1120,9 +1215,64 @@ abstract_syntax_tree nasal_parse::loop_expr() loop_main_node.set_node_type(this_token.type); if(this_token.type==__for) { + this->get_token(); + if(this_token.type!=__left_curve) + { + ++error; + print_parse_error(lack_left_curve,this_token.line); + } this->get_token(); if(this_token.type==__semi) this->push_token(); + else + { + if(this_token.type==__var) + { + this->push_token(); + loop_main_node.add_children(definition()); + } + else + { + this->push_token(); + // cannot use calculation() here + // because for-loop's first statement must be definition or call_identifier + loop_main_node.add_children(scalar_generate()); + } + } + this->get_token(); + if(this_token.type!=__semi) + { + ++error; + print_parse_error(lack_semi,this_token.line); + } + this->get_token(); + if(this_token.type==__semi) + this->push_token(); + else + { + this->push_token(); + loop_main_node.add_children(calculation()); + } + this->get_token(); + if(this_token.type!=__semi) + { + ++error; + print_parse_error(lack_semi,this_token.line); + } + this->get_token(); + if(this_token.type==__right_curve) + this->push_token(); + else + { + this->push_token(); + loop_main_node.add_children(calculation()); + } + this->get_token(); + if(this_token.type!=__right_curve) + { + ++error; + print_parse_error(lack_right_curve,this_token.line); + } } else if(this_token.type==__while) { @@ -1181,7 +1331,7 @@ abstract_syntax_tree nasal_parse::loop_expr() print_parse_error(lack_right_curve,this_token.line,this_token.type); } } - statements_block_generate(loop_main_node); + loop_main_node.add_children(statements_block_generate()); return loop_main_node; } @@ -1210,7 +1360,7 @@ abstract_syntax_tree nasal_parse::choose_expr() ++error; print_parse_error(lack_right_curve,this_token.line); } - statements_block_generate(if_node); + if_node.add_children(statements_block_generate()); // add statements this->get_token(); if(this_token.type==__elsif) @@ -1234,8 +1384,9 @@ abstract_syntax_tree nasal_parse::choose_expr() ++error; print_parse_error(lack_right_curve,this_token.line,this_token.type); } - statements_block_generate(elsif_node); + elsif_node.add_children(statements_block_generate()); choose_main_node.add_children(elsif_node); + this->get_token();// get next 'elsif' if it exists } this->push_token(); } @@ -1246,7 +1397,7 @@ abstract_syntax_tree nasal_parse::choose_expr() { else_node.set_node_line(this_token.type); else_node.set_node_type(__else); - statements_block_generate(else_node); + else_node.add_children(statements_block_generate()); choose_main_node.add_children(else_node); } else diff --git a/version2.0/test/scalar.nas b/version2.0/test/scalar.nas index 979d1ed..f176a6e 100644 --- a/version2.0/test/scalar.nas +++ b/version2.0/test/scalar.nas @@ -13,6 +13,7 @@ nil; {}; [0,1,2,3,4,5][2]; # 2 ([0,1,2,3,4])[2]; # 2 +(([0,1,2,3]))[2]; # 2 [0,1,2,3,4,5][5,4,3,2+1][0:2][0]; # 5 {str:"hello"}.str; # "hello" {str:"hello"}["str"]; # "hello" @@ -94,6 +95,13 @@ var (r,g,b)=color; (var r,g,b)=color; (r,g,b)=(b,g,r); (number_1,number_2)=(number_2,number_1); +var (swap_a,swap_b)=(0x1,0x80); +(swap_a,swap_b)=(swap_b,swap_a); +# ((swap_a),(swap_b))=(swap_b,swap_a) is wrong +# anything that use multi_assignment must not have curve around them +var multi_assign_1=[0,1,2,3,4]; +var multi_assign_2=[10,9,8,7]; +(multi_assign_1[1],multi_assign_2[0])=(multi_assign_1[2],multi_assign_2[1]); # calculation 1+1;