This commit is contained in:
Valk Richard Li 2020-07-14 01:30:27 -07:00 committed by GitHub
parent f235c168ca
commit b5f0eddb4c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 235 additions and 47 deletions

View File

@ -46,7 +46,7 @@ void lex_func()
if(!lexer.get_error()) if(!lexer.get_error())
lexer.print_token(); lexer.print_token();
else else
std::cout<<">> [lexer] error occurred,stop.\n"; std::cout<<">> [lexer] error(s) occurred,stop.\n";
return; return;
} }
@ -58,10 +58,10 @@ void par_func()
parse.set_toklist(lexer.get_token_list()); parse.set_toklist(lexer.get_token_list());
parse.main_process(); parse.main_process();
if(parse.get_error()) if(parse.get_error())
std::cout<<">> [parse] error occurred,stop.\n"; std::cout<<">> [parse] error(s) occurred,stop.\n";
} }
else else
std::cout<<">> [lexer] error occurred,stop.\n"; std::cout<<">> [lexer] error(s) occurred,stop.\n";
return; return;
} }
@ -70,6 +70,7 @@ int main()
#ifdef _WIN32 #ifdef _WIN32
// use chcp 65001 to use unicode io // use chcp 65001 to use unicode io
system("chcp 65001"); system("chcp 65001");
system("cls");
#endif #endif
// this curve looks really cool // this curve looks really cool
logo(); logo();

View File

@ -100,7 +100,7 @@ multi_scalar::=
'(' <calculation> {',' calculation} ')' '(' <calculation> {',' calculation} ')'
; ;
multi_assignment::= multi_assignment::=
multi_scalar '=' multi_scalar multi_scalar '=' (multi_scalar|calculation)
; ;
loop::= loop::=
while_loop while_loop
@ -114,7 +114,7 @@ for_loop::=
for '(' [definition|calculation] ';' [calculation] ';' [calculation] ')' expressions for '(' [definition|calculation] ';' [calculation] ';' [calculation] ')' expressions
; ;
forei_loop::= forei_loop::=
(forindex | foreach) '(' (definition | assignment) ';' calculation ')' expressions (forindex | foreach) '(' (definition | calculation) ';' calculation ')' expressions
; ;
conditional::= conditional::=
if '(' calculation ')' expressions if '(' calculation ')' expressions

View File

@ -32,7 +32,7 @@ enum ast_node
ast_unary_sub,ast_unary_not, ast_unary_sub,ast_unary_not,
ast_trinocular, ast_trinocular,
ast_for,ast_forindex,ast_foreach,ast_while, ast_for,ast_forindex,ast_foreach,ast_while,
ast_if,ast_elsif,ast_else, ast_conditional,ast_if,ast_elsif,ast_else,
ast_multi_id,ast_multi_scalar, ast_multi_id,ast_multi_scalar,
ast_definition,ast_multi_assign, ast_definition,ast_multi_assign,
ast_continue,ast_break,ast_return, ast_continue,ast_break,ast_return,
@ -56,7 +56,12 @@ enum parse_error
lack_scalar, lack_scalar,
lack_identifier, lack_identifier,
lack_calculation, lack_calculation,
lack_exprs,
lack_token, lack_token,
lack_args,
default_arg_not_end,
dynamic_id_not_end,
multi_assign_lack_val
}; };
void error_info(int line,int error_type,std::string error_str="") void error_info(int line,int error_type,std::string error_str="")
@ -66,23 +71,28 @@ void error_info(int line,int error_type,std::string error_str="")
std::cout<<info<<line<<": "; std::cout<<info<<line<<": ";
switch(error_type) switch(error_type)
{ {
case unknown: detail="unknown error."; break; case unknown: detail="unknown error."; break;
case error_token: detail="error token \'"+error_str+"\'"; break; case error_token: detail="error token \'"+error_str+"\'"; break;
case lack_left_curve: detail="expected \'(\'."; break; case lack_left_curve: detail="expected \'(\'."; break;
case lack_right_curve: detail="expected \')\'."; break; case lack_right_curve: detail="expected \')\'."; break;
case lack_left_bracket: detail="expected \'[\'."; break; case lack_left_bracket: detail="expected \'[\'."; break;
case lack_right_bracket:detail="expected \']\'."; break; case lack_right_bracket: detail="expected \']\'."; break;
case lack_left_brace: detail="expected \'{\'."; break; case lack_left_brace: detail="expected \'{\'."; break;
case lack_right_brace: detail="expected \'}\'."; break; case lack_right_brace: detail="expected \'}\'."; break;
case exprs_lack_rbrace: detail="expected \'}\' with this line\'s \'{\'.";break; case exprs_lack_rbrace: detail="expected \'}\' with this line\'s \'{\'.";break;
case lack_semi: detail="expected \';\'."; break; case lack_semi: detail="expected \';\'."; break;
case lack_comma: detail="expected \',\'."; break; case lack_comma: detail="expected \',\'."; break;
case lack_colon: detail="expected \':\'."; break; case lack_colon: detail="expected \':\'."; break;
case lack_equal: detail="expected \'=\'."; break; case lack_equal: detail="expected \'=\'."; break;
case lack_scalar: detail="expected scalar here."; break; case lack_scalar: detail="expected scalar here."; break;
case lack_identifier: detail="expected identifier here."; break; case lack_identifier: detail="expected identifier here."; break;
case lack_calculation: detail="expected arithmetic-expression here."; break; case lack_calculation: detail="expected arithmetic-expression here."; break;
case lack_token: detail="expected \'"+error_str+"\' here."; break; case lack_exprs: detail="expected expression block here."; break;
case lack_token: detail="expected \'"+error_str+"\' here."; break;
case lack_args: detail="expected arguments here."; break;
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;
} }
std::cout<<detail<<std::endl; std::cout<<detail<<std::endl;
return; return;

View File

@ -157,28 +157,24 @@ bool nasal_parse::check_multi_definition()
bool nasal_parse::check_multi_scalar() bool nasal_parse::check_multi_scalar()
{ {
bool ret=false; bool ret=false;
int check_ptr=ptr,curve_cnt=1,bracket_cnt=0,brace_cnt=0; int check_ptr=ptr+1,curve_cnt=1,bracket_cnt=0,brace_cnt=0;
while(curve_cnt) while(check_ptr<tok_list_size && curve_cnt)
{ {
++check_ptr; switch(tok_list[check_ptr].type)
if(check_ptr<tok_list_size)
{ {
switch(tok_list[check_ptr].type) case tok_left_curve: ++curve_cnt; break;
{ case tok_left_bracket: ++bracket_cnt;break;
case tok_left_curve:++curve_cnt;break; case tok_left_brace: ++brace_cnt; break;
case tok_left_bracket:++bracket_cnt;break; case tok_right_curve: --curve_cnt; break;
case tok_left_brace:++brace_cnt;break; case tok_right_bracket:--bracket_cnt;break;
case tok_right_curve:--curve_cnt;break; case tok_right_brace: --brace_cnt; break;
case tok_right_bracket:--bracket_cnt;break;
case tok_right_brace:--brace_cnt;break;
}
} }
else break;
if(curve_cnt==1 && !bracket_cnt && !brace_cnt && tok_list[check_ptr].type==tok_comma) if(curve_cnt==1 && !bracket_cnt && !brace_cnt && tok_list[check_ptr].type==tok_comma)
{ {
ret=true; ret=true;
break; break;
} }
++check_ptr;
} }
return ret; return ret;
} }
@ -362,14 +358,14 @@ nasal_ast nasal_parse::args_list_gen()
nasal_ast node; nasal_ast node;
node.set_line(tok_list[ptr].line); node.set_line(tok_list[ptr].line);
node.set_type(ast_args); node.set_type(ast_args);
++ptr;
while(ptr<tok_list_size && tok_list[ptr].type!=tok_right_curve) while(ptr<tok_list_size && tok_list[ptr].type!=tok_right_curve)
{ {
nasal_ast tmp; nasal_ast tmp;
++ptr;
if(tok_list[ptr].type!=tok_identifier) if(tok_list[ptr].type!=tok_identifier)
{ {
++error; ++error;
error_info(tok_list[ptr].line,lack_identifier); error_info(error_line,lack_args);
return node; return node;
} }
tmp=id_gen(); tmp=id_gen();
@ -383,6 +379,7 @@ nasal_ast nasal_parse::args_list_gen()
special_arg.add_child(tmp); special_arg.add_child(tmp);
++ptr; ++ptr;
special_arg.add_child(scalar()); special_arg.add_child(scalar());
special_arg.set_type(ast_default_arg);
} }
else else
{ {
@ -401,7 +398,48 @@ nasal_ast nasal_parse::args_list_gen()
{ {
++error; ++error;
error_info(error_line,lack_comma); error_info(error_line,lack_comma);
--ptr; return node;
}
if(tok_list[ptr].type==tok_comma)
++ptr;
}
if(ptr>=tok_list_size)
{
++error;
error_info(error_line,lack_right_curve);
}
std::string args_format="func(";
int node_child_size=node.get_children().size();
for(int i=0;i<node_child_size;++i)
{
switch(node.get_children()[i].get_type())
{
case ast_identifier: args_format+="val";break;
case ast_default_arg: args_format+="val=scalar";break;
case ast_dynamic_id: args_format+="val...";break;
}
if(i!=node_child_size-1)
args_format+=",";
}
args_format+=")";
bool checked_default_val=false;
bool checked_dynamic_ids=false;
for(int i=0;i<node_child_size;++i)
{
if(node.get_children()[i].get_type()==ast_default_arg)
checked_default_val=true;
else if(node.get_children()[i].get_type()==ast_dynamic_id)
checked_dynamic_ids=true;
if(checked_default_val && node.get_children()[i].get_type()!=ast_default_arg)
{
++error;
error_info(node.get_children()[i].get_line(),default_arg_not_end,args_format);
}
if(checked_dynamic_ids && i!=node_child_size-1)
{
++error;
error_info(node.get_children()[i].get_line(),dynamic_id_not_end,args_format);
} }
} }
return node; return node;
@ -446,26 +484,35 @@ nasal_ast nasal_parse::expr()
nasal_ast nasal_parse::exprs_gen() nasal_ast nasal_parse::exprs_gen()
{ {
nasal_ast node; nasal_ast node;
if(ptr>=tok_list_size)
{
++error;
error_info(error_line,lack_exprs);
return node;
}
node.set_line(tok_list[ptr].line); node.set_line(tok_list[ptr].line);
node.set_type(ast_block); node.set_type(ast_block);
if(tok_list[ptr].type==tok_left_brace) if(tok_list[ptr].type==tok_left_brace)
{ {
int left_brace_line=tok_list[ptr].line; int left_brace_line=tok_list[ptr].line;
++ptr;
while(ptr<tok_list_size && tok_list[ptr].type!=tok_right_brace) while(ptr<tok_list_size && tok_list[ptr].type!=tok_right_brace)
{ {
node.add_child(expr()); node.add_child(expr());
++ptr; ++ptr;
if(ptr<tok_list_size && tok_list[ptr].type==tok_semi) ++ptr; if(ptr>=tok_list_size) break;
else if(ptr<tok_list_size && (node.get_children().empty() || !check_function_end(node.get_children().back()))) if(tok_list[ptr].type==tok_semi) ++ptr;
else if(node.get_children().empty() || !check_function_end(node.get_children().back()))
{ {
++error; ++error;
error_info(error_line,lack_semi); error_info(error_line,lack_semi);
break;
} }
} }
if(ptr>=tok_list_size) if(ptr>=tok_list_size || tok_list[ptr].type!=tok_right_brace)
{ {
error_info(left_brace_line,exprs_lack_rbrace);
++error; ++error;
error_info(left_brace_line,exprs_lack_rbrace);
} }
} }
else else
@ -480,6 +527,12 @@ nasal_ast nasal_parse::exprs_gen()
nasal_ast nasal_parse::calculation() nasal_ast nasal_parse::calculation()
{ {
nasal_ast node; nasal_ast node;
if(ptr>=tok_list_size)
{
++error;
error_info(error_line,lack_calculation);
return node;
}
node=or_expr(); node=or_expr();
++ptr; ++ptr;
if(ptr<tok_list_size && tok_list[ptr].type==tok_quesmark) if(ptr<tok_list_size && tok_list[ptr].type==tok_quesmark)
@ -686,7 +739,9 @@ nasal_ast nasal_parse::scalar()
{ {
nasal_ast node; nasal_ast node;
node.set_line(tok_list[ptr].line); node.set_line(tok_list[ptr].line);
if(tok_list[ptr].type==tok_number) if(tok_list[ptr].type==tok_nil)
node=nil_gen();
else if(tok_list[ptr].type==tok_number)
node=number_gen(); node=number_gen();
else if(tok_list[ptr].type==tok_string) else if(tok_list[ptr].type==tok_string)
node=string_gen(); node=string_gen();
@ -869,7 +924,16 @@ nasal_ast nasal_parse::definition()
return node; return node;
} }
++ptr; ++ptr;
// unfinished if(ptr>=tok_list_size)
{
++error;
error_info(error_line,lack_scalar);
return node;
}
if(tok_list[ptr].type==tok_left_curve)
node.add_child(check_multi_scalar()?multi_scalar():calculation());
else
node.add_child(calculation());
return node; return node;
} }
nasal_ast nasal_parse::normal_def() nasal_ast nasal_parse::normal_def()
@ -951,11 +1015,53 @@ nasal_ast nasal_parse::multi_id()
nasal_ast nasal_parse::multi_scalar() nasal_ast nasal_parse::multi_scalar()
{ {
nasal_ast node; nasal_ast node;
node.set_line(tok_list[ptr].line);
node.set_type(ast_multi_scalar);
++ptr;
while(ptr<tok_list_size && tok_list[ptr].type!=tok_right_curve)
{
node.add_child(calculation());
++ptr;
if(ptr>=tok_list_size) break;
if(tok_list[ptr].type==tok_comma) ++ptr;
else if(tok_list[ptr].type!=tok_comma && tok_list[ptr].type!=tok_right_curve)
{
++error;
error_info(error_line,lack_comma);
break;
}
}
if(ptr>=tok_list_size || tok_list[ptr].type!=tok_right_curve)
{
++error;
error_info(error_line,lack_right_curve);
}
return node; return node;
} }
nasal_ast nasal_parse::multi_assgin() nasal_ast nasal_parse::multi_assgin()
{ {
nasal_ast node; nasal_ast node;
node.set_line(tok_list[ptr].line);
node.set_type(ast_multi_assign);
node.add_child(multi_scalar());
++ptr;
if(ptr>=tok_list_size || tok_list[ptr].type!=tok_equal)
{
++error;
error_info(error_line,lack_equal);
return node;
}
++ptr;
if(ptr>=tok_list_size)
{
++error;
error_info(error_line,multi_assign_lack_val);
return node;
}
if(tok_list[ptr].type==tok_left_curve)
node.add_child(check_multi_scalar()?multi_scalar():calculation());
else
node.add_child(calculation());
return node; return node;
} }
nasal_ast nasal_parse::loop() nasal_ast nasal_parse::loop()
@ -991,12 +1097,14 @@ nasal_ast nasal_parse::while_loop()
{ {
++error; ++error;
error_info(error_line,lack_left_curve); error_info(error_line,lack_left_curve);
return node;
} }
++ptr; ++ptr;
if(ptr>=tok_list_size || tok_list[ptr].type!=tok_right_curve) if(ptr>=tok_list_size || tok_list[ptr].type!=tok_right_curve)
{ {
++error; ++error;
error_info(error_line,lack_right_curve); error_info(error_line,lack_right_curve);
return node;
} }
++ptr; ++ptr;
node.add_child(exprs_gen()); node.add_child(exprs_gen());
@ -1012,6 +1120,7 @@ nasal_ast nasal_parse::for_loop()
{ {
++error; ++error;
error_info(error_line,lack_left_curve); error_info(error_line,lack_left_curve);
return node;
} }
++ptr; ++ptr;
// unfinished // unfinished
@ -1031,6 +1140,7 @@ nasal_ast nasal_parse::forei_loop()
{ {
++error; ++error;
error_info(error_line,lack_left_curve); error_info(error_line,lack_left_curve);
return node;
} }
++ptr; ++ptr;
// unfinished // unfinished
@ -1039,8 +1149,73 @@ nasal_ast nasal_parse::forei_loop()
nasal_ast nasal_parse::conditional() nasal_ast nasal_parse::conditional()
{ {
nasal_ast node; nasal_ast node;
nasal_ast tmp;
node.set_line(tok_list[ptr].line); node.set_line(tok_list[ptr].line);
node.set_type(ast_if); node.set_type(ast_conditional);
tmp.set_line(tok_list[ptr].line);
tmp.set_type(ast_if);
++ptr;
if(ptr>=tok_list_size || tok_list[ptr].type!=tok_left_curve)
{
++error;
error_info(error_line,lack_left_curve);
return node;
}
++ptr;
tmp.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;
tmp.add_child(exprs_gen());
node.add_child(tmp);
// end of if-expression
++ptr;
while(ptr<tok_list_size && (tok_list[ptr].type==tok_elsif || (tok_list[ptr].type==tok_else && ptr+1<tok_list_size && tok_list[ptr+1].type==tok_if)))
{
if(tok_list[ptr].type==tok_else) ++ptr;
++ptr;
if(ptr>=tok_list_size || tok_list[ptr].type!=tok_left_curve)
{
++error;
error_info(error_line,lack_left_curve);
return node;
}
tmp.set_line(tok_list[ptr].line);
tmp.set_type(ast_elsif);
tmp.get_children().clear();
++ptr;
tmp.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;
tmp.add_child(exprs_gen());
node.add_child(tmp);
++ptr;
}
// end of elsif-expression
// after this process,ptr will point to the next token of exprs_gen()'s last token
// for example
// else if(scalar){} else {}
// ptr^
if(ptr<tok_list_size && tok_list[ptr].type==tok_else)
{
tmp.set_line(tok_list[ptr].line);
tmp.set_type(ast_else);
tmp.get_children().clear();
++ptr;
tmp.add_child(exprs_gen());
node.add_child(tmp);
}
return node; return node;
} }
nasal_ast nasal_parse::continue_expr() nasal_ast nasal_parse::continue_expr()
@ -1069,6 +1244,8 @@ nasal_ast nasal_parse::return_expr()
if(type==tok_nil || type==tok_number || type==tok_string || type==tok_identifier || type==tok_func || if(type==tok_nil || type==tok_number || type==tok_string || type==tok_identifier || type==tok_func ||
type==tok_sub || type==tok_not || type==tok_left_curve || type==tok_left_bracket || type==tok_left_brace) type==tok_sub || type==tok_not || type==tok_left_curve || type==tok_left_bracket || type==tok_left_brace)
node.add_child(calculation()); node.add_child(calculation());
else
--ptr;
} }
return node; return node;
} }