mirror of
https://github.com/ValKmjolnir/Nasal-Interpreter.git
synced 2026-07-22 10:58:47 +08:00
update
This commit is contained in:
@@ -159,8 +159,9 @@ enum parse_error_type
|
|||||||
|
|
||||||
lack_semi,
|
lack_semi,
|
||||||
lack_id,
|
lack_id,
|
||||||
lack_left_curve, // lack left curve
|
lack_left_curve,
|
||||||
lack_right_curve, // lack right curve
|
lack_right_curve,
|
||||||
|
lack_right_brace,
|
||||||
|
|
||||||
definition_lack_id, // lack identifier
|
definition_lack_id, // lack identifier
|
||||||
definition_lack_equal, // lack '=' when not getting ';'
|
definition_lack_equal, // lack '=' when not getting ';'
|
||||||
@@ -215,6 +216,8 @@ void print_parse_error(int error_type,int line,int error_token_type=__stack_end)
|
|||||||
std::cout<<error_info_head<<line<<": expect a \'(\' here."<<std::endl;break;
|
std::cout<<error_info_head<<line<<": expect a \'(\' here."<<std::endl;break;
|
||||||
case lack_right_curve:
|
case lack_right_curve:
|
||||||
std::cout<<error_info_head<<line<<": expect a \')\' here."<<std::endl;break;
|
std::cout<<error_info_head<<line<<": expect a \')\' here."<<std::endl;break;
|
||||||
|
case lack_right_brace:
|
||||||
|
std::cout<<error_info_head<<line<<": expect a \'}\' here."<<std::endl;break;
|
||||||
|
|
||||||
case definition_lack_id:
|
case definition_lack_id:
|
||||||
std::cout<<error_info_head<<line<<": expect identifier(s) after \'var\'."<<std::endl;break;
|
std::cout<<error_info_head<<line<<": expect identifier(s) after \'var\'."<<std::endl;break;
|
||||||
|
|||||||
@@ -154,6 +154,13 @@ struct token
|
|||||||
int line;
|
int line;
|
||||||
int type;
|
int type;
|
||||||
std::string str;
|
std::string str;
|
||||||
|
token& operator=(const token& tmp)
|
||||||
|
{
|
||||||
|
line=tmp.line;
|
||||||
|
type=tmp.type;
|
||||||
|
str=tmp.str;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class nasal_lexer
|
class nasal_lexer
|
||||||
|
|||||||
+91
-29
@@ -4,6 +4,7 @@
|
|||||||
class nasal_parse
|
class nasal_parse
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
bool need_semi_check;// if this is true,this means needs check_semi()
|
||||||
std::stack<token> parse_token_stream;
|
std::stack<token> parse_token_stream;
|
||||||
std::stack<token> checked_tokens;
|
std::stack<token> checked_tokens;
|
||||||
token this_token;
|
token this_token;
|
||||||
@@ -27,6 +28,7 @@ class nasal_parse
|
|||||||
void push_token();
|
void push_token();
|
||||||
int get_error();
|
int get_error();
|
||||||
abstract_syntax_tree& get_root();
|
abstract_syntax_tree& get_root();
|
||||||
|
void check_semi();
|
||||||
|
|
||||||
// check '(' confliction
|
// check '(' confliction
|
||||||
bool check_multi_assignment();// check multi_call_id '=' multi_scalar
|
bool check_multi_assignment();// check multi_call_id '=' multi_scalar
|
||||||
@@ -68,7 +70,7 @@ class nasal_parse
|
|||||||
abstract_syntax_tree multi_scalar_assignment();
|
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 conditional_expr();
|
||||||
};
|
};
|
||||||
|
|
||||||
void nasal_parse::print_detail_token()
|
void nasal_parse::print_detail_token()
|
||||||
@@ -110,7 +112,7 @@ void nasal_parse::get_token_list(std::list<token>& detail_token_stream)
|
|||||||
checked_tokens.pop();
|
checked_tokens.pop();
|
||||||
// add stack_end token
|
// add stack_end token
|
||||||
token end_token;
|
token end_token;
|
||||||
end_token.line=0;
|
end_token.line=detail_token_stream.back().line;
|
||||||
end_token.str="stack_end";
|
end_token.str="stack_end";
|
||||||
end_token.type=__stack_end;
|
end_token.type=__stack_end;
|
||||||
|
|
||||||
@@ -140,11 +142,6 @@ void nasal_parse::get_token()
|
|||||||
parse_token_stream.pop();
|
parse_token_stream.pop();
|
||||||
checked_tokens.push(this_token);
|
checked_tokens.push(this_token);
|
||||||
}
|
}
|
||||||
if(this_token.type==__stack_end)
|
|
||||||
{
|
|
||||||
std::cout<<">>[Parse-error] fatal error."<<std::endl;
|
|
||||||
std::cout<<">>[Stack-end] empty token stack."<<std::endl;
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,13 +150,9 @@ void nasal_parse::push_token()
|
|||||||
if(!checked_tokens.empty())
|
if(!checked_tokens.empty())
|
||||||
{
|
{
|
||||||
parse_token_stream.push(checked_tokens.top());
|
parse_token_stream.push(checked_tokens.top());
|
||||||
this_token=checked_tokens.top();
|
|
||||||
checked_tokens.pop();
|
checked_tokens.pop();
|
||||||
}
|
if(!checked_tokens.empty())
|
||||||
if(this_token.type==__stack_end)
|
this_token=checked_tokens.top();
|
||||||
{
|
|
||||||
std::cout<<">>[Parse-error] fatal error."<<std::endl;
|
|
||||||
std::cout<<">>[Stack-end] empty token stack."<<std::endl;
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -177,6 +170,35 @@ abstract_syntax_tree& nasal_parse::get_root()
|
|||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nasal_parse::check_semi()
|
||||||
|
{
|
||||||
|
// check if this statement has ';' as its end.
|
||||||
|
if(this_token.type==__stack_end)
|
||||||
|
{
|
||||||
|
++error;
|
||||||
|
print_parse_error(lack_semi,this_token.line,this_token.type);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this->get_token();
|
||||||
|
if(this_token.type==__semi)
|
||||||
|
return;
|
||||||
|
else if(this_token.type==__right_brace)
|
||||||
|
{
|
||||||
|
this->push_token();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++error;
|
||||||
|
this->push_token();
|
||||||
|
print_parse_error(lack_semi,this_token.line,this_token.type);
|
||||||
|
this->get_token();
|
||||||
|
if(this_token.type!=__stack_end)
|
||||||
|
this->push_token();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bool nasal_parse::check_multi_assignment()
|
bool nasal_parse::check_multi_assignment()
|
||||||
{
|
{
|
||||||
bool ret=false;
|
bool ret=false;
|
||||||
@@ -285,12 +307,13 @@ void nasal_parse::main_generate()
|
|||||||
// initialize root node
|
// initialize root node
|
||||||
while(!parse_token_stream.empty() && parse_token_stream.top().type!=__stack_end)
|
while(!parse_token_stream.empty() && parse_token_stream.top().type!=__stack_end)
|
||||||
{
|
{
|
||||||
|
need_semi_check=false;
|
||||||
this->get_token();
|
this->get_token();
|
||||||
switch(this_token.type)
|
switch(this_token.type)
|
||||||
{
|
{
|
||||||
case __var:
|
case __var:
|
||||||
this->push_token();
|
this->push_token();
|
||||||
root.get_children().push_back(definition());
|
root.add_children(definition());
|
||||||
break;
|
break;
|
||||||
case __nor_operator: case __sub_operator:
|
case __nor_operator: case __sub_operator:
|
||||||
case __number: case __nil: case __string: case __id:
|
case __number: case __nil: case __string: case __id:
|
||||||
@@ -298,23 +321,33 @@ void nasal_parse::main_generate()
|
|||||||
case __func:
|
case __func:
|
||||||
this->push_token();
|
this->push_token();
|
||||||
root.add_children(calculation());
|
root.add_children(calculation());
|
||||||
|
need_semi_check=true;
|
||||||
break;
|
break;
|
||||||
case __left_curve:
|
case __left_curve:
|
||||||
this->push_token();
|
this->push_token();
|
||||||
if(check_var_in_curve())
|
if(check_var_in_curve())
|
||||||
|
{
|
||||||
root.add_children(definition());
|
root.add_children(definition());
|
||||||
|
// in definition,only function doesn't need check_semi()
|
||||||
|
}
|
||||||
else if(check_multi_assignment())
|
else if(check_multi_assignment())
|
||||||
|
{
|
||||||
|
need_semi_check=true;
|
||||||
root.add_children(multi_scalar_assignment());
|
root.add_children(multi_scalar_assignment());
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
need_semi_check=true;
|
||||||
root.add_children(calculation());
|
root.add_children(calculation());
|
||||||
|
}
|
||||||
|
break;
|
||||||
// '(' is the beginning of too many statements
|
// '(' is the beginning of too many statements
|
||||||
// '(' var id,id,id ')'
|
// '(' var id,id,id ')'
|
||||||
// '(' calculation ')'
|
// '(' calculation ')'
|
||||||
// '(' scalar,scalar,scalar ')' '=' '(' scalar,scalar,scalar ')'
|
// '(' scalar,scalar,scalar ')' '=' '(' scalar,scalar,scalar ')'
|
||||||
break;
|
|
||||||
case __if:
|
case __if:
|
||||||
this->push_token();
|
this->push_token();
|
||||||
root.add_children(choose_expr());
|
root.add_children(conditional_expr());
|
||||||
break;
|
break;
|
||||||
case __while: case __for: case __foreach: case __forindex:
|
case __while: case __for: case __foreach: case __forindex:
|
||||||
this->push_token();
|
this->push_token();
|
||||||
@@ -327,7 +360,8 @@ void nasal_parse::main_generate()
|
|||||||
print_parse_error(error_token_in_main,this_token.line,this_token.type);
|
print_parse_error(error_token_in_main,this_token.line,this_token.type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if(need_semi_check)
|
||||||
|
check_semi();
|
||||||
}
|
}
|
||||||
std::cout<<">>[Parse] complete generation. "<<error<<" error(s)."<<std::endl;
|
std::cout<<">>[Parse] complete generation. "<<error<<" error(s)."<<std::endl;
|
||||||
return;
|
return;
|
||||||
@@ -342,11 +376,13 @@ abstract_syntax_tree nasal_parse::block_generate()
|
|||||||
block_node.set_node_type(__normal_statement_block);
|
block_node.set_node_type(__normal_statement_block);
|
||||||
if(this_token.type!=__left_brace)
|
if(this_token.type!=__left_brace)
|
||||||
{
|
{
|
||||||
|
// only one statement
|
||||||
|
// so this doesn't need check_semi()
|
||||||
switch(this_token.type)
|
switch(this_token.type)
|
||||||
{
|
{
|
||||||
case __var:
|
case __var:
|
||||||
this->push_token();
|
this->push_token();
|
||||||
block_node.get_children().push_back(definition());
|
block_node.add_children(definition());
|
||||||
break;
|
break;
|
||||||
case __nor_operator: case __sub_operator:
|
case __nor_operator: case __sub_operator:
|
||||||
case __number: case __nil: case __string: case __id:
|
case __number: case __nil: case __string: case __id:
|
||||||
@@ -370,7 +406,7 @@ abstract_syntax_tree nasal_parse::block_generate()
|
|||||||
break;
|
break;
|
||||||
case __if:
|
case __if:
|
||||||
this->push_token();
|
this->push_token();
|
||||||
block_node.add_children(choose_expr());
|
block_node.add_children(conditional_expr());
|
||||||
break;
|
break;
|
||||||
case __while: case __for: case __foreach: case __forindex:
|
case __while: case __for: case __foreach: case __forindex:
|
||||||
this->push_token();
|
this->push_token();
|
||||||
@@ -396,12 +432,14 @@ abstract_syntax_tree nasal_parse::block_generate()
|
|||||||
this->get_token();
|
this->get_token();
|
||||||
if(this_token.type!=__semi)
|
if(this_token.type!=__semi)
|
||||||
this->push_token();
|
this->push_token();
|
||||||
|
need_semi_check=false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
this->get_token();
|
||||||
while(this_token.type!=__right_brace && !parse_token_stream.empty() && parse_token_stream.top().type!=__stack_end)
|
while(this_token.type!=__right_brace && !parse_token_stream.empty() && parse_token_stream.top().type!=__stack_end)
|
||||||
{
|
{
|
||||||
this->get_token();
|
need_semi_check=false;
|
||||||
switch(this_token.type)
|
switch(this_token.type)
|
||||||
{
|
{
|
||||||
case __var:
|
case __var:
|
||||||
@@ -414,23 +452,33 @@ abstract_syntax_tree nasal_parse::block_generate()
|
|||||||
case __func:
|
case __func:
|
||||||
this->push_token();
|
this->push_token();
|
||||||
block_node.add_children(calculation());
|
block_node.add_children(calculation());
|
||||||
|
need_semi_check=true;
|
||||||
break;
|
break;
|
||||||
case __left_curve:
|
case __left_curve:
|
||||||
this->push_token();
|
this->push_token();
|
||||||
if(check_var_in_curve())
|
if(check_var_in_curve())
|
||||||
|
{
|
||||||
block_node.add_children(definition());
|
block_node.add_children(definition());
|
||||||
|
// in definition,only function doesn't need check_semi()
|
||||||
|
}
|
||||||
else if(check_multi_assignment())
|
else if(check_multi_assignment())
|
||||||
|
{
|
||||||
|
need_semi_check=true;
|
||||||
block_node.add_children(multi_scalar_assignment());
|
block_node.add_children(multi_scalar_assignment());
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
need_semi_check=true;
|
||||||
block_node.add_children(calculation());
|
block_node.add_children(calculation());
|
||||||
// '(' is the beginning of too many statements
|
}
|
||||||
// '(' var id,id,id ')'
|
|
||||||
// '(' calculation ')'
|
|
||||||
// '(' scalar,scalar,scalar ')' '=' '(' scalar,scalar,scalar ')'
|
|
||||||
break;
|
break;
|
||||||
|
// '(' is the beginning of too many statements
|
||||||
|
// '(' var id,id,id ')'
|
||||||
|
// '(' calculation ')'
|
||||||
|
// '(' scalar,scalar,scalar ')' '=' '(' scalar,scalar,scalar ')'
|
||||||
case __if:
|
case __if:
|
||||||
this->push_token();
|
this->push_token();
|
||||||
block_node.add_children(choose_expr());
|
block_node.add_children(conditional_expr());
|
||||||
break;
|
break;
|
||||||
case __while: case __for: case __foreach: case __forindex:
|
case __while: case __for: case __foreach: case __forindex:
|
||||||
this->push_token();
|
this->push_token();
|
||||||
@@ -439,12 +487,14 @@ abstract_syntax_tree nasal_parse::block_generate()
|
|||||||
case __return:
|
case __return:
|
||||||
this->push_token();
|
this->push_token();
|
||||||
block_node.add_children(return_expr());
|
block_node.add_children(return_expr());
|
||||||
|
need_semi_check=true;
|
||||||
break;
|
break;
|
||||||
case __continue:
|
case __continue:
|
||||||
case __break:
|
case __break:
|
||||||
continue_break_node.set_node_line(this_token.line);
|
continue_break_node.set_node_line(this_token.line);
|
||||||
continue_break_node.set_node_type(this_token.type);
|
continue_break_node.set_node_type(this_token.type);
|
||||||
block_node.add_children(continue_break_node);
|
block_node.add_children(continue_break_node);
|
||||||
|
need_semi_check=true;
|
||||||
break;
|
break;
|
||||||
case __semi:break;
|
case __semi:break;
|
||||||
case __stack_end:break;
|
case __stack_end:break;
|
||||||
@@ -453,10 +503,16 @@ abstract_syntax_tree nasal_parse::block_generate()
|
|||||||
print_parse_error(error_token_in_block,this_token.line,this_token.type);
|
print_parse_error(error_token_in_block,this_token.line,this_token.type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if(need_semi_check)
|
||||||
|
check_semi();
|
||||||
this->get_token();
|
this->get_token();
|
||||||
if(this_token.type!=__right_brace)
|
|
||||||
this->push_token();
|
|
||||||
}
|
}
|
||||||
|
if(this_token.type!=__right_brace)
|
||||||
|
{
|
||||||
|
++error;
|
||||||
|
print_parse_error(lack_right_brace,this_token.line,this_token.type);
|
||||||
|
}
|
||||||
|
need_semi_check=false;
|
||||||
}
|
}
|
||||||
return block_node;
|
return block_node;
|
||||||
}
|
}
|
||||||
@@ -1211,6 +1267,7 @@ abstract_syntax_tree nasal_parse::definition()
|
|||||||
++error;
|
++error;
|
||||||
print_parse_error(definition_lack_equal,this_token.line,this_token.type);
|
print_parse_error(definition_lack_equal,this_token.line,this_token.type);
|
||||||
}
|
}
|
||||||
|
need_semi_check=true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1224,7 +1281,11 @@ abstract_syntax_tree nasal_parse::definition()
|
|||||||
definition_node.add_children(new_var_identifier);
|
definition_node.add_children(new_var_identifier);
|
||||||
this->get_token();
|
this->get_token();
|
||||||
if(this_token.type==__equal)
|
if(this_token.type==__equal)
|
||||||
definition_node.add_children(calculation());// var id = scalar
|
{
|
||||||
|
abstract_syntax_tree calc_scalar=calculation();
|
||||||
|
need_semi_check=(calc_scalar.get_node_type()!=__function);
|
||||||
|
definition_node.add_children(calc_scalar);// var id = scalar
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this->push_token();
|
this->push_token();
|
||||||
@@ -1304,6 +1365,7 @@ abstract_syntax_tree nasal_parse::definition()
|
|||||||
++error;
|
++error;
|
||||||
print_parse_error(definition_lack_equal,this_token.line,this_token.type);
|
print_parse_error(definition_lack_equal,this_token.line,this_token.type);
|
||||||
}
|
}
|
||||||
|
need_semi_check=true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1443,7 +1505,7 @@ abstract_syntax_tree nasal_parse::loop_expr()
|
|||||||
return loop_main_node;
|
return loop_main_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract_syntax_tree nasal_parse::choose_expr()
|
abstract_syntax_tree nasal_parse::conditional_expr()
|
||||||
{
|
{
|
||||||
abstract_syntax_tree choose_main_node;
|
abstract_syntax_tree choose_main_node;
|
||||||
abstract_syntax_tree if_node;
|
abstract_syntax_tree if_node;
|
||||||
|
|||||||
@@ -85,19 +85,19 @@
|
|||||||
| <foreach> '(' (<var> <id>)|(<id>) ';' <scalar> ')' '{' {<statement> ';'} '}'
|
| <foreach> '(' (<var> <id>)|(<id>) ';' <scalar> ')' '{' {<statement> ';'} '}'
|
||||||
;
|
;
|
||||||
|
|
||||||
<choose_expr> = <choose_expr_if> {<choose_expr_elsif>} [<choose_expr_else>]
|
<conditional_expr> = <conditional_expr_if> {<conditional_expr_elsif>} [<conditional_expr_else>]
|
||||||
;
|
;
|
||||||
<choose_expr_if> =
|
<conditional_expr_if> =
|
||||||
<if> '(' <calculation> ')' <statement> [';']
|
<if> '(' <calculation> ')' <statement> [';']
|
||||||
| <if> '(' <calculation> ')' '{' {<statement> ';'} '}'
|
| <if> '(' <calculation> ')' '{' {<statement> ';'} '}'
|
||||||
;
|
;
|
||||||
<choose_expr_elsif> =
|
<conditional_expr_elsif> =
|
||||||
<elsif> '(' <calculation> ')' <statement> [';']
|
<elsif> '(' <calculation> ')' <statement> [';']
|
||||||
| <elsif> '(' <calculation> ')' '{' {<statement> ';'} '}'
|
| <elsif> '(' <calculation> ')' '{' {<statement> ';'} '}'
|
||||||
| <else> <if> '(' <calculation> ')' <statement> [';']
|
| <else> <if> '(' <calculation> ')' <statement> [';']
|
||||||
| <else> <if> '(' <calculation> ')' '{' {<statement> ';'} '}'
|
| <else> <if> '(' <calculation> ')' '{' {<statement> ';'} '}'
|
||||||
;
|
;
|
||||||
<choose_expr_else> =
|
<conditional_expr_else> =
|
||||||
<else> <statement> [';']
|
<else> <statement> [';']
|
||||||
| <else> '{' {<statement> ';'} '}'
|
| <else> '{' {<statement> ';'} '}'
|
||||||
;
|
;
|
||||||
@@ -108,7 +108,7 @@
|
|||||||
<statement> =
|
<statement> =
|
||||||
<definition>
|
<definition>
|
||||||
| <assignment>
|
| <assignment>
|
||||||
| <choose_expr>
|
| <conditional_expr>
|
||||||
| <loop_expr>
|
| <loop_expr>
|
||||||
| <continue_expr>
|
| <continue_expr>
|
||||||
| <break_expr>
|
| <break_expr>
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ elsif(!condition_true and condition_false)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
var c=1;
|
var c=1;
|
||||||
|
var d=1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(condition_true)
|
if(condition_true)
|
||||||
|
|||||||
Reference in New Issue
Block a user