From 4220e5bc5d3fc82d8ab98c0fcd903f5da3ccd87f Mon Sep 17 00:00:00 2001 From: Valk Richard Li <48872266+ValKmjolnir@users.noreply.github.com> Date: Mon, 17 Feb 2020 17:16:36 +0800 Subject: [PATCH] update --- version2.0/nasal_ast.h | 342 ++++++++++++++++++++++++++++++++++++- version2.0/nasal_enum.h | 70 ++++---- version2.0/nasal_parse.h | 27 ++- version2.0/nasal_runtime.h | 1 - 4 files changed, 397 insertions(+), 43 deletions(-) diff --git a/version2.0/nasal_ast.h b/version2.0/nasal_ast.h index 64b2658..c06ff50 100644 --- a/version2.0/nasal_ast.h +++ b/version2.0/nasal_ast.h @@ -220,4 +220,344 @@ void abstract_syntax_tree::merge_children(abstract_syntax_tree& tmp) return; } -#endif \ No newline at end of file +#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 +*/ \ No newline at end of file diff --git a/version2.0/nasal_enum.h b/version2.0/nasal_enum.h index 5f8e909..16fe10a 100644 --- a/version2.0/nasal_enum.h +++ b/version2.0/nasal_enum.h @@ -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<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(); diff --git a/version2.0/nasal_runtime.h b/version2.0/nasal_runtime.h index 5e7505b..b29ef89 100644 --- a/version2.0/nasal_runtime.h +++ b/version2.0/nasal_runtime.h @@ -28,7 +28,6 @@ class nasal_runtime // init global.set_clear(); nasal_gc.gc_init(); - return; } };