This commit is contained in:
Valk Richard Li 2020-07-15 01:59:38 -07:00 committed by GitHub
parent b5f0eddb4c
commit 6ba888e445
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 279 additions and 12 deletions

View File

@ -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")
{
;

View File

@ -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

View File

@ -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;

View File

@ -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()