#ifndef __NASAL_PARSE_H__ #define __NAsAL_PARSE_H__ class nasal_parse { private: int tok_list_size; int ptr; int error; nasal_ast root; std::vector tok_list; void reset(); bool check_function_end(nasal_ast&); bool check_special_call(); nasal_ast nil_gen(); nasal_ast number_gen(); nasal_ast string_gen(); nasal_ast id_gen(); nasal_ast vector_gen(); nasal_ast hash_gen(); nasal_ast hash_member_gen(); nasal_ast func_gen(); nasal_ast args_list_gen(); nasal_ast expr(); nasal_ast exprs_gen(); nasal_ast calculation(); nasal_ast or_expr(); nasal_ast and_expr(); nasal_ast cmp_expr(); nasal_ast additive_expr(); nasal_ast multive_expr(); nasal_ast unary(); nasal_ast scalar(); nasal_ast call_scalar(); nasal_ast call_hash(); nasal_ast call_vector(); nasal_ast call_func(); nasal_ast subvec(); nasal_ast definition(); nasal_ast multi_id(); nasal_ast multi_scalar(); nasal_ast multi_assgin(); nasal_ast loop(); nasal_ast while_loop(); nasal_ast for_loop(); nasal_ast forei_loop(); nasal_ast conditional(); nasal_ast continue_expr(); nasal_ast break_expr(); nasal_ast return_expr(); public: int get_error(); void clear(); void set_toklist(std::vector&); void main_process(); }; int nasal_parse::get_error() { return this->error; } void nasal_parse::clear() { this->tok_list_size=0; this->ptr=0; this->error=0; this->tok_list.clear(); this->root.clear(); return; } void nasal_parse::set_toklist(std::vector& lex_token) { this->tok_list=lex_token; tok_list_size=this->tok_list.size(); return; } void nasal_parse::main_process() { this->reset(); root.set_line(1); root.set_type(ast_root); while(ptr> [parse] complete generation. "<ptr=0; this->error=0; this->root.clear(); return; } bool nasal_parse::check_function_end(nasal_ast& node) { if(node.get_type()==ast_function) return true; if(node.get_children().empty() || (node.get_type()!=ast_definition && node.get_type()!=ast_equal)) return false; else return check_function_end(node.get_children().back()); return false; } bool nasal_parse::check_special_call() { int tmp=ptr+1; int curve_cnt=1; bool ret=false; while(tmp=tok_list_size) break; if(ptr=tok_list_size || tok_list[ptr].type!=tok_colon) { error_info(ptr>=tok_list_size?node.get_line():tok_list[ptr].line,lack_colon); ++error; return node; } ++ptr; if(ptr=tok_list_size) { error_info(node.get_line(),lack_left_curve); ++error; return node; } if(tok_list[ptr].type==tok_left_curve) { node.add_child(args_list_gen()); ++ptr; } if(ptr>=tok_list_size) { error_info(node.get_line(),lack_left_brace); ++error; return node; } node.add_child(exprs_gen()); return node; } nasal_ast nasal_parse::args_list_gen() { int last_id_line; nasal_ast node; node.set_line(tok_list[ptr].line); node.set_type(ast_args); while(ptr=tok_list_size || (tok_list[ptr].type!=tok_comma && tok_list[ptr].type!=tok_right_curve)) { ++error; error_info(last_id_line,lack_comma); --ptr; } } return node; } nasal_ast nasal_parse::expr() { nasal_ast node; node.set_line(tok_list[ptr].line); switch(tok_list[ptr].type) { case tok_nil: case tok_number: case tok_string: case tok_identifier: case tok_func: case tok_left_bracket: case tok_left_brace: case tok_sub: case tok_not: node=calculation(); break; case tok_var: node=definition(); break; case tok_for: case tok_forindex: case tok_foreach: case tok_while: node=loop(); break; case tok_if: node=conditional(); break; case tok_continue: node=continue_expr(); break; case tok_break: node=break_expr(); break; case tok_return: node=return_expr(); break; case tok_semi: --ptr; break; default: error_info(tok_list[ptr].line,error_token,tok_list[ptr].str);++error;break; } return node; } nasal_ast nasal_parse::exprs_gen() { nasal_ast node; node.set_line(tok_list[ptr].line); node.set_type(ast_block); if(tok_list[ptr].type==tok_left_brace) { while(ptr=tok_list_size) { error_info(node.get_line(),lack_right_brace); ++error; } } else { node.add_child(expr()); ++ptr; if(ptr>=tok_list_size || tok_list[ptr].type!=tok_semi) --ptr; } return node; } nasal_ast nasal_parse::calculation() { nasal_ast node; node=or_expr(); ++ptr; if(ptr=tok_list_size || tok_list[ptr].type!=tok_colon) { ++error; error_info(tmp.get_line(),lack_colon); return node; } ++ptr; if(ptr=tok_list_size || tok_list[ptr].type!=tok_right_curve) { ++error; error_info(curve_line,lack_right_curve); } } else { ++error; error_info(tok_list[ptr].line,lack_scalar); return nil_gen(); } ++ptr; if(ptr=tok_list_size || tok_list[ptr].type!=tok_right_bracket) { ++error; error_info(node.get_line(),lack_comma); break; } } return node; } nasal_ast nasal_parse::call_func() { nasal_ast node; node.set_line(tok_list[ptr].line); node.set_type(ast_call_func); bool special_call=check_special_call(); ++ptr; while(ptr=tok_list_size || tok_list[ptr].type!=tok_comma || tok_list[ptr].type!=tok_right_curve) { ++error; error_info(node.get_line(),lack_comma); } } return node; } nasal_ast nasal_parse::subvec() { nasal_ast node; if(tok_list[ptr].type==tok_colon) { --ptr; node=nil_gen(); } else node=calculation(); ++ptr; if(ptrtok_list_size) { ++error; error_info(tok_list.back().line,lack_token,"loop"); return node; } switch(tok_list[ptr].type) { case tok_while: node=while_loop(); break; case tok_for: node=for_loop(); break; case tok_forindex: case tok_foreach: node=forei_loop(); break; } return node; } nasal_ast nasal_parse::while_loop() { nasal_ast node; node.set_line(tok_list[ptr].line); node.set_type(ast_while); ++ptr; if(ptrtok_list_size || tok_list[ptr].type!=tok_right_curve) { ++error; error_info(node.get_line(),lack_right_curve); } ++ptr; node.add_child(exprs_gen()); return node; } nasal_ast nasal_parse::for_loop() { nasal_ast node; node.set_line(tok_list[ptr].line); node.set_type(ast_for); ++ptr; if(ptr>tok_list_size || tok_list[ptr].type!=tok_left_curve) { ++error; error_info(node.get_line(),lack_left_curve); } ++ptr; // unfinished return node; } nasal_ast nasal_parse::forei_loop() { nasal_ast node; node.set_line(tok_list[ptr].line); switch(tok_list[ptr].type) { case tok_forindex: node.set_type(ast_forindex);break; case tok_foreach: node.set_type(ast_foreach); break; } ++ptr; if(ptr>tok_list_size || tok_list[ptr].type!=tok_left_curve) { ++error; error_info(node.get_line(),lack_left_curve); } ++ptr; // unfinished return node; } nasal_ast nasal_parse::conditional() { nasal_ast node; node.set_line(tok_list[ptr].line); node.set_type(ast_if); return node; } nasal_ast nasal_parse::continue_expr() { nasal_ast node; node.set_line(tok_list[ptr].line); node.set_type(ast_continue); return node; } nasal_ast nasal_parse::break_expr() { nasal_ast node; node.set_line(tok_list[ptr].line); node.set_type(ast_break); return node; } nasal_ast nasal_parse::return_expr() { nasal_ast node; node.set_line(tok_list[ptr].line); node.set_type(ast_return); ++ptr; if(ptr