diff --git a/version2.0/abstract_syntax_tree.h b/version2.0/abstract_syntax_tree.h index 7b74141..f4afb61 100644 --- a/version2.0/abstract_syntax_tree.h +++ b/version2.0/abstract_syntax_tree.h @@ -18,14 +18,19 @@ class abstract_syntax_tree abstract_syntax_tree& operator=(const abstract_syntax_tree&); // main functions - void set_clear(); + // print void print_tree(const int); + + // set + void set_clear(); void set_type(const int); void set_line(const int); void set_string(std::string); void set_number(std::string); void set_name(std::string); void add_child(abstract_syntax_tree); + + // get int get_type(); int get_line(); double get_number(); @@ -74,17 +79,6 @@ abstract_syntax_tree& abstract_syntax_tree::operator=(const abstract_syntax_tree return *this; } -void abstract_syntax_tree::set_clear() -{ - type=0; - line=0; - number=0; - str=""; - name=""; - children.clear(); - return; -} - void abstract_syntax_tree::print_tree(const int n) { std::string __str=""; @@ -111,6 +105,17 @@ void abstract_syntax_tree::print_tree(const int n) return; } +void abstract_syntax_tree::set_clear() +{ + type=0; + line=0; + number=0; + str=""; + name=""; + children.clear(); + return; +} + void abstract_syntax_tree::set_type(const int __type) { type=__type; @@ -122,7 +127,10 @@ void abstract_syntax_tree::set_line(const int __line) if(__line>=0) line=__line; else + { + std::cout<<">> [Abstract-syntax-tree-warning] incorrect line under 0: "<<__line<<"."< >= __and_operator,__or_operator,__nor_operator,__add_operator,__sub_operator,__mul_operator,__div_operator,__link_operator, @@ -49,6 +48,7 @@ enum parse_token_type // absttract_syntax_tree type below __root, __null_type, + __multi_id, __list,__hash, __hash_member, __call_function,__call_array,__call_hash, @@ -63,7 +63,6 @@ void print_parse_token(int type) switch(type) { case __stack_end: context="#"; break; - case __stack_top: context="#"; break; case __cmp_equal: context="=="; break; case __cmp_not_equal: context="!="; break; @@ -122,20 +121,21 @@ void print_parse_token(int type) case __number: context="number"; break; case __string: context="string"; break; - case __root: context="root"; break; - case __null_type: context="null_type"; break; - case __list: context="list"; break; - case __hash: context="hash"; break; - case __hash_member: context="hash_member";break; - case __call_function: context="call_func"; break; - case __call_array: context="call_array"; break; - 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; + case __root: context="root"; break; + case __null_type: context="null_type"; break; + case __multi_id: context="multi_identifiers"; break; + case __list: context="list"; break; + case __hash: context="hash"; break; + case __hash_member: context="hash_member"; break; + case __call_function: context="call_func"; break; + case __call_array: context="call_array"; break; + 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; } @@ -145,26 +145,37 @@ void print_parse_token(int type) 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 - definition_lack_var, // lack 'var' reserve word - definition_lack_id, // lack identifier + parse_unknown_error, // unknown error + error_token_in_main, // when a token should not be the begin of a statement in main + 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)' }; void print_parse_error(int error_type,int line,int error_token_type=__stack_end) { std::string error_info_head=">>[Parse-error] line "; + std::string warning_info_head=">> [Parse-warning] line "; switch(error_type) { - case parse_unknown_error: std::cout<& detail_token_stream) parse_token_stream.pop(); while(!checked_tokens.empty()) checked_tokens.pop(); - // clear stack + 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 + std::stack backward_tmp; + // backward_tmp is used to backward detail_token_stream + // to the parse_token_stream so get_token can get token + // according to the correct subsequence. for(std::list::iterator i=detail_token_stream.begin();i!=detail_token_stream.end();++i) backward_tmp.push(*i); while(!backward_tmp.empty()) @@ -81,16 +89,11 @@ void nasal_parse::get_token_list(std::list& detail_token_stream) void nasal_parse::get_token() { - if(!parse_token_stream.empty()) + this_token=parse_token_stream.top(); + parse_token_stream.pop(); + checked_tokens.push(this_token); + if(this_token.type==__stack_end) { - this_token=parse_token_stream.top(); - parse_token_stream.pop(); - checked_tokens.push(this_token); - } - else - { - this_token.type=__stack_end; - this_token.str="__stack_end"; std::cout<<">>[Parse-error] fatal error occurred."<>[Parse-error] empty token stack."<>[Parse-error] fatal error occurred."<>[Parse-error] empty checked-token stack."<get_token(); switch(this_token.type) { - case __var:this->push_token();root.get_children().push_back(var_outside_definition());break; - case __nor_operator: - case __sub_operator: - case __number: - case __string: - case __nil: - case __id:break; - case __left_curve:break; - case __left_bracket:break; - case __left_brace:break; - case __func:break; - case __if:break; - case __while: - case __for: - case __foreach: - case __forindex:this->push_token();root.get_children().push_back(loop_expr());break; + case __var: + this->push_token(); + root.get_children().push_back(var_outside_definition()); + break; + case __nor_operator: case __sub_operator: + case __number: case __nil: case __string: case __id: + case __left_curve: case __left_bracket: case __left_brace: + case __func: + this->push_token(); + root.add_child(scalar_generate()); + break; + case __if: + this->push_token(); + root.add_child(choose_expr()); + break; + case __while: case __for: case __foreach: case __forindex: + this->push_token(); + root.add_child(loop_expr()); + break; case __semi:break; - default:++error;print_parse_error(error_token_in_main,this_token.line,this_token.type); + default: + ++error; + print_parse_error(error_token_in_main,this_token.line,this_token.type); + break; } } std::cout<<">>[Parse] complete generation. "<get_token(); - node.set_line(this_token.line); - node.set_type(__number); - node.set_number(this_token.str); - return node; -} - -abstract_syntax_tree nasal_parse::string_expr() -{ - abstract_syntax_tree node; - this->get_token(); - node.set_line(this_token.line); - node.set_type(__string); - node.set_string(this_token.str); - return node; -} - -abstract_syntax_tree nasal_parse::nil_expr() -{ - abstract_syntax_tree node; - this->get_token(); - node.set_line(this_token.line); - node.set_type(__nil); - return node; + abstract_syntax_tree scalar_node; + switch(this_token.type) + { + case __nor_operator: + case __sub_operator: + break; + case __number: + case __string: + case __nil: + case __id: + break; + case __left_curve:break; + case __left_brace:break; + case __left_bracket:break; + case __func:break; + } + return scalar_node; } abstract_syntax_tree nasal_parse::var_outside_definition() { abstract_syntax_tree definition_node; definition_node.set_type(__definition); - this->get_token(); + this->get_token();// get 'var' definition_node.set_line(this_token.line); - if(this_token.type!=__var) - { - ++error; - print_parse_error(definition_lack_var,this_token.line); - } this->get_token(); if(this_token.type==__id) { + abstract_syntax_tree new_var_identifier; + new_var_identifier.set_type(__id); + new_var_identifier.set_line(this_token.line); + new_var_identifier.set_name(this_token.str); + definition_node.add_child(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_child(scalar_generate());// var id = scalar + else + { + this->push_token(); + ++error; + print_parse_error(definition_lack_equal,this_token.line); + } } else if(this_token.type==__left_curve) { + abstract_syntax_tree multi_identifier; + multi_identifier.set_type(__multi_id); + multi_identifier.set_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 + { + this->push_token(); + multi_identifier.add_child(scalar_generate()); + } + 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_child(multi_identifier); + this->get_token(); + if(this_token.type==__semi) + this->push_token();// var (id,id,id) + else if(this_token.type==__equal) + { + ; + } + else + { + this->push_token(); + ++error; + print_parse_error(definition_lack_equal,this_token.line); + } } else { + this->push_token(); ++error; print_parse_error(definition_lack_id,this_token.line); } @@ -236,7 +291,7 @@ abstract_syntax_tree nasal_parse::choose_expr() { abstract_syntax_tree choose_main_node; choose_main_node.set_type(__ifelse); - this->get_token(); + this->get_token();// get 'if' choose_main_node.set_line(this_token.line); return choose_main_node; } diff --git a/version2.0/parse.bnf b/version2.0/parse.bnf index 35aa624..9db0c8b 100644 --- a/version2.0/parse.bnf +++ b/version2.0/parse.bnf @@ -16,12 +16,14 @@ | | -| +| +| +| +| | | | <(> <)> -| -| +| { (<[> { <,>} <]>) | (<[> <:> [] <]>) | (<.> ) | (<(> { <,>} <)>) | (<(> { <:> <,>} <)>) } ::= [<(> <)>] @@ -29,18 +31,12 @@ | <(> { <,>} { <=> <,>} {} <)> | <(> { <,>} { <=> <,>} {} <)> <{> { <;>} <}> - ::= - { (<[> { <,>} <]>) | (<[> <:> [] <]>) | (<.> ) | (<(> { <,>} <)>) | (<(> { <:> <,>} <)>) } -| { (<[> { <,>} <]>) | (<[> <:> [] <]>) | (<.> ) | (<(> { <,>} <)>) | (<(> { <:> <,>} <)>) } -| -| <(> <)> { (<[> { <,>} <]>) | (<[> <:> [] <]>) | (<.> ) | (<(> { <,>} <)>) | (<(> { <:> <,>} <)>) } - ::= | | | -| +| [<->|] ::= { } ::= @@ -48,7 +44,7 @@ ::= {<+>|<->|<~> } ::= - {<*>| } + <->| {<*>| } ::=