From f0b5ef86acfaafab38fb0c3a2cbec05b6c4224b9 Mon Sep 17 00:00:00 2001 From: Valk Richard Li <48872266+ValKmjolnir@users.noreply.github.com> Date: Mon, 20 Jan 2020 14:27:48 +0800 Subject: [PATCH] Update --- version2.0/loop_and_choice.nas | 58 +++++++ version2.0/nasal_enum.h | 22 +++ version2.0/nasal_parse.h | 277 +++++++++++++++++++++------------ version2.0/test.nas | 1 + 4 files changed, 259 insertions(+), 99 deletions(-) create mode 100644 version2.0/loop_and_choice.nas diff --git a/version2.0/loop_and_choice.nas b/version2.0/loop_and_choice.nas new file mode 100644 index 0000000..fe41308 --- /dev/null +++ b/version2.0/loop_and_choice.nas @@ -0,0 +1,58 @@ +for(;;)break; +for(;;) +{ + var a=1; + break; +} +for(var i=1;;)break; +for(var i=1;;i+=1)break; +for(var i=1;i<10;i+=1)print(i); + +while(1)break; +var j=0; +while(j<10) +{ + print(j); + j+=1; +} + +forindex(var j;[0,1,2,3])print(j); +forindex(var j;[0,1,2,3]) +{ + var a=j; + print(a*a); +} +foreach(var j;[0,1,2,3])print([0,1,2,3][j]); +foreach(var j;[0,1,2,3]) +{ + var a=[0,1,2,3][j]; + print(a*a-1); +} + +var condition_true=1; +var condition_false=0; +if(condition_true) +{ + var a=1; +} +else if(!condition_false) +{ + var b=1; +} +elsif(!condition_true and condition_false) +{ + print("impossible"); +} +else +{ + var c=1; +} + +if(condition_true) + var a=1; +else if(!condition_false) + var b=1; +elsif(!condition_true and condition_false) + print("impossible"); +else + var c=1; \ No newline at end of file diff --git a/version2.0/nasal_enum.h b/version2.0/nasal_enum.h index f8f70f4..9051872 100644 --- a/version2.0/nasal_enum.h +++ b/version2.0/nasal_enum.h @@ -156,6 +156,7 @@ 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 + error_token_in_block, // when a token should not be the begin of a statement in block lack_semi, @@ -198,6 +199,11 @@ 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."< parse_token_stream; std::stack checked_tokens; token this_token; @@ -22,6 +23,7 @@ class nasal_parse // abstract_syntax_tree generation bool check_comma_in_curve(); void main_generate(); + void statements_block_generate(abstract_syntax_tree&); abstract_syntax_tree multi_scalar_assignment(); abstract_syntax_tree calculation(); abstract_syntax_tree and_calculation(); @@ -164,6 +166,8 @@ bool nasal_parse::check_comma_in_curve() void nasal_parse::main_generate() { + statement_generate_state=stat_null; + // initialize state error=0; warning=0; // initialize error and warning @@ -213,11 +217,130 @@ void nasal_parse::main_generate() print_parse_error(error_token_in_main,this_token.line,this_token.type); break; } + } std::cout<<">>[Parse] complete generation. "<get_token(); + if(this_token.type!=__left_brace) + { + switch(this_token.type) + { + case __var: + this->push_token(); + tmp_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()); + break; + case __left_curve: + this->push_token(); + if(check_comma_in_curve()) + tmp_node.add_children(multi_scalar_assignment()); + else + tmp_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(); + tmp_node.add_children(choose_expr()); + break; + case __while: case __for: case __foreach: case __forindex: + this->push_token(); + tmp_node.add_children(loop_expr()); + break; + case __return: + this->push_token(); + tmp_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); + break; + case __semi:this->push_token();break; + case __stack_end:break; + default: + ++error; + print_parse_error(error_token_in_block,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(); + tmp_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()); + break; + case __left_curve: + this->push_token(); + if(check_comma_in_curve()) + tmp_node.add_children(multi_scalar_assignment()); + else + tmp_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(); + tmp_node.add_children(choose_expr()); + break; + case __while: case __for: case __foreach: case __forindex: + this->push_token(); + tmp_node.add_children(loop_expr()); + break; + case __return: + this->push_token(); + tmp_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); + break; + case __semi:break; + case __stack_end:break; + default: + ++error; + print_parse_error(error_token_in_block,this_token.line,this_token.type); + break; + } + this->get_token(); + if(this_token.type!=__right_brace) + this->push_token(); + } + } + return; +} + abstract_syntax_tree nasal_parse::multi_scalar_assignment() { abstract_syntax_tree assignment_node; @@ -862,103 +985,7 @@ abstract_syntax_tree nasal_parse::function_generate() } 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; - } - } - } + statements_block_generate(function_node); return function_node; } @@ -1073,12 +1100,25 @@ abstract_syntax_tree nasal_parse::loop_expr() } else if(this_token.type==__while) { - ; + this->get_token(); + if(this_token.type!=__left_curve) + { + ++error; + print_parse_error(lack_left_curve,this_token.line,this_token.type); + } + 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,this_token.type); + } } else { ; } + statements_block_generate(loop_main_node); return loop_main_node; } @@ -1107,9 +1147,48 @@ abstract_syntax_tree nasal_parse::choose_expr() ++error; print_parse_error(lack_right_curve,this_token.line); } + statements_block_generate(if_node); // add statements + this->get_token(); + if(this_token.type==__elsif) + { + while(this_token.type==__elsif) + { + elsif_node.set_clear(); + elsif_node.set_node_line(this_token.line); + elsif_node.set_node_type(__elsif); - // get elsif or else if + this->get_token(); + if(this_token.type!=__left_curve) + { + ++error; + print_parse_error(lack_left_curve,this_token.line,this_token.type); + } + elsif_node.add_children(calculation()); + this->get_token(); + if(this_token.type!=__right_curve) + { + ++error; + print_parse_error(lack_right_curve,this_token.line,this_token.type); + } + statements_block_generate(elsif_node); + choose_main_node.add_children(elsif_node); + } + this->push_token(); + } + else + this->push_token(); + this->get_token(); + if(this_token.type==__else) + { + else_node.set_node_line(this_token.type); + else_node.set_node_type(__else); + statements_block_generate(else_node); + choose_main_node.add_children(else_node); + } + else + this->push_token(); + // get elsif or else return choose_main_node; } #endif diff --git a/version2.0/test.nas b/version2.0/test.nas index dff612b..979d1ed 100644 --- a/version2.0/test.nas +++ b/version2.0/test.nas @@ -12,6 +12,7 @@ nil; []; {}; [0,1,2,3,4,5][2]; # 2 +([0,1,2,3,4])[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"