update
This commit is contained in:
parent
fcc09e2e16
commit
9ced4f41c7
|
@ -68,30 +68,29 @@ void print_parse_token(int type)
|
||||||
std::string context="";
|
std::string context="";
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
case __stack_end: context="#"; break;
|
case __stack_end: context=" # "; break;
|
||||||
|
case __cmp_equal: context=" == "; break;
|
||||||
|
case __cmp_not_equal: context=" != "; break;
|
||||||
|
case __cmp_less: context=" < "; break;
|
||||||
|
case __cmp_less_or_equal: context=" <= "; break;
|
||||||
|
case __cmp_more: context=" > "; break;
|
||||||
|
case __cmp_more_or_equal: context=" >= "; break;
|
||||||
|
|
||||||
case __cmp_equal: context="=="; break;
|
case __and_operator: context=" and ";break;
|
||||||
case __cmp_not_equal: context="!="; break;
|
case __or_operator: context=" or "; break;
|
||||||
case __cmp_less: context="<"; break;
|
case __nor_operator: context=" ! "; break;
|
||||||
case __cmp_less_or_equal: context="<="; break;
|
case __add_operator: context=" + "; break;
|
||||||
case __cmp_more: context=">"; break;
|
case __sub_operator: context=" - "; break;
|
||||||
case __cmp_more_or_equal: context=">="; break;
|
case __mul_operator: context=" * "; break;
|
||||||
|
case __div_operator: context=" / "; break;
|
||||||
|
case __link_operator: context=" ~ "; break;
|
||||||
|
|
||||||
case __and_operator: context="and";break;
|
case __equal: context=" = "; break;
|
||||||
case __or_operator: context="or"; break;
|
case __add_equal: context=" += "; break;
|
||||||
case __nor_operator: context="!"; break;
|
case __sub_equal: context=" -= "; break;
|
||||||
case __add_operator: context="+"; break;
|
case __mul_equal: context=" *= "; break;
|
||||||
case __sub_operator: context="-"; break;
|
case __div_equal: context=" /= "; break;
|
||||||
case __mul_operator: context="*"; break;
|
case __link_equal: context=" ~= "; break;
|
||||||
case __div_operator: context="/"; break;
|
|
||||||
case __link_operator: context="~"; break;
|
|
||||||
|
|
||||||
case __equal: context="="; break;
|
|
||||||
case __add_equal: context="+="; break;
|
|
||||||
case __sub_equal: context="-="; break;
|
|
||||||
case __mul_equal: context="*="; break;
|
|
||||||
case __div_equal: context="/="; break;
|
|
||||||
case __link_equal: context="~="; break;
|
|
||||||
|
|
||||||
case __left_brace: context="{"; break;
|
case __left_brace: context="{"; break;
|
||||||
case __right_brace: context="}"; break;
|
case __right_brace: context="}"; break;
|
||||||
|
@ -108,18 +107,18 @@ void print_parse_token(int type)
|
||||||
|
|
||||||
case __unknown_operator: context="unknown_operator";break;
|
case __unknown_operator: context="unknown_operator";break;
|
||||||
|
|
||||||
case __var: context="var"; break;
|
case __var: context="var "; break;
|
||||||
case __func: context="func"; break;
|
case __func: context="func "; break;
|
||||||
case __continue: context="continye"; break;
|
case __continue: context="continue"; break;
|
||||||
case __break: context="break"; break;
|
case __break: context="break"; break;
|
||||||
case __for: context="for"; break;
|
case __for: context="for"; break;
|
||||||
case __forindex: context="forindex"; break;
|
case __forindex: context="forindex"; break;
|
||||||
case __foreach: context="foreach"; break;
|
case __foreach: context="foreach "; break;
|
||||||
case __while: context="while"; break;
|
case __while: context="while"; break;
|
||||||
case __if: context="if"; break;
|
case __if: context="if "; break;
|
||||||
case __elsif: context="elsif"; break;
|
case __elsif: context="elsif "; break;
|
||||||
case __else: context="else"; break;
|
case __else: context="else "; break;
|
||||||
case __return: context="return"; break;
|
case __return: context="return "; break;
|
||||||
case __nil: context="nil"; break;
|
case __nil: context="nil"; break;
|
||||||
|
|
||||||
case __id: context="identifier"; break;
|
case __id: context="identifier"; break;
|
||||||
|
|
|
@ -9,12 +9,12 @@ class nasal_parse
|
||||||
std::stack<token> checked_tokens;
|
std::stack<token> checked_tokens;
|
||||||
token this_token;
|
token this_token;
|
||||||
int error;
|
int error;
|
||||||
int warning;
|
|
||||||
abstract_syntax_tree root;
|
abstract_syntax_tree root;
|
||||||
public:
|
public:
|
||||||
// basic
|
// basic
|
||||||
void delete_all_elements()
|
void delete_all_elements()
|
||||||
{
|
{
|
||||||
|
// used in 'del' command
|
||||||
while(!parse_token_stream.empty())
|
while(!parse_token_stream.empty())
|
||||||
parse_token_stream.pop();
|
parse_token_stream.pop();
|
||||||
while(!checked_tokens.empty())
|
while(!checked_tokens.empty())
|
||||||
|
@ -30,14 +30,14 @@ class nasal_parse
|
||||||
abstract_syntax_tree& get_root();
|
abstract_syntax_tree& get_root();
|
||||||
|
|
||||||
// check '(' confliction
|
// check '(' confliction
|
||||||
bool check_multi_assignment();// multi_call_id = multi_scalar
|
bool check_multi_assignment();// check multi_call_id '=' multi_scalar
|
||||||
bool check_multi_scalar();
|
bool check_multi_scalar(); // check multi_scalar
|
||||||
bool check_var_in_curve(); // multi_definition
|
bool check_var_in_curve(); // check multi_definition: (var id,id,id)
|
||||||
|
|
||||||
// abstract_syntax_tree generation
|
// abstract_syntax_tree generation
|
||||||
|
// block statements generation
|
||||||
void main_generate();
|
void main_generate();
|
||||||
abstract_syntax_tree statements_block_generate();
|
abstract_syntax_tree block_generate();
|
||||||
abstract_syntax_tree multi_scalar_assignment();
|
|
||||||
/*
|
/*
|
||||||
calculation() will get elements generated by and_calculation()
|
calculation() will get elements generated by and_calculation()
|
||||||
and_calculation() will get elements generated by or_calculation()
|
and_calculation() will get elements generated by or_calculation()
|
||||||
|
@ -64,7 +64,9 @@ class nasal_parse
|
||||||
abstract_syntax_tree vector_generate();
|
abstract_syntax_tree vector_generate();
|
||||||
abstract_syntax_tree function_generate();
|
abstract_syntax_tree function_generate();
|
||||||
|
|
||||||
|
// return_expr() generates ebnf: <return> [<calculation>] ';'
|
||||||
abstract_syntax_tree return_expr();
|
abstract_syntax_tree return_expr();
|
||||||
|
abstract_syntax_tree multi_scalar_assignment();
|
||||||
abstract_syntax_tree definition();
|
abstract_syntax_tree definition();
|
||||||
abstract_syntax_tree loop_expr();
|
abstract_syntax_tree loop_expr();
|
||||||
abstract_syntax_tree choose_expr();
|
abstract_syntax_tree choose_expr();
|
||||||
|
@ -72,26 +74,30 @@ class nasal_parse
|
||||||
|
|
||||||
void nasal_parse::print_detail_token()
|
void nasal_parse::print_detail_token()
|
||||||
{
|
{
|
||||||
|
// copy tokens from parse_token_stream
|
||||||
|
// so this function only works when generation hasn't begun.
|
||||||
std::stack<token> tmp=parse_token_stream;
|
std::stack<token> tmp=parse_token_stream;
|
||||||
std::string space="";
|
// indent
|
||||||
|
std::string indent="";
|
||||||
int line=1;
|
int line=1;
|
||||||
std::cout<<line<<"\t";
|
std::cout<<line<<"\t";
|
||||||
while(tmp.top().type!=__stack_end)
|
while((!tmp.empty()) && (tmp.top().type!=__stack_end))
|
||||||
{
|
{
|
||||||
if(tmp.top().line!=line)
|
if(tmp.top().line!=line)
|
||||||
{
|
{
|
||||||
|
// if line changes,print '\n' and number of line
|
||||||
for(int i=line+1;i<tmp.top().line;++i)
|
for(int i=line+1;i<tmp.top().line;++i)
|
||||||
std::cout<<std::endl<<i<<"\t";
|
std::cout<<std::endl<<i<<"\t";
|
||||||
line=tmp.top().line;
|
line=tmp.top().line;
|
||||||
std::cout<<std::endl<<line<<"\t"<<space;
|
std::cout<<std::endl<<line<<"\t"<<indent;
|
||||||
}
|
}
|
||||||
print_parse_token(tmp.top().type);
|
print_parse_token(tmp.top().type);
|
||||||
|
|
||||||
if(tmp.top().type==__left_brace)
|
if(tmp.top().type==__left_brace)
|
||||||
space+=' ';
|
indent+=' ';
|
||||||
std::cout<<" ";
|
|
||||||
tmp.pop();
|
tmp.pop();
|
||||||
if(!tmp.empty() && tmp.top().type==__right_brace)
|
if((!tmp.empty()) && (tmp.top().type==__right_brace))
|
||||||
space.pop_back();
|
indent.pop_back();
|
||||||
}
|
}
|
||||||
std::cout<<std::endl;
|
std::cout<<std::endl;
|
||||||
return;
|
return;
|
||||||
|
@ -103,13 +109,15 @@ void nasal_parse::get_token_list(std::list<token>& detail_token_stream)
|
||||||
parse_token_stream.pop();
|
parse_token_stream.pop();
|
||||||
while(!checked_tokens.empty())
|
while(!checked_tokens.empty())
|
||||||
checked_tokens.pop();
|
checked_tokens.pop();
|
||||||
|
// add stack_end token
|
||||||
token end_token;
|
token end_token;
|
||||||
end_token.line=0;
|
end_token.line=0;
|
||||||
end_token.str="stack_end";
|
end_token.str="stack_end";
|
||||||
end_token.type=__stack_end;
|
end_token.type=__stack_end;
|
||||||
|
|
||||||
parse_token_stream.push(end_token);
|
parse_token_stream.push(end_token);
|
||||||
checked_tokens.push(end_token);
|
checked_tokens.push(end_token);
|
||||||
// clear stacks and initialize them with end_token
|
// clear stacks and initialize them with stack_end token
|
||||||
|
|
||||||
std::stack<token> backward_tmp;
|
std::stack<token> backward_tmp;
|
||||||
// backward_tmp is used to backward detail_token_stream
|
// backward_tmp is used to backward detail_token_stream
|
||||||
|
@ -134,7 +142,10 @@ void nasal_parse::get_token()
|
||||||
checked_tokens.push(this_token);
|
checked_tokens.push(this_token);
|
||||||
}
|
}
|
||||||
if(this_token.type==__stack_end)
|
if(this_token.type==__stack_end)
|
||||||
|
{
|
||||||
|
std::cout<<">>[Parse-error] fatal error."<<std::endl;
|
||||||
std::cout<<">>[Stack-end] empty token stack."<<std::endl;
|
std::cout<<">>[Stack-end] empty token stack."<<std::endl;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,7 +158,10 @@ void nasal_parse::push_token()
|
||||||
checked_tokens.pop();
|
checked_tokens.pop();
|
||||||
}
|
}
|
||||||
if(this_token.type==__stack_end)
|
if(this_token.type==__stack_end)
|
||||||
|
{
|
||||||
|
std::cout<<">>[Parse-error] fatal error."<<std::endl;
|
||||||
std::cout<<">>[Stack-end] empty token stack."<<std::endl;
|
std::cout<<">>[Stack-end] empty token stack."<<std::endl;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,6 +197,12 @@ bool nasal_parse::check_multi_assignment()
|
||||||
{
|
{
|
||||||
this->get_token();
|
this->get_token();
|
||||||
++cnt;
|
++cnt;
|
||||||
|
// these determine statements are used with curve_cnt,bracket_cnt and brace_cnt together
|
||||||
|
// to avoid checking commas in other curves/brackets/braces
|
||||||
|
// such as ([0,1,2,3])
|
||||||
|
// but in multi_assignment, only things like (id[scalar],id.id[scalar]) can be recognized as multi_scalar
|
||||||
|
// if ([0,1,2,3]) and i don't use these judgements,then ([0,1,2,3]) will be recognized as multi_scalar
|
||||||
|
// but in fact ([0,1,2,3]) is not
|
||||||
if(this_token.type==__left_curve) ++curve_cnt;
|
if(this_token.type==__left_curve) ++curve_cnt;
|
||||||
if(this_token.type==__left_bracket) ++bracket_cnt;
|
if(this_token.type==__left_bracket) ++bracket_cnt;
|
||||||
if(this_token.type==__left_brace) ++brace_cnt;
|
if(this_token.type==__left_brace) ++brace_cnt;
|
||||||
|
@ -220,6 +240,9 @@ bool nasal_parse::check_multi_scalar()
|
||||||
{
|
{
|
||||||
this->get_token();
|
this->get_token();
|
||||||
++cnt;
|
++cnt;
|
||||||
|
// these determine statements are used with curve_cnt,bracket_cnt and brace_cnt together
|
||||||
|
// to avoid checking commas in other curves/brackets/braces
|
||||||
|
// such as (a[0,1,2],b(2,3))
|
||||||
if(this_token.type==__left_curve) ++curve_cnt;
|
if(this_token.type==__left_curve) ++curve_cnt;
|
||||||
if(this_token.type==__left_bracket) ++bracket_cnt;
|
if(this_token.type==__left_bracket) ++bracket_cnt;
|
||||||
if(this_token.type==__left_brace) ++brace_cnt;
|
if(this_token.type==__left_brace) ++brace_cnt;
|
||||||
|
@ -245,11 +268,11 @@ bool nasal_parse::check_multi_scalar()
|
||||||
bool nasal_parse::check_var_in_curve()
|
bool nasal_parse::check_var_in_curve()
|
||||||
{
|
{
|
||||||
bool ret=false;
|
bool ret=false;
|
||||||
this->get_token();// get '('
|
this->get_token(); // get '('
|
||||||
this->get_token();
|
this->get_token(); // get 'var' if exists
|
||||||
ret=(this_token.type==__var);
|
ret=(this_token.type==__var);// check
|
||||||
this->push_token();
|
this->push_token(); // push 'var'
|
||||||
this->push_token();
|
this->push_token(); // push '('
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,8 +281,7 @@ void nasal_parse::main_generate()
|
||||||
statement_generate_state=stat_null;
|
statement_generate_state=stat_null;
|
||||||
// initialize state
|
// initialize state
|
||||||
error=0;
|
error=0;
|
||||||
warning=0;
|
// initialize error
|
||||||
// initialize error and warning
|
|
||||||
root.set_clear();
|
root.set_clear();
|
||||||
root.set_node_line(1);
|
root.set_node_line(1);
|
||||||
root.set_node_type(__root);
|
root.set_node_type(__root);
|
||||||
|
@ -310,11 +332,11 @@ void nasal_parse::main_generate()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
std::cout<<">>[Parse] complete generation. "<<error<<" error(s), "<<warning<<" warning(s)."<<std::endl;
|
std::cout<<">>[Parse] complete generation. "<<error<<" error(s)."<<std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract_syntax_tree nasal_parse::statements_block_generate()
|
abstract_syntax_tree nasal_parse::block_generate()
|
||||||
{
|
{
|
||||||
abstract_syntax_tree block_node;
|
abstract_syntax_tree block_node;
|
||||||
abstract_syntax_tree continue_break_node;
|
abstract_syntax_tree continue_break_node;
|
||||||
|
@ -454,7 +476,7 @@ abstract_syntax_tree nasal_parse::multi_scalar_assignment()
|
||||||
{
|
{
|
||||||
front_multi_scalar_node.add_children(scalar_generate());
|
front_multi_scalar_node.add_children(scalar_generate());
|
||||||
this->get_token();
|
this->get_token();
|
||||||
if(this_token.type!=__comma && this_token.type!=__right_curve)
|
if((this_token.type!=__comma) && (this_token.type!=__right_curve))
|
||||||
{
|
{
|
||||||
++error;
|
++error;
|
||||||
print_parse_error(multi_assignment_need_curve,this_token.line,this_token.type);
|
print_parse_error(multi_assignment_need_curve,this_token.line,this_token.type);
|
||||||
|
@ -470,6 +492,7 @@ abstract_syntax_tree nasal_parse::multi_scalar_assignment()
|
||||||
this->get_token();
|
this->get_token();
|
||||||
assignment_node.set_node_line(this_token.line);
|
assignment_node.set_node_line(this_token.line);
|
||||||
assignment_node.set_node_type(this_token.type);
|
assignment_node.set_node_type(this_token.type);
|
||||||
|
// only '=' is alowed in multi_assignment
|
||||||
if(this_token.type!=__equal)
|
if(this_token.type!=__equal)
|
||||||
{
|
{
|
||||||
++error;
|
++error;
|
||||||
|
@ -490,7 +513,7 @@ abstract_syntax_tree nasal_parse::multi_scalar_assignment()
|
||||||
{
|
{
|
||||||
back_multi_scalar_node.add_children(scalar_generate());
|
back_multi_scalar_node.add_children(scalar_generate());
|
||||||
this->get_token();
|
this->get_token();
|
||||||
if(this_token.type!=__comma && this_token.type!=__right_curve)
|
if((this_token.type!=__comma) && (this_token.type!=__right_curve))
|
||||||
{
|
{
|
||||||
++error;
|
++error;
|
||||||
print_parse_error(multi_assignment_need_curve,this_token.line,this_token.type);
|
print_parse_error(multi_assignment_need_curve,this_token.line,this_token.type);
|
||||||
|
@ -884,7 +907,7 @@ abstract_syntax_tree nasal_parse::scalar_generate()
|
||||||
{
|
{
|
||||||
call_vector_node.add_children(calculation());
|
call_vector_node.add_children(calculation());
|
||||||
this->get_token();
|
this->get_token();
|
||||||
if(this_token.type!=__comma && this_token.type!=__right_bracket)
|
if((this_token.type!=__comma) && (this_token.type!=__right_bracket))
|
||||||
{
|
{
|
||||||
++error;
|
++error;
|
||||||
print_parse_error(call_vector_lack_bracket,this_token.line,this_token.type);
|
print_parse_error(call_vector_lack_bracket,this_token.line,this_token.type);
|
||||||
|
@ -1053,7 +1076,7 @@ abstract_syntax_tree nasal_parse::function_generate()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
++error;
|
++error;
|
||||||
print_parse_error(parameter_lack_part,this_token.line);
|
print_parse_error(parameter_lack_part,this_token.line,this_token.type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1076,7 +1099,7 @@ abstract_syntax_tree nasal_parse::function_generate()
|
||||||
if((this_token.type!=__right_curve) && (this_token.type!=__comma))
|
if((this_token.type!=__right_curve) && (this_token.type!=__comma))
|
||||||
{
|
{
|
||||||
++error;
|
++error;
|
||||||
print_parse_error(parameter_lack_curve,this_token.line);
|
print_parse_error(parameter_lack_curve,this_token.line,this_token.type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(this_token.type==__comma)
|
if(this_token.type==__comma)
|
||||||
|
@ -1090,7 +1113,7 @@ abstract_syntax_tree nasal_parse::function_generate()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
this->push_token();
|
this->push_token();
|
||||||
function_node.add_children(statements_block_generate());
|
function_node.add_children(block_generate());
|
||||||
return function_node;
|
return function_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1224,7 +1247,7 @@ abstract_syntax_tree nasal_parse::definition()
|
||||||
{
|
{
|
||||||
this->push_token();
|
this->push_token();
|
||||||
++error;
|
++error;
|
||||||
print_parse_error(definition_wrong_type,this_token.line);
|
print_parse_error(definition_wrong_type,this_token.line,this_token.type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1419,7 +1442,7 @@ abstract_syntax_tree nasal_parse::loop_expr()
|
||||||
print_parse_error(lack_right_curve,this_token.line,this_token.type);
|
print_parse_error(lack_right_curve,this_token.line,this_token.type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
loop_main_node.add_children(statements_block_generate());
|
loop_main_node.add_children(block_generate());
|
||||||
return loop_main_node;
|
return loop_main_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1448,7 +1471,7 @@ abstract_syntax_tree nasal_parse::choose_expr()
|
||||||
++error;
|
++error;
|
||||||
print_parse_error(lack_right_curve,this_token.line);
|
print_parse_error(lack_right_curve,this_token.line);
|
||||||
}
|
}
|
||||||
if_node.add_children(statements_block_generate());
|
if_node.add_children(block_generate());
|
||||||
// add statements
|
// add statements
|
||||||
this->get_token();
|
this->get_token();
|
||||||
if(this_token.type==__elsif)
|
if(this_token.type==__elsif)
|
||||||
|
@ -1472,7 +1495,7 @@ abstract_syntax_tree nasal_parse::choose_expr()
|
||||||
++error;
|
++error;
|
||||||
print_parse_error(lack_right_curve,this_token.line,this_token.type);
|
print_parse_error(lack_right_curve,this_token.line,this_token.type);
|
||||||
}
|
}
|
||||||
elsif_node.add_children(statements_block_generate());
|
elsif_node.add_children(block_generate());
|
||||||
choose_main_node.add_children(elsif_node);
|
choose_main_node.add_children(elsif_node);
|
||||||
this->get_token();// get next 'elsif' if it exists
|
this->get_token();// get next 'elsif' if it exists
|
||||||
}
|
}
|
||||||
|
@ -1485,7 +1508,7 @@ abstract_syntax_tree nasal_parse::choose_expr()
|
||||||
{
|
{
|
||||||
else_node.set_node_line(this_token.type);
|
else_node.set_node_line(this_token.type);
|
||||||
else_node.set_node_type(__else);
|
else_node.set_node_type(__else);
|
||||||
else_node.add_children(statements_block_generate());
|
else_node.add_children(block_generate());
|
||||||
choose_main_node.add_children(else_node);
|
choose_main_node.add_children(else_node);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -104,7 +104,7 @@
|
||||||
|
|
||||||
<continue_expr> = <continue> ;
|
<continue_expr> = <continue> ;
|
||||||
<break_expr> = <break> ;
|
<break_expr> = <break> ;
|
||||||
<return_expr> = <return> [<scalar>] ;
|
<return_expr> = <return> [<calculation>] ;
|
||||||
<statement> =
|
<statement> =
|
||||||
<definition>
|
<definition>
|
||||||
| <assignment>
|
| <assignment>
|
||||||
|
|
Loading…
Reference in New Issue