From 9e31e3d956d8f561ef3b14839d8ce8027f4702f6 Mon Sep 17 00:00:00 2001 From: Valk Richard Li <48872266+ValKmjolnir@users.noreply.github.com> Date: Sun, 19 Jan 2020 21:30:04 +0800 Subject: [PATCH] update --- version2.0/nasal_enum.h | 37 +++- version2.0/nasal_parse.h | 375 +++++++++++++++++++++++++++++---------- version2.0/parse.ebnf | 16 +- 3 files changed, 321 insertions(+), 107 deletions(-) diff --git a/version2.0/nasal_enum.h b/version2.0/nasal_enum.h index 87625ca..55ced29 100644 --- a/version2.0/nasal_enum.h +++ b/version2.0/nasal_enum.h @@ -50,14 +50,16 @@ enum parse_token_type __root, __null_type, __multi_id, + __multi_scalar, __parameters, + __defult_parameter, __vector,__hash, __hash_member, __sub_vector, __call_function,__call_vector,__call_hash, __normal_statement_block, - __definition,__assignment, - __function,__loop,__ifelse + __definition, + __function,__ifelse }; void print_parse_token(int type) @@ -127,7 +129,9 @@ void print_parse_token(int type) case __root: context="root"; break; case __null_type: context="null_type"; break; case __multi_id: context="identifiers"; break; + case __multi_scalar: context="scalars"; break; case __parameters: context="parameters"; break; + case __defult_parameter: context="para=scalar"; break; case __vector: context="vector"; break; case __hash: context="hash"; break; case __hash_member: context="hash_member"; break; @@ -137,9 +141,7 @@ void print_parse_token(int type) case __call_hash: context="call_hash"; break; case __normal_statement_block:context="block"; break; case __definition: context="definition"; break; - case __assignment: context="assignment"; break; case __function: context="function"; break; - case __loop: context="loop"; break; case __ifelse: context="if-else"; break; default: context="undefined_token";break; @@ -152,10 +154,15 @@ enum parse_error_type { parse_unknown_error, // unknown error error_token_in_main, // when a token should not be the begin of a statement in main + + lack_semi, + definition_lack_id, // lack identifier definition_lack_equal, // lack '=' when not getting ';' definition_wrong_type, // need identifier but get number or string multi_definition_need_curve, // lack right curve when generating 'var (id,id,id)' + multi_assignment_need_curve, // lack right curve when generating (scalar,scalar)=(scalar,scalar) + multi_assignment_need_equal, // lack '=' when generating (scalar,scalar)=(scalar,scalar) error_begin_token_of_scalar, // in scalar_generate() lack_left_curve, // lack left curve lack_right_curve, // lack right curve @@ -186,14 +193,32 @@ void print_parse_error(int error_type,int line,int error_token_type=__stack_end) print_parse_token(error_token_type); std::cout<<"\' in main scope."<& detail_token_stream) void nasal_parse::get_token() { - this_token=parse_token_stream.top(); - parse_token_stream.pop(); - checked_tokens.push(this_token); - if(this_token.type==__stack_end) + if(!parse_token_stream.empty()) { - std::cout<<">>[Parse-error] fatal error occurred."<>[Parse-error] empty token stack."<>[Stack-end] empty token stack."<>[Parse-error] fatal error occurred."<>[Parse-error] empty checked-token stack."<>[Stack-end] empty token stack."<get_token(); + if(this_token.type==__left_curve) + ++left_curve_cnt; + if(left_curve_cnt>1) + break; if(this_token.type==__comma) { ret=true; @@ -161,14 +170,14 @@ void nasal_parse::main_generate() root.set_node_line(1); root.set_node_type(__root); // initialize root node - while(parse_token_stream.top().type!=__stack_end) + while(!parse_token_stream.empty() && parse_token_stream.top().type!=__stack_end) { this->get_token(); switch(this_token.type) { case __var: this->push_token(); - root.get_children().push_back(var_outside_definition()); + root.get_children().push_back(definition()); break; case __nor_operator: case __sub_operator: case __number: case __nil: case __string: case __id: @@ -180,29 +189,13 @@ void nasal_parse::main_generate() case __left_curve: this->push_token(); if(check_comma_in_curve()) - { - this->get_token();// get '(' - this->get_token();// check if there is a 'var' - if(this_token.type==__var) - { - this->push_token(); - this->push_token(); - root.add_children(var_inside_definition()); - } - else - { - this->push_token(); - this->push_token(); - root.add_children(in_curve_assignment()); - } - } + root.add_children(multi_scalar_assignment()); else root.add_children(calculation()); // '(' is the beginning of too many statements // '(' var id,id,id ')' // '(' calculation ')' // '(' scalar,scalar,scalar ')' '=' '(' scalar,scalar,scalar ')' - // but these statements can be distinguished by commas in them break; case __if: this->push_token(); @@ -224,6 +217,76 @@ void nasal_parse::main_generate() return; } +abstract_syntax_tree nasal_parse::multi_scalar_assignment() +{ + abstract_syntax_tree assignment_node; + abstract_syntax_tree front_multi_scalar_node; + abstract_syntax_tree back_multi_scalar_node; + this->get_token();// get '(' + front_multi_scalar_node.set_node_line(this_token.line); + front_multi_scalar_node.set_node_type(__multi_scalar); + while(this_token.type!=__right_curve) + { + front_multi_scalar_node.add_children(scalar_generate()); + this->get_token(); + if(this_token.type!=__comma && this_token.type!=__right_curve) + { + ++error; + print_parse_error(multi_assignment_need_curve,this_token.line,this_token.type); + break; + } + if(this_token.type==__comma) + { + this->get_token(); + if(this_token.type!=__right_curve) + this->push_token(); + } + } + this->get_token(); + assignment_node.set_node_line(this_token.line); + assignment_node.set_node_type(this_token.type); + if(this_token.type!=__equal) + { + ++error; + print_parse_error(multi_assignment_need_equal,this_token.line,this_token.type); + } + this->get_token(); + if(this_token.type!=__left_curve) + back_multi_scalar_node=scalar_generate(); + else + { + this->push_token(); + if(check_comma_in_curve()) + { + this->get_token();// get '(' + back_multi_scalar_node.set_node_line(this_token.line); + back_multi_scalar_node.set_node_type(__multi_scalar); + while(this_token.type!=__right_curve) + { + back_multi_scalar_node.add_children(scalar_generate()); + this->get_token(); + if(this_token.type!=__comma && this_token.type!=__right_curve) + { + ++error; + print_parse_error(multi_assignment_need_curve,this_token.line,this_token.type); + break; + } + if(this_token.type==__comma) + { + this->get_token(); + if(this_token.type!=__right_curve) + this->push_token(); + } + } + } + else + back_multi_scalar_node=calculation(); + } + assignment_node.add_children(front_multi_scalar_node); + assignment_node.add_children(back_multi_scalar_node); + return assignment_node; +} + abstract_syntax_tree nasal_parse::calculation() { abstract_syntax_tree calc_node; @@ -308,7 +371,7 @@ abstract_syntax_tree nasal_parse::additive_calculation() abstract_syntax_tree tmp_node; calc_node=multive_calculation(); this->get_token(); - while((this_token.type==__add_operator) || (this_token.type==__sub_operator)) + while((this_token.type==__add_operator) || (this_token.type==__sub_operator) || (this_token.type==__link_operator)) { tmp_node.set_clear(); tmp_node.set_node_line(this_token.line); @@ -336,12 +399,12 @@ abstract_syntax_tree nasal_parse::multive_calculation() null_node.set_node_type(__number); null_node.set_var_number("0"); calc_node.add_children(null_node); - calc_node.add_children(scalar_generate()); + calc_node.add_children(assign_calculation()); } else { this->push_token(); - calc_node=scalar_generate(); + calc_node=assign_calculation(); } this->get_token(); while((this_token.type==__mul_operator) || (this_token.type==__div_operator)) @@ -361,12 +424,12 @@ abstract_syntax_tree nasal_parse::multive_calculation() null_node.set_node_type(__number); null_node.set_var_number("0"); calc_node.add_children(null_node); - calc_node.add_children(scalar_generate()); + calc_node.add_children(assign_calculation()); } else { this->push_token(); - calc_node=scalar_generate(); + calc_node=assign_calculation(); } tmp_node.add_children(calc_node); calc_node=tmp_node; @@ -376,6 +439,27 @@ abstract_syntax_tree nasal_parse::multive_calculation() return calc_node; } +abstract_syntax_tree nasal_parse::assign_calculation() +{ + abstract_syntax_tree scalar_node=scalar_generate(); + abstract_syntax_tree assignment_node; + this->get_token();// check if this token is '=' or '+=' or '-=' or '*=' or '/=' or '~=' + if((this_token.type==__equal) || (this_token.type==__add_equal) || (this_token.type==__sub_equal) || (this_token.type==__mul_equal) || (this_token.type==__div_equal) || (this_token.type==__link_equal)) + { + // ('=' | '+=' | '-=' | '*=' | '/=' | '~=') + assignment_node.set_node_line(this_token.line); + assignment_node.set_node_type(this_token.type); + assignment_node.add_children(scalar_node); + assignment_node.add_children(calculation()); + } + else + { + this->push_token(); + assignment_node=scalar_node; + } + return assignment_node; +} + abstract_syntax_tree nasal_parse::scalar_generate() { this->get_token(); @@ -435,6 +519,9 @@ abstract_syntax_tree nasal_parse::scalar_generate() abstract_syntax_tree call_func_node; call_func_node.set_node_line(this_token.line); call_func_node.set_node_type(__call_function); + + + // unfinished } else if(this_token.type==__left_bracket) { @@ -509,6 +596,7 @@ abstract_syntax_tree nasal_parse::scalar_generate() } this->get_token(); } + // call identifier/vector/hash/function this->push_token(); return scalar_node; } @@ -618,17 +706,16 @@ abstract_syntax_tree nasal_parse::function_generate() while(this_token.type!=__right_curve) { // check identifier + abstract_syntax_tree parameter; this->get_token(); if(this_token.type==__id) { - abstract_syntax_tree parameter; parameter.set_node_line(this_token.line); parameter.set_node_type(__id); parameter.set_var_name(this_token.str); } else if(this_token.type==__dynamic_id) { - abstract_syntax_tree parameter; parameter.set_node_line(this_token.line); parameter.set_node_type(__dynamic_id); parameter.set_var_name(this_token.str); @@ -646,17 +733,16 @@ abstract_syntax_tree nasal_parse::function_generate() this->get_token(); if(this_token.type==__equal) { - + abstract_syntax_tree default_parameter; + default_parameter.set_node_line(this_token.line); + default_parameter.set_node_type(__defult_parameter); + default_parameter.add_children(parameter); + default_parameter.add_children(calculation()); + parameter=default_parameter; } - else if((this_token.type==__right_curve) || (this_token.type==__comma)) - this->push_token(); else - { - ++error; - print_parse_error(parameter_lack_part,this_token.line); - break; - } - + this->push_token(); + parameter_list.add_children(parameter); // check comma or right_curve this->get_token(); if((this_token.type!=__right_curve) && (this_token.type!=__comma)) @@ -665,14 +751,137 @@ abstract_syntax_tree nasal_parse::function_generate() print_parse_error(parameter_lack_curve,this_token.line); break; } + if(this_token.type==__comma) + { + this->get_token(); + if(this_token.type!=__right_curve) + this->push_token(); + } } + function_node.add_children(parameter_list); } else this->push_token(); + this->get_token(); + if(this_token.type!=__left_brace) + { + switch(this_token.type) + { + case __var: + this->push_token(); + function_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(); + function_node.add_children(calculation()); + break; + case __left_curve: + this->push_token(); + if(check_comma_in_curve()) + function_node.add_children(multi_scalar_assignment()); + else + function_node.add_children(calculation()); + // '(' is the beginning of too many statements + // '(' var id,id,id ')' + // '(' calculation ')' + // '(' scalar,scalar,scalar ')' '=' '(' scalar,scalar,scalar ')' + break; + case __if: + this->push_token(); + function_node.add_children(choose_expr()); + break; + case __while: case __for: case __foreach: case __forindex: + this->push_token(); + function_node.add_children(loop_expr()); + break; + case __return: + this->push_token(); + function_node.add_children(return_expr()); + break; + case __semi:this->push_token();break; + case __stack_end:break; + default: + ++error; + print_parse_error(error_token_in_main,this_token.line,this_token.type); + break; + } + } + else + { + while(this_token.type!=__right_brace && !parse_token_stream.empty() && parse_token_stream.top().type!=__stack_end) + { + this->get_token(); + switch(this_token.type) + { + case __var: + this->push_token(); + function_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(); + function_node.add_children(calculation()); + break; + case __left_curve: + this->push_token(); + if(check_comma_in_curve()) + function_node.add_children(multi_scalar_assignment()); + else + function_node.add_children(calculation()); + // '(' is the beginning of too many statements + // '(' var id,id,id ')' + // '(' calculation ')' + // '(' scalar,scalar,scalar ')' '=' '(' scalar,scalar,scalar ')' + break; + case __if: + this->push_token(); + function_node.add_children(choose_expr()); + break; + case __while: case __for: case __foreach: case __forindex: + this->push_token(); + function_node.add_children(loop_expr()); + break; + case __return: + this->push_token(); + function_node.add_children(return_expr()); + break; + case __semi:break; + case __stack_end:break; + default: + ++error; + print_parse_error(error_token_in_main,this_token.line,this_token.type); + break; + } + } + } return function_node; } -abstract_syntax_tree nasal_parse::var_outside_definition() +abstract_syntax_tree nasal_parse::return_expr() +{ + abstract_syntax_tree ret_node; + this->get_token(); + ret_node.set_node_line(this_token.line); + ret_node.set_node_type(__return); + this->get_token(); + if((this_token.type==__sub_operator) || (this_token.type==__nor_operator) || + (this_token.type==__number) || (this_token.type==__string) || (this_token.type==__func) || + (this_token.type==__id) || (this_token.type==__nil) || + (this_token.type==__left_curve) || (this_token.type==__left_brace) || (this_token.type==__left_bracket) + ) + { + this->push_token(); + ret_node.add_children(calculation()); + } + return ret_node; +} + +abstract_syntax_tree nasal_parse::definition() { abstract_syntax_tree var_outsied_definition_node; var_outsied_definition_node.set_node_type(__definition); @@ -690,12 +899,12 @@ abstract_syntax_tree nasal_parse::var_outside_definition() if(this_token.type==__semi) this->push_token();// var id else if(this_token.type==__equal) - var_outsied_definition_node.add_children(scalar_generate());// var id = scalar + var_outsied_definition_node.add_children(calculation());// var id = scalar else { this->push_token(); ++error; - print_parse_error(definition_lack_equal,this_token.line); + print_parse_error(definition_lack_equal,this_token.line,this_token.type); } } else if(this_token.type==__left_curve) @@ -715,8 +924,11 @@ abstract_syntax_tree nasal_parse::var_outside_definition() } else { - this->push_token(); - multi_identifier.add_children(scalar_generate()); + 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) @@ -729,9 +941,7 @@ abstract_syntax_tree nasal_parse::var_outside_definition() } var_outsied_definition_node.add_children(multi_identifier); this->get_token(); - if(this_token.type==__semi) - this->push_token();// var (id,id,id) - else if(this_token.type==__equal) + if(this_token.type==__equal)// var (id,id,id)= { ; } @@ -739,7 +949,7 @@ abstract_syntax_tree nasal_parse::var_outside_definition() { this->push_token(); ++error; - print_parse_error(definition_lack_equal,this_token.line); + print_parse_error(definition_lack_equal,this_token.line,this_token.type); } } else @@ -751,44 +961,23 @@ abstract_syntax_tree nasal_parse::var_outside_definition() return var_outsied_definition_node; } -abstract_syntax_tree nasal_parse::var_inside_definition() -{ - abstract_syntax_tree var_inside_definition_node; - var_inside_definition_node.set_node_type(__definition); - this->get_token(); // get '(' - this->get_token(); // get 'var' - var_inside_definition_node.set_node_line(this_token.line); - return var_inside_definition_node; -} - -abstract_syntax_tree nasal_parse::normal_assignment() -{ - abstract_syntax_tree assign_node; - assign_node.set_node_type(__assignment); - return assign_node; -} - -abstract_syntax_tree nasal_parse::in_curve_assignment() -{ - abstract_syntax_tree assign_node; - this->get_token(); // get '(' - assign_node.set_node_line(this_token.line); - assign_node.set_node_type(__assignment); - return assign_node; -} - abstract_syntax_tree nasal_parse::loop_expr() { abstract_syntax_tree loop_main_node; - loop_main_node.set_node_type(__loop); this->get_token(); // get the first token of loop loop_main_node.set_node_line(this_token.line); - switch(this_token.type) + loop_main_node.set_node_type(this_token.type); + if(this_token.type==__for) { - case __for: - case __while: - case __foreach: - case __forindex:break; + ; + } + else if(this_token.type==__while) + { + ; + } + else + { + ; } return loop_main_node; } diff --git a/version2.0/parse.ebnf b/version2.0/parse.ebnf index 87543d6..e3303e2 100644 --- a/version2.0/parse.ebnf +++ b/version2.0/parse.ebnf @@ -26,6 +26,7 @@ | | | +| | '(' ')' | { ('[' { ','} ']') | ('[' ':' [] ']') | ('.' ) | ('(' { ','} ')') | ('(' { ':' ','} ')') } ; @@ -45,16 +46,15 @@ | [('-' | '!')] | '?' ':' ; - = { } ; - = { } ; - = {('+' | '-' | '~') } ; - =[('-' | '!')] {[('-' | '!')] } ; + = { } ; + = { } ; + = {('+' | '-' | '~') } ; + = [('-' | '!')] {('*' | '/') [('-' | '!')] }; (* this definition is also used in for loop*) = '=' -| '(' {() | () ','} ')' '=' ( | '(' { ','} ')') -| '(' {() | () ','} ')' '=' ( | '(' { ','} ')') +| '(' { ','} ')' '=' ( | '(' { ','} ')') ; = @@ -63,8 +63,8 @@ ; = - '=' -| '(' { ','} ')' '=' ( | '(' { ','} ')') + ('=' | '+=' | '-=' | '*=' | '/=' | '~=') +| '(' { ','} ')' ('=' | '+=' | '-=' | '*=' | '/=' | '~=') ( | '(' { ','} ')') ; =