This commit is contained in:
Valk Richard Li 2020-02-17 17:16:36 +08:00 committed by GitHub
parent e9e5e1a3fc
commit 4220e5bc5d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 397 additions and 43 deletions

View File

@ -220,4 +220,344 @@ void abstract_syntax_tree::merge_children(abstract_syntax_tree& tmp)
return;
}
#endif
#endif
/*
examples of each type of sub-tree
ast begins in root node:
root
statement_1
statement_2
...
source code:
0xdeadbeef;
'str';
"str";
ast:
root
num: 3.73593e+009
str: str
str: str
source code:
1+2*(1-3)/4~'str';
ast:
root
~
+
num: 1
/
*
num: 2
-
num: 1
num: 3
num:4
str: str
source code:
var id=1;
ast:
root
definition
id: id
num: 1
source code:
var (id1,id2,id3)=(1,2,3);
(var id1,id2,id3)=(1,2,3);
ast:
root
definition
identifiers
id: id1
id: id2
id: id3
scalars
num: 1
num: 2
num: 3
source code:
var (id1,id2,id3)=[1,2,3];
(var id1,id2,id3)=[1,2,3];
ast:
root
definition
identifiers
id: id1
id: id2
id: id3
vector
num: 1
num: 2
num: 3
source code:
(id1,id2,id3)=(1,2,3);
ast:
root
=
scalars
id: id1
id: id2
id: id3
scalars
num: 1
num: 2
num: 3
source code:
(id1[0],id2,id3)=[1,2,3];
ast:
root
=
scalars
id: id1
call_vector
num: 0
id: id2
id: id3
vector
num: 1
num: 2
num: 3
source code:
id.call_hs(call_f)[call_vec][subvec1:subvec2,subvec3];
ast:
root
id: id
call_hash: call_hs
call_function
id: call_f
call_vector
id: call_vec
call_vector
sub_vector
id: subvec1
id: subvec2
id: subvec3
source code:
id.id.id.id.id.id.id.id;
ast:
root
id: id
call_hash: id
call_hash: id
call_hash: id
call_hash: id
call_hash: id
call_hash: id
call_hash: id
source code:
function(a,b,c,d,e);
function(func a);
function(func a());
ast:
root
id: function
call_function
id: a
id: b
id: c
id: d
id: e
id: function
call_function
id: a
id: function
call_function
id: a
call_function
source code:
function(
a,
b,
func{print("hello");}
);
ast:
id: function
call_function
id: a
id: b
function
parameters
block
id: print
call_function
str: hello
source code:
function(a:1,b:2,c:3,);
ast:
root
id: function
call_function
special_parameter
id: a
num: 1
special_parameter
id: b
num: 2
special_parameter
id: c
num: 3
source code:
while(id)
{
fun();
var a=1;
var b=2;
}
ast:
root
while
id: id
block
id: func
call_function
definition
id: 1
num: 1
definition
id: b
num: 2
source code:
for(;;){}
ast:
root
for
null_type
null_type
null_type
block
source code:
for(var i=1;i<100;i+=1){}
ast:
root
for
definition
id: i
num: 1
<
id: i
num: 100
+=
id: i
num: 1
block
source code:
foreach(var i;[0,1,2]){}
forindex(var i;[0,1,2]){}
ast:
root
foreach
id: i
vector
num: 0
num: 1
num: 2
block
forindex
id: i
vector
num: 0
num: 1
num: 2
block
source code:
if(condition_1)
{
}
else if(condition_2)
{
}
else
{
}
ast:
root
conditional
if
id: condition_1
block
else
block
if
id: condition_2
block
else
block
source code:
if(condition_1)
{
}
elsif(condition_2)
{
}
elsif(condition_3)
{
}
ast:
root
conditional
if
id: condition_1
block
elsif
id: condition_2
block
elsif
id: condition_3
block
source code:
var function=func{};
ast:
root
definition
id: function
function
parameters
block
source code:
var function=func(x,y,dyn...){};
ast:
root
definition
id: function
function
parameters
id: x
id: y
id...: dyn
block
source code:
var function=func(x=2,y=1){};
ast:
root
definition
id: function
function
parameters
default_parameter
id: x
num: 2
default_parameter
id: y
num: 1
block
*/

View File

@ -26,6 +26,8 @@ void print_lexer_token(int type)
enum parse_gen_type
{
__stack_end=1,
// operators
__cmp_equal,__cmp_not_equal,__cmp_less,__cmp_less_or_equal,__cmp_more,__cmp_more_or_equal,
// == != < <= > >=
__and_operator,__or_operator,__nor_operator,__add_operator,__sub_operator,__mul_operator,__div_operator,__link_operator,
@ -35,33 +37,30 @@ enum parse_gen_type
__left_brace,__right_brace, // {}
__left_bracket,__right_bracket, // []
__left_curve,__right_curve, // ()
__semi,__comma,__colon,__dot,__ques_mark, // ; , : . ?
__semi,__comma,__colon,__dot,__ques_mark, // ; , : . ?
__unknown_operator,
// operators
// reserve words
__var,__func,__return,__nil,
__if,__elsif,__else,
__continue,__break,
__for,__forindex,__foreach,__while,
// reserve words
__number,__string,__id,__dynamic_id,
// basic scalar type: number string identifier dynamic_identifier
__number,__string,__id,__dynamic_id,
// abstract_syntax_tree type below
// abstract_syntax_tree also uses the types above, such as operators
__root,
__null_type,
__multi_id,
__multi_scalar,
__parameters,
__special_para,
__defult_parameter,
__vector,__hash,
__hash_member,
__sub_vector,
__call_function,__call_vector,__call_hash,
__multi_id,__multi_scalar,
__parameters,__special_parameter,__default_parameter,
__vector,__sub_vector,__call_vector,
__hash,__hash_member,__call_hash,
__function,__call_function,
__normal_statement_block,
__definition,
__function,__conditional
__conditional
};
void print_parse_token(int type)
{
@ -180,26 +179,26 @@ void print_ast_type(int type)
case __number: context="num"; break;
case __string: context="str"; break;
case __root: context="root"; break;
case __null_type: context="null_type"; break;
case __multi_id: context="ids"; break;
case __multi_scalar: context="scalars"; break;
case __parameters: context="paras"; break;
case __special_para: context="id:scalar"; break;
case __defult_parameter: context="para=scalar"; break;
case __vector: context="vector"; break;
case __hash: context="hash"; break;
case __hash_member: context="hash_member"; break;
case __sub_vector: context="num:num"; break;
case __call_function: context="call_func"; break;
case __call_vector: context="call_vector"; break;
case __call_hash: context="call_hash"; break;
case __normal_statement_block:context="block"; break;
case __definition: context="def"; break;
case __function: context="function"; break;
case __conditional: context="conditional"; break;
case __root: context="root"; break; // root of the ast that parser generates
case __null_type: context="null_type"; break; // type of the node of the tree is unknown
case __multi_id: context="identifiers"; break; // id,id,id,id |often used in multi-definition or multi-assignment
case __multi_scalar: context="scalars"; break; // scalar,scalar,scalar,scalar|often used in multi-definition or multi-assignment
case __parameters: context="parameters"; break; // parameter list
case __special_parameter: context="special_parameter"; break; // identifier:scalar |special way of calling a function
case __default_parameter: context="default_parameter"; break; // identifier=scalar |default parameter when generating a new function
case __vector: context="vector"; break; // vector
case __sub_vector: context="sub_vector"; break; // the same as subvec() but more flexible to use
case __call_vector: context="call_vector"; break; // call vector member
case __hash: context="hash"; break; // hash
case __hash_member: context="hash_member"; break; // hash member
case __call_hash: context="call_hash"; break; // call hash member
case __function: context="function"; break; // function
case __call_function: context="call_function"; break; // call function
case __normal_statement_block:context="block"; break; // block
case __definition: context="definition"; break; // definition
case __conditional: context="conditional"; break; // if-else
default: context="undefined"; break;
default: context="undefined"; break;
}
std::cout<<context;
return;
@ -227,12 +226,13 @@ enum parse_error_type
error_begin_token_of_scalar, // in scalar_generate()
default_dynamic_parameter, // default parameter should not be dynamic
parameter_lack_part, // parameter lack a ')' or identifier
parameter_lack_curve, // parameter lack a ',' or ')'
special_call_func_lack_id,
special_call_func_lack_colon,
call_func_lack_comma,
call_func_lack_comma, // lack comma when giving parameters to a function
call_hash_lack_id, // lack identifier when calling a hash
call_vector_wrong_comma, // wrong use of comma like this: id[0,4:6,7,] (the last comma is incorrect here)
call_vector_lack_bracket, // lack ']' when calling a vector
@ -308,6 +308,8 @@ void print_parse_error(int error_type,int line,int error_token_type=__stack_end)
std::cout<<"\' ."<<std::endl;
break;
case default_dynamic_parameter:
std::cout<<error_info_head<<line<<": dynamic parameter should not have a default value."<<std::endl;break;
case parameter_lack_part:
std::cout<<error_info_head<<line<<": expect a \')\' or identifier here when generating parameter_list."<<std::endl;break;
case parameter_lack_curve:

View File

@ -577,7 +577,10 @@ abstract_syntax_tree nasal_parse::multi_scalar_assignment()
}
this->get_token();
if(this_token.type!=__left_curve)
{
this->push_token();
back_multi_scalar_node=scalar_generate();
}
else
{
this->push_token();
@ -901,7 +904,7 @@ abstract_syntax_tree nasal_parse::scalar_generate()
abstract_syntax_tree id_node;
this->get_token();
special_para_node.set_node_line(this_token.line);
special_para_node.set_node_type(__special_para);
special_para_node.set_node_type(__special_parameter);
if(this_token.type!=__id)
{
++error;
@ -1156,6 +1159,7 @@ abstract_syntax_tree nasal_parse::function_generate()
// check identifier
abstract_syntax_tree parameter;
this->get_token();
int parameter_type=this_token.type;
if(this_token.type==__id)
{
parameter.set_node_line(this_token.line);
@ -1184,12 +1188,21 @@ abstract_syntax_tree nasal_parse::function_generate()
this->get_token();
if(this_token.type==__equal)
{
abstract_syntax_tree default_parameter;
default_parameter.set_node_line(this_token.line);
default_parameter.set_node_type(__defult_parameter);
default_parameter.add_children(parameter);
default_parameter.add_children(calculation());
parameter=default_parameter;
if(parameter_type==__id)
{
abstract_syntax_tree default_parameter;
default_parameter.set_node_line(this_token.line);
default_parameter.set_node_type(__default_parameter);
default_parameter.add_children(parameter);
default_parameter.add_children(calculation());
parameter=default_parameter;
}
else
{
++error;
print_parse_error(default_dynamic_parameter,this_token.line,this_token.type);
break;
}
}
else
this->push_token();

View File

@ -28,7 +28,6 @@ class nasal_runtime
// init
global.set_clear();
nasal_gc.gc_init();
return;
}
};