update
This commit is contained in:
parent
b5f0eddb4c
commit
6ba888e445
|
@ -65,6 +65,23 @@ void par_func()
|
|||
return;
|
||||
}
|
||||
|
||||
void ast_func()
|
||||
{
|
||||
lexer.scanner(resource.get_file());
|
||||
if(!lexer.get_error())
|
||||
{
|
||||
parse.set_toklist(lexer.get_token_list());
|
||||
parse.main_process();
|
||||
if(parse.get_error())
|
||||
std::cout<<">> [parse] error(s) occurred,stop.\n";
|
||||
else
|
||||
parse.get_root().print_ast(0);
|
||||
}
|
||||
else
|
||||
std::cout<<">> [lexer] error(s) occurred,stop.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
@ -116,9 +133,7 @@ int main()
|
|||
else if(command=="par")
|
||||
par_func();
|
||||
else if(command=="ast")
|
||||
{
|
||||
;
|
||||
}
|
||||
ast_func();
|
||||
else if(command=="run")
|
||||
{
|
||||
;
|
||||
|
|
|
@ -22,6 +22,7 @@ public:
|
|||
int get_type();
|
||||
std::string get_str();
|
||||
std::vector<nasal_ast>& get_children();
|
||||
void print_ast(int);
|
||||
};
|
||||
|
||||
nasal_ast::nasal_ast()
|
||||
|
@ -110,4 +111,24 @@ std::vector<nasal_ast>& nasal_ast::get_children()
|
|||
return this->children;
|
||||
}
|
||||
|
||||
void nasal_ast::print_ast(int depth)
|
||||
{
|
||||
std::string indentation="";
|
||||
for(int i=0;i<depth;++i) indentation+="| ";
|
||||
indentation+=ast_str(this->type);
|
||||
std::cout<<indentation;
|
||||
switch(this->type)
|
||||
{
|
||||
case ast_number: std::cout<<":"<<this->str;break;
|
||||
case ast_string: std::cout<<":"<<this->str;break;
|
||||
case ast_identifier:std::cout<<":"<<this->str;break;
|
||||
case ast_call_hash: std::cout<<":"<<this->str;break;
|
||||
}
|
||||
std::cout<<std::endl;
|
||||
int child_size=this->children.size();
|
||||
for(int i=0;i<child_size;++i)
|
||||
this->children[i].print_ast(depth+1);
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -31,13 +31,79 @@ enum ast_node
|
|||
ast_add,ast_sub,ast_mult,ast_div,ast_link,
|
||||
ast_unary_sub,ast_unary_not,
|
||||
ast_trinocular,
|
||||
ast_for,ast_forindex,ast_foreach,ast_while,
|
||||
ast_for,ast_forindex,ast_foreach,ast_while,ast_new_iter,
|
||||
ast_conditional,ast_if,ast_elsif,ast_else,
|
||||
ast_multi_id,ast_multi_scalar,
|
||||
ast_definition,ast_multi_assign,
|
||||
ast_continue,ast_break,ast_return,
|
||||
};
|
||||
|
||||
std::string ast_str(int type)
|
||||
{
|
||||
std::string str="";
|
||||
switch(type)
|
||||
{
|
||||
case ast_null: str="null";break;
|
||||
case ast_root: str="root";break;
|
||||
case ast_block: str="block";break;
|
||||
case ast_nil: str="nil";break;
|
||||
case ast_number: str="number";break;
|
||||
case ast_string: str="string";break;
|
||||
case ast_identifier: str="id";break;
|
||||
case ast_function: str="function";break;
|
||||
case ast_hash: str="hash";break;
|
||||
case ast_vector: str="vector";break;
|
||||
case ast_hashmember: str="hashmember";break;
|
||||
case ast_call: str="call";break;
|
||||
case ast_call_hash: str="call_hash";break;
|
||||
case ast_call_vec: str="call_vector";break;
|
||||
case ast_call_func: str="call_func";break;
|
||||
case ast_subvec: str="subvec";break;
|
||||
case ast_args: str="arguments";break;
|
||||
case ast_default_arg: str="default_arg";break;
|
||||
case ast_dynamic_id: str="dynamic_id";break;
|
||||
case ast_and: str="and";break;
|
||||
case ast_or: str="or";break;
|
||||
case ast_equal: str="=";break;
|
||||
case ast_add_equal: str="+=";break;
|
||||
case ast_sub_equal: str="-=";break;
|
||||
case ast_mult_equal: str="*=";break;
|
||||
case ast_div_equal: str="/=";break;
|
||||
case ast_link_equal: str="~=";break;
|
||||
case ast_cmp_equal: str="==";break;
|
||||
case ast_cmp_not_equal:str="!=";break;
|
||||
case ast_less_than: str="<";break;
|
||||
case ast_less_equal: str="<=";break;
|
||||
case ast_greater_than: str=">";break;
|
||||
case ast_greater_equal:str=">=";break;
|
||||
case ast_add: str="+";break;
|
||||
case ast_sub: str="-";break;
|
||||
case ast_mult: str="*";break;
|
||||
case ast_div: str="/";break;
|
||||
case ast_link: str="~";break;
|
||||
case ast_unary_sub: str="unary-";break;
|
||||
case ast_unary_not: str="unary!";break;
|
||||
case ast_trinocular: str="trinocular";break;
|
||||
case ast_for: str="for";break;
|
||||
case ast_forindex: str="forindex";break;
|
||||
case ast_foreach: str="foreach";break;
|
||||
case ast_while: str="while";break;
|
||||
case ast_new_iter: str="new_iterator";break;
|
||||
case ast_conditional: str="conditional";break;
|
||||
case ast_if: str="if";break;
|
||||
case ast_elsif: str="elsif";break;
|
||||
case ast_else: str="else";break;
|
||||
case ast_multi_id: str="multi_id";break;
|
||||
case ast_multi_scalar: str="multi_scalar";break;
|
||||
case ast_definition: str="definition";break;
|
||||
case ast_multi_assign: str="multi_assignment";break;
|
||||
case ast_continue: str="continue";break;
|
||||
case ast_break: str="break";break;
|
||||
case ast_return: str="return";break;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
enum parse_error
|
||||
{
|
||||
unknown,
|
||||
|
@ -61,7 +127,9 @@ enum parse_error
|
|||
lack_args,
|
||||
default_arg_not_end,
|
||||
dynamic_id_not_end,
|
||||
multi_assign_lack_val
|
||||
multi_assign_lack_val,
|
||||
lack_definition,
|
||||
lack_loop_iter
|
||||
};
|
||||
|
||||
void error_info(int line,int error_type,std::string error_str="")
|
||||
|
@ -93,6 +161,8 @@ void error_info(int line,int error_type,std::string error_str="")
|
|||
case default_arg_not_end: detail="default argument missing for parameter of "+error_str+".";break;
|
||||
case dynamic_id_not_end: detail="dynamic id must be the end of "+error_str+".";break;
|
||||
case multi_assign_lack_val:detail="multi-assignment lacks value list.";break;
|
||||
case lack_definition: detail="expected a definition expression here.";break;
|
||||
case lack_loop_iter: detail="expected an iterator to loop through.";break;
|
||||
}
|
||||
std::cout<<detail<<std::endl;
|
||||
return;
|
||||
|
|
|
@ -53,6 +53,8 @@ private:
|
|||
bool check_multi_scalar();
|
||||
bool check_function_end(nasal_ast&);
|
||||
bool check_special_call();
|
||||
bool need_semi_check(nasal_ast&);
|
||||
nasal_ast null_node_gen();
|
||||
nasal_ast nil_gen();
|
||||
nasal_ast number_gen();
|
||||
nasal_ast string_gen();
|
||||
|
@ -88,6 +90,7 @@ private:
|
|||
nasal_ast while_loop();
|
||||
nasal_ast for_loop();
|
||||
nasal_ast forei_loop();
|
||||
nasal_ast new_iter_gen();
|
||||
nasal_ast conditional();
|
||||
nasal_ast continue_expr();
|
||||
nasal_ast break_expr();
|
||||
|
@ -97,6 +100,7 @@ public:
|
|||
void clear();
|
||||
void set_toklist(std::vector<token>&);
|
||||
void main_process();
|
||||
nasal_ast& get_root();
|
||||
};
|
||||
|
||||
int nasal_parse::get_error()
|
||||
|
@ -130,8 +134,9 @@ void nasal_parse::main_process()
|
|||
{
|
||||
root.add_child(expr());
|
||||
++ptr;
|
||||
if(ptr<tok_list_size && tok_list[ptr].type==tok_semi) ++ptr;
|
||||
else if(ptr<tok_list_size && (root.get_children().empty() || !check_function_end(root.get_children().back())))
|
||||
if(ptr<tok_list_size && tok_list[ptr].type==tok_semi)
|
||||
++ptr;
|
||||
else if(root.get_children().empty() || need_semi_check(root.get_children().back()))
|
||||
{
|
||||
++error;
|
||||
error_info(error_line,lack_semi);
|
||||
|
@ -141,6 +146,11 @@ void nasal_parse::main_process()
|
|||
return;
|
||||
}
|
||||
|
||||
nasal_ast& nasal_parse::get_root()
|
||||
{
|
||||
return root;
|
||||
}
|
||||
|
||||
void nasal_parse::reset()
|
||||
{
|
||||
this->ptr=0;
|
||||
|
@ -214,6 +224,22 @@ bool nasal_parse::check_special_call()
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool nasal_parse::need_semi_check(nasal_ast& node)
|
||||
{
|
||||
int type=node.get_type();
|
||||
if(type==ast_for || type==ast_foreach || type==ast_forindex || type==ast_while || type==ast_conditional)
|
||||
return false;
|
||||
return !check_function_end(node);
|
||||
}
|
||||
|
||||
nasal_ast nasal_parse::null_node_gen()
|
||||
{
|
||||
nasal_ast node;
|
||||
node.set_line(tok_list[ptr].line);
|
||||
node.set_type(ast_null);
|
||||
return node;
|
||||
}
|
||||
|
||||
nasal_ast nasal_parse::nil_gen()
|
||||
{
|
||||
nasal_ast node;
|
||||
|
@ -500,9 +526,9 @@ nasal_ast nasal_parse::exprs_gen()
|
|||
{
|
||||
node.add_child(expr());
|
||||
++ptr;
|
||||
if(ptr>=tok_list_size) break;
|
||||
if(tok_list[ptr].type==tok_semi) ++ptr;
|
||||
else if(node.get_children().empty() || !check_function_end(node.get_children().back()))
|
||||
if(ptr<tok_list_size || tok_list[ptr].type==tok_semi)
|
||||
++ptr;
|
||||
else if(node.get_children().empty() || need_semi_check(node.get_children().back()))
|
||||
{
|
||||
++error;
|
||||
error_info(error_line,lack_semi);
|
||||
|
@ -1122,8 +1148,76 @@ nasal_ast nasal_parse::for_loop()
|
|||
error_info(error_line,lack_left_curve);
|
||||
return node;
|
||||
}
|
||||
// first expression
|
||||
++ptr;
|
||||
// unfinished
|
||||
if(ptr>=tok_list_size)
|
||||
{
|
||||
++error;
|
||||
error_info(error_line,lack_definition);
|
||||
return node;
|
||||
}
|
||||
if(tok_list[ptr].type==tok_semi)
|
||||
{
|
||||
node.add_child(null_node_gen());
|
||||
--ptr;
|
||||
}
|
||||
else if(tok_list[ptr].type==tok_var)
|
||||
node.add_child(definition());
|
||||
else
|
||||
node.add_child(calculation());
|
||||
++ptr;
|
||||
if(ptr>=tok_list_size || tok_list[ptr].type!=tok_semi)
|
||||
{
|
||||
++error;
|
||||
error_info(error_line,lack_semi);
|
||||
return node;
|
||||
}
|
||||
// conditional expression
|
||||
++ptr;
|
||||
if(ptr>=tok_list_size)
|
||||
{
|
||||
++error;
|
||||
error_info(error_line,lack_calculation);
|
||||
return node;
|
||||
}
|
||||
if(tok_list[ptr].type==tok_semi)
|
||||
{
|
||||
node.add_child(null_node_gen());
|
||||
--ptr;
|
||||
}
|
||||
else
|
||||
node.add_child(calculation());
|
||||
++ptr;
|
||||
if(ptr>=tok_list_size || tok_list[ptr].type!=tok_semi)
|
||||
{
|
||||
++error;
|
||||
error_info(error_line,lack_semi);
|
||||
return node;
|
||||
}
|
||||
//after loop expression
|
||||
++ptr;
|
||||
if(ptr>=tok_list_size)
|
||||
{
|
||||
++error;
|
||||
error_info(error_line,lack_calculation);
|
||||
return node;
|
||||
}
|
||||
if(tok_list[ptr].type==tok_right_curve)
|
||||
{
|
||||
node.add_child(null_node_gen());
|
||||
--ptr;
|
||||
}
|
||||
else
|
||||
node.add_child(calculation());
|
||||
++ptr;
|
||||
if(ptr>=tok_list_size || tok_list[ptr].type!=tok_right_curve)
|
||||
{
|
||||
++error;
|
||||
error_info(error_line,lack_right_curve);
|
||||
return node;
|
||||
}
|
||||
++ptr;
|
||||
node.add_child(exprs_gen());
|
||||
return node;
|
||||
}
|
||||
nasal_ast nasal_parse::forei_loop()
|
||||
|
@ -1142,10 +1236,75 @@ nasal_ast nasal_parse::forei_loop()
|
|||
error_info(error_line,lack_left_curve);
|
||||
return node;
|
||||
}
|
||||
// first expression
|
||||
// foreach/forindex must have an iterator to loop through
|
||||
++ptr;
|
||||
// unfinished
|
||||
if(ptr>=tok_list_size || (tok_list[ptr].type!=tok_var && tok_list[ptr].type!=tok_identifier))
|
||||
{
|
||||
++error;
|
||||
error_info(error_line,lack_loop_iter);
|
||||
return node;
|
||||
}
|
||||
node.add_child(new_iter_gen());
|
||||
++ptr;
|
||||
if(ptr>=tok_list_size || tok_list[ptr].type!=tok_semi)
|
||||
{
|
||||
++error;
|
||||
error_info(error_line,lack_semi);
|
||||
return node;
|
||||
}
|
||||
++ptr;
|
||||
if(ptr>=tok_list_size)
|
||||
{
|
||||
++error;
|
||||
error_info(error_line,lack_calculation);
|
||||
return node;
|
||||
}
|
||||
node.add_child(calculation());
|
||||
++ptr;
|
||||
if(ptr>=tok_list_size || tok_list[ptr].type!=tok_right_curve)
|
||||
{
|
||||
++error;
|
||||
error_info(error_line,lack_right_curve);
|
||||
return node;
|
||||
}
|
||||
++ptr;
|
||||
node.add_child(exprs_gen());
|
||||
return node;
|
||||
}
|
||||
|
||||
nasal_ast nasal_parse::new_iter_gen()
|
||||
{
|
||||
nasal_ast node;
|
||||
if(tok_list[ptr].type==tok_var)
|
||||
{
|
||||
node.set_line(tok_list[ptr].line);
|
||||
node.set_type(ast_new_iter);
|
||||
++ptr;
|
||||
if(ptr>=tok_list_size || tok_list[ptr].type!=tok_identifier)
|
||||
{
|
||||
++error;
|
||||
error_info(error_line,lack_identifier);
|
||||
return node;
|
||||
}
|
||||
node.add_child(id_gen());
|
||||
}
|
||||
else
|
||||
{
|
||||
node.set_line(tok_list[ptr].line);
|
||||
node.set_type(ast_call);
|
||||
node.add_child(id_gen());
|
||||
++ptr;
|
||||
while(ptr<tok_list_size && (tok_list[ptr].type==tok_left_curve || tok_list[ptr].type==tok_left_bracket || tok_list[ptr].type==tok_dot))
|
||||
{
|
||||
node.add_child(call_scalar());
|
||||
++ptr;
|
||||
}
|
||||
--ptr;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
nasal_ast nasal_parse::conditional()
|
||||
{
|
||||
nasal_ast node;
|
||||
|
@ -1216,6 +1375,8 @@ nasal_ast nasal_parse::conditional()
|
|||
tmp.add_child(exprs_gen());
|
||||
node.add_child(tmp);
|
||||
}
|
||||
else
|
||||
--ptr;
|
||||
return node;
|
||||
}
|
||||
nasal_ast nasal_parse::continue_expr()
|
||||
|
|
Loading…
Reference in New Issue