optimize nasal_parser

This commit is contained in:
ValKmjolnir 2022-07-26 20:04:57 +08:00
parent ea33ce020c
commit 3e8b9e4846
1 changed files with 40 additions and 60 deletions

View File

@ -123,7 +123,7 @@ void nasal_parse::compile(const nasal_lexer& lexer)
} }
void nasal_parse::die(u32 line,string info,bool report_prev=false) void nasal_parse::die(u32 line,string info,bool report_prev=false)
{ {
int col=(int)tokens[ptr].col-(int)tokens[ptr].str.length(); int col=(int)tokens[ptr].col-(tokens[ptr].type==tok_eof?0:(int)tokens[ptr].str.length());
if(tokens[ptr].type==tok_str) if(tokens[ptr].type==tok_str)
col-=2; // tok_str's str has no \" col-=2; // tok_str's str has no \"
if(report_prev && ptr) // used to report lack of ',' ';' if(report_prev && ptr) // used to report lack of ',' ';'
@ -147,7 +147,7 @@ void nasal_parse::match(u32 type,const char* info)
case tok_num:die(error_line,"expected number"); break; case tok_num:die(error_line,"expected number"); break;
case tok_str:die(error_line,"expected string"); break; case tok_str:die(error_line,"expected string"); break;
case tok_id: die(error_line,"expected identifier");break; case tok_id: die(error_line,"expected identifier");break;
default: die(error_line,"expected \'"+string(tok_table[type-tok_for].str)+"\'"); break; default: die(error_line,"expected '"+string(tok_table[type-tok_for].str)+"'"); break;
} }
return; return;
} }
@ -160,7 +160,7 @@ bool nasal_parse::check_comma(const u32* panic_set)
for(u32 i=0;panic_set[i];++i) for(u32 i=0;panic_set[i];++i)
if(tokens[ptr].type==panic_set[i]) if(tokens[ptr].type==panic_set[i])
{ {
die(error_line,"expected \',\' between scalars",true); die(error_line,"expected ',' between scalars",true);
return true; return true;
} }
return false; return false;
@ -263,18 +263,21 @@ nasal_ast nasal_parse::num()
{ {
nasal_ast node(tokens[ptr].line,ast_num); nasal_ast node(tokens[ptr].line,ast_num);
node.set_num(str2num(tokens[ptr].str.c_str())); node.set_num(str2num(tokens[ptr].str.c_str()));
match(tok_num);
return node; return node;
} }
nasal_ast nasal_parse::str() nasal_ast nasal_parse::str()
{ {
nasal_ast node(tokens[ptr].line,ast_str); nasal_ast node(tokens[ptr].line,ast_str);
node.set_str(tokens[ptr].str); node.set_str(tokens[ptr].str);
match(tok_str);
return node; return node;
} }
nasal_ast nasal_parse::id() nasal_ast nasal_parse::id()
{ {
nasal_ast node(tokens[ptr].line,ast_id); nasal_ast node(tokens[ptr].line,ast_id);
node.set_str(tokens[ptr].str); node.set_str(tokens[ptr].str);
match(tok_id);
return node; return node;
} }
nasal_ast nasal_parse::vec() nasal_ast nasal_parse::vec()
@ -300,7 +303,7 @@ nasal_ast nasal_parse::vec()
else if(tokens[ptr].type!=tok_rbracket && !check_comma(panic_set)) else if(tokens[ptr].type!=tok_rbracket && !check_comma(panic_set))
break; break;
} }
match(tok_rbracket,"expected \']\' when generating vector"); match(tok_rbracket,"expected ']' when generating vector");
return node; return node;
} }
nasal_ast nasal_parse::hash() nasal_ast nasal_parse::hash()
@ -313,34 +316,29 @@ nasal_ast nasal_parse::hash()
if(tokens[ptr].type==tok_comma) if(tokens[ptr].type==tok_comma)
match(tok_comma); match(tok_comma);
else if(tokens[ptr].type==tok_id || tokens[ptr].type==tok_str)// first set of hashmember else if(tokens[ptr].type==tok_id || tokens[ptr].type==tok_str)// first set of hashmember
die(error_line,"expected \',\' between hash members",true); die(error_line,"expected ',' between hash members",true);
else else
break; break;
} }
match(tok_rbrace,"expected \'}\' when generating hash"); match(tok_rbrace,"expected '}' when generating hash");
return node; return node;
} }
nasal_ast nasal_parse::pair() nasal_ast nasal_parse::pair()
{ {
nasal_ast node(tokens[ptr].line,ast_pair); nasal_ast node(tokens[ptr].line,ast_pair);
if(tokens[ptr].type==tok_id) if(tokens[ptr].type==tok_id)
{
node.add(id()); node.add(id());
match(tok_id);
}
else if(tokens[ptr].type==tok_str) else if(tokens[ptr].type==tok_str)
{
node.add(str()); node.add(str());
match(tok_str);
}
else else
match(tok_id); match(tok_id,"expected hashmap key");
match(tok_colon); match(tok_colon);
node.add(calc()); node.add(calc());
return node; return node;
} }
nasal_ast nasal_parse::func() nasal_ast nasal_parse::func()
{ {
++in_func;
nasal_ast node(tokens[ptr].line,ast_func); nasal_ast node(tokens[ptr].line,ast_func);
match(tok_func); match(tok_func);
if(tokens[ptr].type==tok_lcurve) if(tokens[ptr].type==tok_lcurve)
@ -348,6 +346,7 @@ nasal_ast nasal_parse::func()
else else
node.add(null()); node.add(null());
node.add(exprs()); node.add(exprs());
--in_func;
return node; return node;
} }
nasal_ast nasal_parse::args() nasal_ast nasal_parse::args()
@ -357,7 +356,6 @@ nasal_ast nasal_parse::args()
while(tokens[ptr].type!=tok_rcurve) while(tokens[ptr].type!=tok_rcurve)
{ {
nasal_ast tmp=id(); nasal_ast tmp=id();
match(tok_id);
if(tokens[ptr].type==tok_eq || tokens[ptr].type==tok_ellipsis) if(tokens[ptr].type==tok_eq || tokens[ptr].type==tok_ellipsis)
{ {
nasal_ast special_arg(tokens[ptr].line,ast_null); nasal_ast special_arg(tokens[ptr].line,ast_null);
@ -381,11 +379,11 @@ nasal_ast nasal_parse::args()
if(tokens[ptr].type==tok_comma) if(tokens[ptr].type==tok_comma)
match(tok_comma); match(tok_comma);
else if(tokens[ptr].type==tok_id)// first set of identifier else if(tokens[ptr].type==tok_id)// first set of identifier
die(error_line,"expected \',\' between identifiers",true); die(error_line,"expected ',' between identifiers",true);
else else
break; break;
} }
match(tok_rcurve,"expected \')\' after parameter list"); match(tok_rcurve,"expected ')' after parameter list");
string format="func("; string format="func(";
for(auto& tmp:node.child()) for(auto& tmp:node.child())
@ -488,9 +486,9 @@ nasal_ast nasal_parse::exprs()
match(tok_semi); match(tok_semi);
// the last expression can be recognized without semi // the last expression can be recognized without semi
else if(need_semi_check(node.child().back()) && tokens[ptr].type!=tok_rbrace) else if(need_semi_check(node.child().back()) && tokens[ptr].type!=tok_rbrace)
die(error_line,"expected \';\'",true); die(error_line,"expected ';'",true);
} }
match(tok_rbrace,"expected \'}\' when generating expressions"); match(tok_rbrace,"expected '}' when generating expressions");
} }
else else
{ {
@ -612,20 +610,13 @@ nasal_ast nasal_parse::unary()
nasal_ast nasal_parse::scalar() nasal_ast nasal_parse::scalar()
{ {
nasal_ast node(tokens[ptr].line,ast_null); nasal_ast node(tokens[ptr].line,ast_null);
if(tokens[ptr].type==tok_nil) {node=nil(); match(tok_nil);} if(tokens[ptr].type==tok_nil) {node=nil();match(tok_nil);}
else if(tokens[ptr].type==tok_num){node=num(); match(tok_num);} else if(tokens[ptr].type==tok_num) node=num();
else if(tokens[ptr].type==tok_str){node=str(); match(tok_str);} else if(tokens[ptr].type==tok_str) node=str();
else if(tokens[ptr].type==tok_id) {node=id(); match(tok_id); } else if(tokens[ptr].type==tok_id) node=id();
else if(tokens[ptr].type==tok_func) else if(tokens[ptr].type==tok_func) node=func();
{ else if(tokens[ptr].type==tok_lbracket) node=vec();
++in_func; else if(tokens[ptr].type==tok_lbrace) node=hash();
node=func();
--in_func;
}
else if(tokens[ptr].type==tok_lbracket)
node=vec();
else if(tokens[ptr].type==tok_lbrace)
node=hash();
else if(tokens[ptr].type==tok_lcurve) else if(tokens[ptr].type==tok_lcurve)
{ {
match(tok_lcurve); match(tok_lcurve);
@ -637,7 +628,6 @@ nasal_ast nasal_parse::scalar()
match(tok_var); match(tok_var);
node.set_type(ast_def); node.set_type(ast_def);
node.add(id()); node.add(id());
match(tok_id);
match(tok_eq); match(tok_eq);
node.add(calc()); node.add(calc());
} }
@ -673,7 +663,7 @@ nasal_ast nasal_parse::callh()
nasal_ast node(tokens[ptr].line,ast_callh); nasal_ast node(tokens[ptr].line,ast_callh);
match(tok_dot); match(tok_dot);
node.set_str(tokens[ptr].str); node.set_str(tokens[ptr].str);
match(tok_id); match(tok_id,"expected hashmap key"); // get key
return node; return node;
} }
nasal_ast nasal_parse::callv() nasal_ast nasal_parse::callv()
@ -700,7 +690,7 @@ nasal_ast nasal_parse::callv()
else if(tokens[ptr].type!=tok_rbracket && !check_comma(panic_set)) else if(tokens[ptr].type!=tok_rbracket && !check_comma(panic_set))
break; break;
} }
match(tok_rbracket,"expected \']\' when calling vector"); match(tok_rbracket,"expected ']' when calling vector");
return node; return node;
} }
nasal_ast nasal_parse::callf() nasal_ast nasal_parse::callf()
@ -727,7 +717,7 @@ nasal_ast nasal_parse::callf()
else if(tokens[ptr].type!=tok_rcurve && !check_comma(panic_set)) else if(tokens[ptr].type!=tok_rcurve && !check_comma(panic_set))
break; break;
} }
match(tok_rcurve,"expected \')\' when calling function"); match(tok_rcurve,"expected ')' when calling function");
return node; return node;
} }
nasal_ast nasal_parse::subvec() nasal_ast nasal_parse::subvec()
@ -751,7 +741,7 @@ nasal_ast nasal_parse::definition()
match(tok_var); match(tok_var);
switch(tokens[ptr].type) switch(tokens[ptr].type)
{ {
case tok_id: node.add(id());match(tok_id);break; case tok_id: node.add(id());break;
case tok_lcurve: node.add(outcurve_def());break; case tok_lcurve: node.add(outcurve_def());break;
default: die(error_line,"expected identifier");break; default: die(error_line,"expected identifier");break;
} }
@ -764,10 +754,9 @@ nasal_ast nasal_parse::definition()
else else
node.add(calc()); node.add(calc());
if(node[0].type()==ast_id && node[1].type()==ast_multi_scalar) if(node[0].type()==ast_id && node[1].type()==ast_multi_scalar)
die(node[1].line(),"one identifier cannot accept too many values"); die(node[1].line(),"one variable cannot accept too many values");
else if(node[0].type()==ast_multi_id && node[1].type()==ast_multi_scalar) else if(node[0].type()==ast_multi_id && node[1].type()==ast_multi_scalar && node[0].size()!=node[1].size())
if(node[0].size()!=node[1].size()) die(node[0].line(),"too much or lack values in multi-definition");
die(node[0].line(),"too much or lack values in multi-definition");
return node; return node;
} }
nasal_ast nasal_parse::incurve_def() nasal_ast nasal_parse::incurve_def()
@ -791,7 +780,6 @@ nasal_ast nasal_parse::multi_id()
while(tokens[ptr].type!=tok_eof) while(tokens[ptr].type!=tok_eof)
{ {
node.add(id()); node.add(id());
match(tok_id);
if(is_call(tokens[ptr].type)) if(is_call(tokens[ptr].type))
{ {
call_scalar();// recognize calls but this is still a syntax error call_scalar();// recognize calls but this is still a syntax error
@ -800,7 +788,7 @@ nasal_ast nasal_parse::multi_id()
if(tokens[ptr].type==tok_comma) if(tokens[ptr].type==tok_comma)
match(tok_comma); match(tok_comma);
else if(tokens[ptr].type==tok_id)// first set of identifier else if(tokens[ptr].type==tok_id)// first set of identifier
die(error_line,"expected \',\' between identifiers",true); die(error_line,"expected ',' between identifiers",true);
else else
break; break;
} }
@ -829,7 +817,7 @@ nasal_ast nasal_parse::multi_scalar(bool check_call_memory)
else if(tokens[ptr].type!=tok_rcurve && !check_comma(panic_set)) else if(tokens[ptr].type!=tok_rcurve && !check_comma(panic_set))
break; break;
} }
match(tok_rcurve,"expected \')\' after multi-scalar"); match(tok_rcurve,"expected ')' after multi-scalar");
return node; return node;
} }
nasal_ast nasal_parse::multi_assgin() nasal_ast nasal_parse::multi_assgin()
@ -891,7 +879,7 @@ nasal_ast nasal_parse::for_loop()
node.add(lcurve_expr()); node.add(lcurve_expr());
else else
node.add(calc()); node.add(calc());
match(tok_semi,"expected \';\' in for(;;)"); match(tok_semi,"expected ';' in for(;;)");
// conditional expression // conditional expression
if(tokens[ptr].type==tok_eof) if(tokens[ptr].type==tok_eof)
die(error_line,"expected conditional expr"); die(error_line,"expected conditional expr");
@ -899,7 +887,7 @@ nasal_ast nasal_parse::for_loop()
node.add(null()); node.add(null());
else else
node.add(calc()); node.add(calc());
match(tok_semi,"expected \';\' in for(;;)"); match(tok_semi,"expected ';' in for(;;)");
//after loop expression //after loop expression
if(tokens[ptr].type==tok_eof) if(tokens[ptr].type==tok_eof)
die(error_line,"expected calculation"); die(error_line,"expected calculation");
@ -925,7 +913,7 @@ nasal_ast nasal_parse::forei_loop()
if(tokens[ptr].type!=tok_var && tokens[ptr].type!=tok_id) if(tokens[ptr].type!=tok_var && tokens[ptr].type!=tok_id)
die(error_line,"expected iterator"); die(error_line,"expected iterator");
node.add(iter_gen()); node.add(iter_gen());
match(tok_semi,"expected \';\' in foreach/forindex(iter;vector)"); match(tok_semi,"expected ';' in foreach/forindex(iter;vector)");
if(tokens[ptr].type==tok_eof) if(tokens[ptr].type==tok_eof)
die(error_line,"expected vector"); die(error_line,"expected vector");
node.add(calc()); node.add(calc());
@ -941,13 +929,11 @@ nasal_ast nasal_parse::iter_gen()
match(tok_var); match(tok_var);
node.set_type(ast_iter); node.set_type(ast_iter);
node.add(id()); node.add(id());
match(tok_id);
} }
else else
{ {
node.set_type(ast_call); node.set_type(ast_call);
node.add(id()); node.add(id());
match(tok_id);
while(is_call(tokens[ptr].type)) while(is_call(tokens[ptr].type))
node.add(call_scalar()); node.add(call_scalar());
check_memory_reachable(node); check_memory_reachable(node);
@ -1000,17 +986,11 @@ nasal_ast nasal_parse::ret_expr()
nasal_ast node(tokens[ptr].line,ast_ret); nasal_ast node(tokens[ptr].line,ast_ret);
match(tok_ret); match(tok_ret);
u32 type=tokens[ptr].type; u32 type=tokens[ptr].type;
if( if(type==tok_nil || type==tok_num ||
type==tok_nil || type==tok_str || type==tok_id ||
type==tok_num || type==tok_func || type==tok_sub ||
type==tok_str || type==tok_not || type==tok_lcurve ||
type==tok_id || type==tok_lbracket || type==tok_lbrace)
type==tok_func ||
type==tok_sub ||
type==tok_not ||
type==tok_lcurve ||
type==tok_lbracket ||
type==tok_lbrace)
node.add(calc()); node.add(calc());
return node; return node;
} }