diff --git a/version2.0/nasal_enum.h b/version2.0/nasal_enum.h index d9331a3..9e9176e 100644 --- a/version2.0/nasal_enum.h +++ b/version2.0/nasal_enum.h @@ -68,30 +68,29 @@ void print_parse_token(int type) std::string context=""; switch(type) { - case __stack_end: context="#"; break; + case __stack_end: context=" # "; break; + case __cmp_equal: context=" == "; break; + case __cmp_not_equal: context=" != "; break; + case __cmp_less: context=" < "; break; + case __cmp_less_or_equal: context=" <= "; break; + case __cmp_more: context=" > "; break; + case __cmp_more_or_equal: context=" >= "; break; - case __cmp_equal: context="=="; break; - case __cmp_not_equal: context="!="; break; - case __cmp_less: context="<"; break; - case __cmp_less_or_equal: context="<="; break; - case __cmp_more: context=">"; break; - case __cmp_more_or_equal: context=">="; break; + case __and_operator: context=" and ";break; + case __or_operator: context=" or "; break; + case __nor_operator: context=" ! "; break; + case __add_operator: context=" + "; break; + case __sub_operator: context=" - "; break; + case __mul_operator: context=" * "; break; + case __div_operator: context=" / "; break; + case __link_operator: context=" ~ "; break; - case __and_operator: context="and";break; - case __or_operator: context="or"; break; - case __nor_operator: context="!"; break; - case __add_operator: context="+"; break; - case __sub_operator: context="-"; break; - case __mul_operator: context="*"; break; - case __div_operator: context="/"; break; - case __link_operator: context="~"; break; - - case __equal: context="="; break; - case __add_equal: context="+="; break; - case __sub_equal: context="-="; break; - case __mul_equal: context="*="; break; - case __div_equal: context="/="; break; - case __link_equal: context="~="; break; + case __equal: context=" = "; break; + case __add_equal: context=" += "; break; + case __sub_equal: context=" -= "; break; + case __mul_equal: context=" *= "; break; + case __div_equal: context=" /= "; break; + case __link_equal: context=" ~= "; break; case __left_brace: context="{"; break; case __right_brace: context="}"; break; @@ -108,18 +107,18 @@ void print_parse_token(int type) case __unknown_operator: context="unknown_operator";break; - case __var: context="var"; break; - case __func: context="func"; break; - case __continue: context="continye"; break; + case __var: context="var "; break; + case __func: context="func "; break; + case __continue: context="continue"; break; case __break: context="break"; break; case __for: context="for"; break; case __forindex: context="forindex"; break; - case __foreach: context="foreach"; break; + case __foreach: context="foreach "; break; case __while: context="while"; break; - case __if: context="if"; break; - case __elsif: context="elsif"; break; - case __else: context="else"; break; - case __return: context="return"; break; + case __if: context="if "; break; + case __elsif: context="elsif "; break; + case __else: context="else "; break; + case __return: context="return "; break; case __nil: context="nil"; break; case __id: context="identifier"; break; diff --git a/version2.0/nasal_parse.h b/version2.0/nasal_parse.h index 0c4d7d9..a00bb4c 100644 --- a/version2.0/nasal_parse.h +++ b/version2.0/nasal_parse.h @@ -9,12 +9,12 @@ class nasal_parse std::stack checked_tokens; token this_token; int error; - int warning; abstract_syntax_tree root; public: // basic void delete_all_elements() { + // used in 'del' command while(!parse_token_stream.empty()) parse_token_stream.pop(); while(!checked_tokens.empty()) @@ -30,14 +30,14 @@ class nasal_parse abstract_syntax_tree& get_root(); // check '(' confliction - bool check_multi_assignment();// multi_call_id = multi_scalar - bool check_multi_scalar(); - bool check_var_in_curve(); // multi_definition + bool check_multi_assignment();// check multi_call_id '=' multi_scalar + bool check_multi_scalar(); // check multi_scalar + bool check_var_in_curve(); // check multi_definition: (var id,id,id) // abstract_syntax_tree generation + // block statements generation void main_generate(); - abstract_syntax_tree statements_block_generate(); - abstract_syntax_tree multi_scalar_assignment(); + abstract_syntax_tree block_generate(); /* calculation() will get elements generated by and_calculation() and_calculation() will get elements generated by or_calculation() @@ -64,7 +64,9 @@ class nasal_parse abstract_syntax_tree vector_generate(); abstract_syntax_tree function_generate(); + // return_expr() generates ebnf: [] ';' abstract_syntax_tree return_expr(); + abstract_syntax_tree multi_scalar_assignment(); abstract_syntax_tree definition(); abstract_syntax_tree loop_expr(); abstract_syntax_tree choose_expr(); @@ -72,26 +74,30 @@ class nasal_parse void nasal_parse::print_detail_token() { + // copy tokens from parse_token_stream + // so this function only works when generation hasn't begun. std::stack tmp=parse_token_stream; - std::string space=""; + // indent + std::string indent=""; int line=1; std::cout<& detail_token_stream) parse_token_stream.pop(); while(!checked_tokens.empty()) checked_tokens.pop(); + // add stack_end token token end_token; end_token.line=0; end_token.str="stack_end"; end_token.type=__stack_end; + parse_token_stream.push(end_token); checked_tokens.push(end_token); - // clear stacks and initialize them with end_token + // clear stacks and initialize them with stack_end token std::stack backward_tmp; // backward_tmp is used to backward detail_token_stream @@ -134,7 +142,10 @@ void nasal_parse::get_token() checked_tokens.push(this_token); } if(this_token.type==__stack_end) + { + std::cout<<">>[Parse-error] fatal error."<>[Stack-end] empty token stack."<>[Parse-error] fatal error."<>[Stack-end] empty token stack."<get_token(); ++cnt; + // these determine statements are used with curve_cnt,bracket_cnt and brace_cnt together + // to avoid checking commas in other curves/brackets/braces + // such as ([0,1,2,3]) + // but in multi_assignment, only things like (id[scalar],id.id[scalar]) can be recognized as multi_scalar + // if ([0,1,2,3]) and i don't use these judgements,then ([0,1,2,3]) will be recognized as multi_scalar + // but in fact ([0,1,2,3]) is not if(this_token.type==__left_curve) ++curve_cnt; if(this_token.type==__left_bracket) ++bracket_cnt; if(this_token.type==__left_brace) ++brace_cnt; @@ -220,6 +240,9 @@ bool nasal_parse::check_multi_scalar() { this->get_token(); ++cnt; + // these determine statements are used with curve_cnt,bracket_cnt and brace_cnt together + // to avoid checking commas in other curves/brackets/braces + // such as (a[0,1,2],b(2,3)) if(this_token.type==__left_curve) ++curve_cnt; if(this_token.type==__left_bracket) ++bracket_cnt; if(this_token.type==__left_brace) ++brace_cnt; @@ -245,11 +268,11 @@ bool nasal_parse::check_multi_scalar() 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(); + this->get_token(); // get '(' + this->get_token(); // get 'var' if exists + ret=(this_token.type==__var);// check + this->push_token(); // push 'var' + this->push_token(); // push '(' return ret; } @@ -258,8 +281,7 @@ void nasal_parse::main_generate() statement_generate_state=stat_null; // initialize state error=0; - warning=0; - // initialize error and warning + // initialize error root.set_clear(); root.set_node_line(1); root.set_node_type(__root); @@ -310,11 +332,11 @@ void nasal_parse::main_generate() } } - std::cout<<">>[Parse] complete generation. "<>[Parse] complete generation. "<get_token(); - if(this_token.type!=__comma && this_token.type!=__right_curve) + if((this_token.type!=__comma) && (this_token.type!=__right_curve)) { ++error; print_parse_error(multi_assignment_need_curve,this_token.line,this_token.type); @@ -470,6 +492,7 @@ abstract_syntax_tree nasal_parse::multi_scalar_assignment() this->get_token(); assignment_node.set_node_line(this_token.line); assignment_node.set_node_type(this_token.type); + // only '=' is alowed in multi_assignment if(this_token.type!=__equal) { ++error; @@ -490,7 +513,7 @@ abstract_syntax_tree nasal_parse::multi_scalar_assignment() { back_multi_scalar_node.add_children(scalar_generate()); this->get_token(); - if(this_token.type!=__comma && this_token.type!=__right_curve) + if((this_token.type!=__comma) && (this_token.type!=__right_curve)) { ++error; print_parse_error(multi_assignment_need_curve,this_token.line,this_token.type); @@ -884,7 +907,7 @@ abstract_syntax_tree nasal_parse::scalar_generate() { call_vector_node.add_children(calculation()); this->get_token(); - if(this_token.type!=__comma && this_token.type!=__right_bracket) + if((this_token.type!=__comma) && (this_token.type!=__right_bracket)) { ++error; print_parse_error(call_vector_lack_bracket,this_token.line,this_token.type); @@ -1053,7 +1076,7 @@ abstract_syntax_tree nasal_parse::function_generate() else { ++error; - print_parse_error(parameter_lack_part,this_token.line); + print_parse_error(parameter_lack_part,this_token.line,this_token.type); break; } @@ -1076,7 +1099,7 @@ abstract_syntax_tree nasal_parse::function_generate() if((this_token.type!=__right_curve) && (this_token.type!=__comma)) { ++error; - print_parse_error(parameter_lack_curve,this_token.line); + print_parse_error(parameter_lack_curve,this_token.line,this_token.type); break; } if(this_token.type==__comma) @@ -1090,7 +1113,7 @@ abstract_syntax_tree nasal_parse::function_generate() } else this->push_token(); - function_node.add_children(statements_block_generate()); + function_node.add_children(block_generate()); return function_node; } @@ -1224,7 +1247,7 @@ abstract_syntax_tree nasal_parse::definition() { this->push_token(); ++error; - print_parse_error(definition_wrong_type,this_token.line); + print_parse_error(definition_wrong_type,this_token.line,this_token.type); break; } else @@ -1419,7 +1442,7 @@ abstract_syntax_tree nasal_parse::loop_expr() print_parse_error(lack_right_curve,this_token.line,this_token.type); } } - loop_main_node.add_children(statements_block_generate()); + loop_main_node.add_children(block_generate()); return loop_main_node; } @@ -1448,7 +1471,7 @@ abstract_syntax_tree nasal_parse::choose_expr() ++error; print_parse_error(lack_right_curve,this_token.line); } - if_node.add_children(statements_block_generate()); + if_node.add_children(block_generate()); // add statements this->get_token(); if(this_token.type==__elsif) @@ -1472,7 +1495,7 @@ abstract_syntax_tree nasal_parse::choose_expr() ++error; print_parse_error(lack_right_curve,this_token.line,this_token.type); } - elsif_node.add_children(statements_block_generate()); + elsif_node.add_children(block_generate()); choose_main_node.add_children(elsif_node); this->get_token();// get next 'elsif' if it exists } @@ -1485,7 +1508,7 @@ abstract_syntax_tree nasal_parse::choose_expr() { else_node.set_node_line(this_token.type); else_node.set_node_type(__else); - else_node.add_children(statements_block_generate()); + else_node.add_children(block_generate()); choose_main_node.add_children(else_node); } else diff --git a/version2.0/parse.ebnf b/version2.0/parse.ebnf index 7edb2c6..aed3c7e 100644 --- a/version2.0/parse.ebnf +++ b/version2.0/parse.ebnf @@ -104,7 +104,7 @@ = ; = ; - = [] ; + = [] ; = |