update
This commit is contained in:
parent
0e5ce8d7fa
commit
4c966af52e
|
@ -26,6 +26,7 @@ int main()
|
|||
std::cout<<">> [par ] turn tokens into abstract syntax tree."<<std::endl;
|
||||
std::cout<<">> [ast ] check the abstract syntax tree."<<std::endl;
|
||||
std::cout<<">> [run ] run code."<<std::endl;
|
||||
std::cout<<">> [info ] print lexer,parser and ast on screen."<<std::endl;
|
||||
std::cout<<">> [exit ] quit nasal interpreter."<<std::endl;
|
||||
}
|
||||
else if(command=="cls")
|
||||
|
@ -117,6 +118,16 @@ int main()
|
|||
else
|
||||
std::cout<<">>[Lexer] error occurred,stop."<<std::endl;
|
||||
}
|
||||
else if(command=="info")
|
||||
{
|
||||
lexer.scanner(resource.get_source());
|
||||
lexer.print_token_list();
|
||||
lexer.generate_detail_token();
|
||||
parser.get_token_list(lexer.get_detail_token_list());
|
||||
parser.print_detail_token();
|
||||
parser.main_generate();
|
||||
parser.get_root().print_tree(1);
|
||||
}
|
||||
else if(command=="exit")
|
||||
break;
|
||||
else
|
||||
|
|
|
@ -159,7 +159,14 @@ enum parse_error_type
|
|||
lack_right_curve, // lack right curve
|
||||
parameter_lack_part, // parameter lack a ')' or identifier
|
||||
parameter_lack_curve, // parameter lack a ',' or ')'
|
||||
call_hash_lack_id, // lack identifier when calling an identifier
|
||||
|
||||
call_hash_lack_id, // lack identifier when calling a hash
|
||||
call_vector_lack_bracket, // lack ']' when calling a vector
|
||||
|
||||
vector_gen_lack_end, // lack ',' or ')' when generating a vector
|
||||
hash_gen_lack_id, // lack identifier or string when generating a hash
|
||||
hash_gen_lack_colon, // lack ':' when generating a hash
|
||||
hash_gen_lack_end, // lack ',' or '}' when generating a hash
|
||||
};
|
||||
|
||||
void print_parse_error(int error_type,int line,int error_token_type=__stack_end)
|
||||
|
@ -198,6 +205,31 @@ void print_parse_error(int error_type,int line,int error_token_type=__stack_end)
|
|||
std::cout<<error_info_head<<line<<": expect a \')\' or \',\' here."<<std::endl;break;
|
||||
case call_hash_lack_id:
|
||||
std::cout<<error_info_head<<line<<": expect an identifier after \'.\' ."<<std::endl;break;
|
||||
case call_vector_lack_bracket:
|
||||
std::cout<<error_info_head<<line<<": expect a \']\' here but get \'";
|
||||
print_parse_token(error_token_type);
|
||||
std::cout<<"\' ."<<std::endl;
|
||||
break;
|
||||
case vector_gen_lack_end:
|
||||
std::cout<<error_info_head<<line<<": expect a \',\' or \')\' here but get \'";
|
||||
print_parse_token(error_token_type);
|
||||
std::cout<<"\' ."<<std::endl;
|
||||
break;
|
||||
case hash_gen_lack_id:
|
||||
std::cout<<error_info_head<<line<<": expect an identifier or string here but get \'";
|
||||
print_parse_token(error_token_type);
|
||||
std::cout<<"\' ."<<std::endl;
|
||||
break;
|
||||
case hash_gen_lack_colon:
|
||||
std::cout<<error_info_head<<line<<": expect a \':\' here but get \'";
|
||||
print_parse_token(error_token_type);
|
||||
std::cout<<"\' ."<<std::endl;
|
||||
break;
|
||||
case hash_gen_lack_end:
|
||||
std::cout<<error_info_head<<line<<": expect a \',\' or \'}\' here but get \'";
|
||||
print_parse_token(error_token_type);
|
||||
std::cout<<"\' ."<<std::endl;
|
||||
break;
|
||||
default:
|
||||
std::cout<<error_info_head<<line<<": unknown parse error. error id: other_type."<<std::endl;break;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ class nasal_parse
|
|||
abstract_syntax_tree& get_root();
|
||||
|
||||
// abstract_syntax_tree generation
|
||||
bool check_comma_in_curve();
|
||||
void main_generate();
|
||||
abstract_syntax_tree calculation();
|
||||
abstract_syntax_tree and_calculation();
|
||||
|
@ -32,6 +33,8 @@ class nasal_parse
|
|||
abstract_syntax_tree function_generate();
|
||||
abstract_syntax_tree var_outside_definition();
|
||||
abstract_syntax_tree var_inside_definition();
|
||||
abstract_syntax_tree normal_assignment();
|
||||
abstract_syntax_tree in_curve_assignment();
|
||||
abstract_syntax_tree loop_expr();
|
||||
abstract_syntax_tree choose_expr();
|
||||
};
|
||||
|
@ -135,6 +138,25 @@ abstract_syntax_tree& nasal_parse::get_root()
|
|||
return root;
|
||||
}
|
||||
|
||||
bool nasal_parse::check_comma_in_curve()
|
||||
{
|
||||
bool ret=false;
|
||||
int cnt=0;
|
||||
while(this_token.type!=__right_curve)
|
||||
{
|
||||
++cnt;
|
||||
this->get_token();
|
||||
if(this_token.type==__comma)
|
||||
{
|
||||
ret=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(int i=0;i<cnt;++i)
|
||||
this->push_token();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void nasal_parse::main_generate()
|
||||
{
|
||||
error=0;
|
||||
|
@ -155,11 +177,38 @@ void nasal_parse::main_generate()
|
|||
break;
|
||||
case __nor_operator: case __sub_operator:
|
||||
case __number: case __nil: case __string: case __id:
|
||||
case __left_curve: case __left_bracket: case __left_brace:
|
||||
case __left_bracket: case __left_brace:
|
||||
case __func:
|
||||
this->push_token();
|
||||
root.add_children(calculation());
|
||||
break;
|
||||
case __left_curve:
|
||||
this->push_token();
|
||||
if(check_comma_in_curve())
|
||||
{
|
||||
this->get_token();// get '('
|
||||
this->get_token();// check if there is a 'var'
|
||||
if(this_token.type==__var)
|
||||
{
|
||||
this->push_token();
|
||||
this->push_token();
|
||||
root.add_children(var_inside_definition());
|
||||
}
|
||||
else
|
||||
{
|
||||
this->push_token();
|
||||
this->push_token();
|
||||
root.add_children(in_curve_assignment());
|
||||
}
|
||||
}
|
||||
else
|
||||
root.add_children(calculation());
|
||||
// '(' is the beginning of too many statements
|
||||
// '(' var id,id,id ')'
|
||||
// '(' calculation ')'
|
||||
// '(' scalar,scalar,scalar ')' '=' '(' scalar,scalar,scalar ')'
|
||||
// but these statements can be distinguished by commas in them
|
||||
break;
|
||||
case __if:
|
||||
this->push_token();
|
||||
root.add_children(choose_expr());
|
||||
|
@ -299,21 +348,10 @@ abstract_syntax_tree nasal_parse::scalar_generate()
|
|||
|
||||
switch(this_token.type)
|
||||
{
|
||||
case __number:
|
||||
scalar_node.set_node_type(__number);
|
||||
scalar_node.set_var_number(this_token.str);
|
||||
break;
|
||||
case __string:
|
||||
scalar_node.set_node_type(__string);
|
||||
scalar_node.set_var_string(this_token.str);
|
||||
break;
|
||||
case __nil:
|
||||
scalar_node.set_node_type(__nil);
|
||||
break;
|
||||
case __id:
|
||||
scalar_node.set_node_type(__id);
|
||||
scalar_node.set_var_name(this_token.str);
|
||||
break;
|
||||
case __number:scalar_node.set_node_type(__number);scalar_node.set_var_number(this_token.str);break;
|
||||
case __string:scalar_node.set_node_type(__string);scalar_node.set_var_string(this_token.str);break;
|
||||
case __nil:scalar_node.set_node_type(__nil);break;
|
||||
case __id:scalar_node.set_node_type(__id);scalar_node.set_var_name(this_token.str);break;
|
||||
case __left_curve:
|
||||
scalar_node=calculation();
|
||||
this->get_token();
|
||||
|
@ -359,7 +397,21 @@ abstract_syntax_tree nasal_parse::scalar_generate()
|
|||
}
|
||||
else if(this_token.type==__left_bracket)
|
||||
{
|
||||
|
||||
abstract_syntax_tree call_vector_node;
|
||||
call_vector_node.set_node_line(this_token.line);
|
||||
call_vector_node.set_node_type(__call_vector);
|
||||
// call_vector_node.add_children(calculation());
|
||||
// this->get_token();
|
||||
// if(this_token.type==__colon)
|
||||
// calculation();
|
||||
// else
|
||||
// this->push_token();
|
||||
this->get_token();
|
||||
if(this_token.type!=__right_bracket)
|
||||
{
|
||||
++error;
|
||||
print_parse_error(call_vector_lack_bracket,this_token.line,this_token.type);
|
||||
}
|
||||
}
|
||||
else if(this_token.type==__dot)
|
||||
{
|
||||
|
@ -370,11 +422,11 @@ abstract_syntax_tree nasal_parse::scalar_generate()
|
|||
print_parse_error(call_hash_lack_id,this_token.line);
|
||||
break;
|
||||
}
|
||||
abstract_syntax_tree identifier_node;
|
||||
identifier_node.set_node_line(this_token.line);
|
||||
identifier_node.set_node_type(__call_hash);
|
||||
identifier_node.set_var_name(this_token.str);
|
||||
scalar_node.add_children(identifier_node);
|
||||
abstract_syntax_tree call_hash_node;
|
||||
call_hash_node.set_node_line(this_token.line);
|
||||
call_hash_node.set_node_type(__call_hash);
|
||||
call_hash_node.set_var_name(this_token.str);
|
||||
scalar_node.add_children(call_hash_node);
|
||||
}
|
||||
this->get_token();
|
||||
}
|
||||
|
@ -388,6 +440,48 @@ abstract_syntax_tree nasal_parse::hash_generate()
|
|||
abstract_syntax_tree hash_node;
|
||||
hash_node.set_node_line(this_token.line);
|
||||
hash_node.set_node_type(__hash);
|
||||
this->get_token();
|
||||
if(this_token.type!=__right_brace)
|
||||
{
|
||||
this->push_token();
|
||||
while(this_token.type!=__right_brace)
|
||||
{
|
||||
abstract_syntax_tree hash_member_node;
|
||||
this->get_token();
|
||||
hash_member_node.set_node_line(this_token.line);
|
||||
hash_member_node.set_node_type(__hash_member);
|
||||
if(this_token.type==__id || this_token.type==__string)
|
||||
{
|
||||
abstract_syntax_tree member_id;
|
||||
member_id.set_node_line(this_token.line);
|
||||
member_id.set_node_type(__id);
|
||||
member_id.set_var_name(this_token.str);
|
||||
hash_member_node.add_children(member_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
++error;
|
||||
print_parse_error(hash_gen_lack_id,this_token.line,this_token.type);
|
||||
break;
|
||||
}
|
||||
this->get_token();
|
||||
if(this_token.type!=__colon)
|
||||
{
|
||||
++error;
|
||||
print_parse_error(hash_gen_lack_colon,this_token.line,this_token.type);
|
||||
break;
|
||||
}
|
||||
hash_member_node.add_children(calculation());
|
||||
this->get_token();
|
||||
if(this_token.type!=__comma && this_token.type!=__right_brace)
|
||||
{
|
||||
++error;
|
||||
print_parse_error(hash_gen_lack_end,this_token.line,this_token.type);
|
||||
break;
|
||||
}
|
||||
hash_node.add_children(hash_member_node);
|
||||
}
|
||||
}
|
||||
return hash_node;
|
||||
}
|
||||
|
||||
|
@ -397,6 +491,22 @@ abstract_syntax_tree nasal_parse::vector_generate()
|
|||
abstract_syntax_tree vector_node;
|
||||
vector_node.set_node_line(this_token.line);
|
||||
vector_node.set_node_type(__vector);
|
||||
this->get_token();
|
||||
if(this_token.type!=__right_bracket)
|
||||
{
|
||||
this->push_token();
|
||||
while(this_token.type!=__right_bracket)
|
||||
{
|
||||
vector_node.add_children(calculation());
|
||||
this->get_token();
|
||||
if(this_token.type!=__comma && this_token.type!=__right_bracket)
|
||||
{
|
||||
++error;
|
||||
print_parse_error(vector_gen_lack_end,this_token.line,this_token.type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return vector_node;
|
||||
}
|
||||
|
||||
|
@ -558,6 +668,22 @@ abstract_syntax_tree nasal_parse::var_inside_definition()
|
|||
return var_inside_definition_node;
|
||||
}
|
||||
|
||||
abstract_syntax_tree nasal_parse::normal_assignment()
|
||||
{
|
||||
abstract_syntax_tree assign_node;
|
||||
assign_node.set_node_type(__assignment);
|
||||
return assign_node;
|
||||
}
|
||||
|
||||
abstract_syntax_tree nasal_parse::in_curve_assignment()
|
||||
{
|
||||
abstract_syntax_tree assign_node;
|
||||
this->get_token(); // get '('
|
||||
assign_node.set_node_line(this_token.line);
|
||||
assign_node.set_node_type(__assignment);
|
||||
return assign_node;
|
||||
}
|
||||
|
||||
abstract_syntax_tree nasal_parse::loop_expr()
|
||||
{
|
||||
abstract_syntax_tree loop_main_node;
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
| '(' <calculation> ')'
|
||||
| <scalar> { ('[' {<calculation> ','} ']') | ('[' <calculation> ':' [<calculation>] ']') | ('.' <id>) | ('(' {<calculation> ','} ')') | ('(' {<id> ':' <calculation> ','} ')') }
|
||||
;
|
||||
0
|
||||
|
||||
<function> =
|
||||
<func> ['(' ')'] <statement>
|
||||
| <func> ['(' ')'] '{' {<statement> ';'} '}'
|
||||
|
@ -56,14 +56,14 @@
|
|||
| '(' <var> {(<id>) | (<call_identifier>) ','} ')' '=' (<scalar> | '(' {<scalar> ','} ')')
|
||||
;
|
||||
<forindex_loop_definition> =
|
||||
|
||||
<var> <id>
|
||||
;
|
||||
<foreach_loop_definition> =
|
||||
<var> <id>
|
||||
;
|
||||
<assignment> =
|
||||
<call_identifier> '=' <scalar>
|
||||
| '(' {<call_identifier> ','} ')' '=' (<scalar> | '(' {<scalar> ','} ')')
|
||||
<scalar> '=' <calculation>
|
||||
| '(' {<scalar> ','} ')' '=' (<calculation> | '(' {<calculation> ','} ')')
|
||||
;
|
||||
<loop_expr> =
|
||||
<for_loop>
|
||||
|
@ -72,12 +72,12 @@
|
|||
| <foreach_loop>
|
||||
;
|
||||
<for_loop> =
|
||||
<for> '(' [<statement>] ';' [<scalar>] ';' <statement> ')' <statement> [';']
|
||||
| <for> '(' [<statement>] ';' [<scalar>] ';' <statement> ')' '{' {<statement> ';'} '}'
|
||||
<for> '(' [<statement>] ';' [<calculation>] ';' [<statement>] ')' <statement> [';']
|
||||
| <for> '(' [<statement>] ';' [<calculation>] ';' [<statement>] ')' '{' {<statement> ';'} '}'
|
||||
;
|
||||
<while_loop> =
|
||||
<while> '(' <scalar> ')' <statement> [';']
|
||||
| <while> '(' <scalar> ')' '{' {<statement> ';'} '}'
|
||||
<while> '(' <calculation> ')' <statement> [';']
|
||||
| <while> '(' <calculation> ')' '{' {<statement> ';'} '}'
|
||||
;
|
||||
(* in forindex and foreach the scalar and definition cannot be lacked*)
|
||||
<forindex_loop> =
|
||||
|
@ -92,14 +92,14 @@
|
|||
<choose_expr> = <choose_expr_if> {<choose_expr_elsif>} [<choose_expr_else>]
|
||||
;
|
||||
<choose_expr_if> =
|
||||
<if> '(' <scalar> ')' <statement> [';']
|
||||
| <if> '(' <scalar> ')' '{' {<statement> ';'} '}'
|
||||
<if> '(' <calculation> ')' <statement> [';']
|
||||
| <if> '(' <calculation> ')' '{' {<statement> ';'} '}'
|
||||
;
|
||||
<choose_expr_elsif> =
|
||||
<elsif> '(' <scalar> ')' <statement> [';']
|
||||
| <elsif> '(' <scalar> ')' '{' {<statement> ';'} '}'
|
||||
| <else> <if> '(' <scalar> ')' <statement> [';']
|
||||
| <else> <if> '(' <scalar> ')' '{' {<statement> ';'} '}'
|
||||
<elsif> '(' <calculation> ')' <statement> [';']
|
||||
| <elsif> '(' <calculation> ')' '{' {<statement> ';'} '}'
|
||||
| <else> <if> '(' <calculation> ')' <statement> [';']
|
||||
| <else> <if> '(' <calculation> ')' '{' {<statement> ';'} '}'
|
||||
;
|
||||
<choose_expr_else> =
|
||||
<else> <statement> [';']
|
||||
|
|
|
@ -11,9 +11,10 @@ nil;
|
|||
-((30));
|
||||
[];
|
||||
{};
|
||||
[0,1,2,3,4,5][2]; # 2
|
||||
{str:"hello"}.str; # "hello"
|
||||
{str:"hello"}["str"]; # "hello"
|
||||
[0,1,2,3,4,5][2]; # 2
|
||||
{str:"hello"}.str; # "hello"
|
||||
{str:"hello"}["str"]; # "hello"
|
||||
{"str":"hello"}["str"]; # "hello"
|
||||
|
||||
# normal scalar
|
||||
var number_1=1;
|
||||
|
|
Loading…
Reference in New Issue