update
This commit is contained in:
parent
8affe84f43
commit
82f8e83dfe
|
@ -45,6 +45,7 @@ void par_func()
|
||||||
if(!lexer.get_error())
|
if(!lexer.get_error())
|
||||||
{
|
{
|
||||||
parse.set_toklist(lexer.get_token_list());
|
parse.set_toklist(lexer.get_token_list());
|
||||||
|
parse.main_process();
|
||||||
if(parse.get_error()) std::cout<<">> [parse] error occurred,stop.\n";
|
if(parse.get_error()) std::cout<<">> [parse] error occurred,stop.\n";
|
||||||
}
|
}
|
||||||
else std::cout<<">> [lexer] error occurred,stop.\n";
|
else std::cout<<">> [lexer] error occurred,stop.\n";
|
||||||
|
|
|
@ -26,16 +26,19 @@ argument_list::=
|
||||||
'(' [{id ','} ([id '...']|{id '=' calculation ','})] ')'
|
'(' [{id ','} ([id '...']|{id '=' calculation ','})] ')'
|
||||||
;
|
;
|
||||||
expressions::=
|
expressions::=
|
||||||
'{' {definition|assignment|calculation|loop|conditional} '}'
|
'{' {definition|assignment|calculation|loop|conditional|return_expr|continue_expr|break_expr} '}'
|
||||||
|definition ';'
|
|definition ';'
|
||||||
|multi_assignment ';'
|
|multi_assignment ';'
|
||||||
|calculation ';'
|
|calculation ';'
|
||||||
|loop
|
|loop
|
||||||
|conditional
|
|conditional
|
||||||
|
|return_expr
|
||||||
|
|continue_expr
|
||||||
|
|break_expr
|
||||||
;
|
;
|
||||||
calculation::=
|
calculation::=
|
||||||
'(' calculation ')'
|
'(' calculation ')'
|
||||||
|scalar_gen
|
|scalar
|
||||||
|trinocular
|
|trinocular
|
||||||
|and_expr
|
|and_expr
|
||||||
|calculation ('=' | '+=' | '-=' | '*=' | '/=' | '~=') calculation
|
|calculation ('=' | '+=' | '-=' | '*=' | '/=' | '~=') calculation
|
||||||
|
@ -61,7 +64,7 @@ multive_expr::=
|
||||||
unary::=
|
unary::=
|
||||||
('-'|'!') calculation
|
('-'|'!') calculation
|
||||||
;
|
;
|
||||||
scalar_gen::=
|
scalar::=
|
||||||
function_call
|
function_call
|
||||||
|identifier_call
|
|identifier_call
|
||||||
|vector_call
|
|vector_call
|
||||||
|
@ -116,3 +119,12 @@ conditional::=
|
||||||
{elsif '(' calculation ')' expressions}
|
{elsif '(' calculation ')' expressions}
|
||||||
[else expressions]
|
[else expressions]
|
||||||
;
|
;
|
||||||
|
continue_expr::=
|
||||||
|
continue
|
||||||
|
;
|
||||||
|
break_expr::=
|
||||||
|
break
|
||||||
|
;
|
||||||
|
return_expr::=
|
||||||
|
return [calculation]
|
||||||
|
;
|
|
@ -12,6 +12,7 @@ public:
|
||||||
nasal_ast();
|
nasal_ast();
|
||||||
nasal_ast(const nasal_ast&);
|
nasal_ast(const nasal_ast&);
|
||||||
~nasal_ast();
|
~nasal_ast();
|
||||||
|
nasal_ast& operator=(const nasal_ast&);
|
||||||
void clear();
|
void clear();
|
||||||
void set_line(int);
|
void set_line(int);
|
||||||
void set_type(int);
|
void set_type(int);
|
||||||
|
@ -47,6 +48,15 @@ nasal_ast::~nasal_ast()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nasal_ast& nasal_ast::operator=(const nasal_ast& tmp)
|
||||||
|
{
|
||||||
|
this->line=tmp.line;
|
||||||
|
this->type=tmp.type;
|
||||||
|
this->str=tmp.str;
|
||||||
|
this->children=tmp.children;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
void nasal_ast::clear()
|
void nasal_ast::clear()
|
||||||
{
|
{
|
||||||
this->line=0;
|
this->line=0;
|
||||||
|
|
|
@ -20,21 +20,24 @@ enum token_type
|
||||||
|
|
||||||
enum ast_node
|
enum ast_node
|
||||||
{
|
{
|
||||||
ast_null=0,
|
ast_null=0,ast_root,ast_block,
|
||||||
ast_nil,ast_number,ast_string,ast_identifier,ast_function,ast_hash,ast_vector,
|
ast_nil,ast_number,ast_string,ast_identifier,ast_function,ast_hash,ast_vector,
|
||||||
ast_hashmember,
|
ast_hashmember,
|
||||||
ast_args,
|
ast_args,
|
||||||
ast_for,ast_forindex,ast_foreach,ast_while,
|
ast_for,ast_forindex,ast_foreach,ast_while,
|
||||||
ast_definition,ast_assignment,ast_calculation
|
ast_definition,ast_assignment,ast_calculation,
|
||||||
|
ast_continue,ast_break,ast_return,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum parse_error
|
enum parse_error
|
||||||
{
|
{
|
||||||
unknown,
|
unknown,
|
||||||
|
error_token,
|
||||||
lack_id,
|
lack_id,
|
||||||
lack_left_curve,
|
lack_left_curve,
|
||||||
lack_left_bracket,
|
lack_left_bracket,
|
||||||
lack_left_brace,
|
lack_left_brace,
|
||||||
|
lack_semi,
|
||||||
lack_comma,
|
lack_comma,
|
||||||
lack_colon,
|
lack_colon,
|
||||||
lack_scalar,
|
lack_scalar,
|
||||||
|
@ -47,14 +50,16 @@ void error_info(int line,int error_type)
|
||||||
std::cout<<info<<line<<": ";
|
std::cout<<info<<line<<": ";
|
||||||
switch(error_type)
|
switch(error_type)
|
||||||
{
|
{
|
||||||
case unknown: detail="unknown error."; break;
|
case unknown: detail="unknown error."; break;
|
||||||
case lack_id: detail="lack identifier."; break;
|
case error_token: detail="this token should not exist here."; break;
|
||||||
case lack_left_curve: detail="lack left curve."; break;
|
case lack_id: detail="lack identifier."; break;
|
||||||
case lack_left_bracket: detail="lack left bracket."; break;
|
case lack_left_curve: detail="lack left curve."; break;
|
||||||
case lack_left_brace: detail="lack left brace."; break;
|
case lack_left_bracket: detail="lack left bracket."; break;
|
||||||
case lack_comma: detail="lack comma."; break;
|
case lack_left_brace: detail="lack left brace."; break;
|
||||||
case lack_colon: detail="lack colon."; break;
|
case lack_semi: detail="lack \';\' here."; break;
|
||||||
case lack_scalar: detail="lack scalar"; break;
|
case lack_comma: detail="lack comma."; break;
|
||||||
|
case lack_colon: detail="lack colon."; break;
|
||||||
|
case lack_scalar: detail="lack scalar"; break;
|
||||||
}
|
}
|
||||||
std::cout<<detail<<std::endl;
|
std::cout<<detail<<std::endl;
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -41,6 +41,9 @@ private:
|
||||||
nasal_ast multi_assgin();
|
nasal_ast multi_assgin();
|
||||||
nasal_ast loop();
|
nasal_ast loop();
|
||||||
nasal_ast conditional();
|
nasal_ast conditional();
|
||||||
|
nasal_ast continue_expr();
|
||||||
|
nasal_ast break_expr();
|
||||||
|
nasal_ast return_expr();
|
||||||
public:
|
public:
|
||||||
int get_error();
|
int get_error();
|
||||||
void clear();
|
void clear();
|
||||||
|
@ -73,11 +76,35 @@ void nasal_parse::set_toklist(std::vector<token>& lex_token)
|
||||||
void nasal_parse::main_process()
|
void nasal_parse::main_process()
|
||||||
{
|
{
|
||||||
this->reset();
|
this->reset();
|
||||||
|
root.set_line(1);
|
||||||
|
root.set_type(ast_root);
|
||||||
while(ptr<tok_list_size)
|
while(ptr<tok_list_size)
|
||||||
{
|
{
|
||||||
if(tok_list[ptr].type);
|
switch(tok_list[ptr].type)
|
||||||
|
{
|
||||||
|
case tok_nil:case tok_number:case tok_string:case tok_identifier:
|
||||||
|
case tok_func:
|
||||||
|
case tok_left_bracket:case tok_left_brace:
|
||||||
|
case tok_sub:
|
||||||
|
case tok_not: root.add_child(calculation()); break;
|
||||||
|
case tok_var: root.add_child(definition()); break;
|
||||||
|
case tok_for:case tok_forindex:case tok_foreach:
|
||||||
|
case tok_while: root.add_child(loop()); break;
|
||||||
|
case tok_if: root.add_child(conditional()); break;
|
||||||
|
defaut: error_info(tok_list[ptr].line,error_token);++error;break;
|
||||||
|
}
|
||||||
++ptr;
|
++ptr;
|
||||||
|
if(ptr<tok_list_size && tok_list[ptr].type==tok_semi)
|
||||||
|
++ptr;
|
||||||
|
else if(ptr<tok_list_size && tok_list[ptr].type!=tok_semi
|
||||||
|
&& !root.get_children().empty() && !root.get_children().back().get_children().empty()
|
||||||
|
&& root.get_children().back().get_children().back().get_type()!=ast_function)
|
||||||
|
{
|
||||||
|
error_info(root.get_children().back().get_children().back().get_line(),lack_semi);
|
||||||
|
++error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
std::cout<<">> [parse] complete generation. "<<error<<" error(s)."<<std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,6 +166,7 @@ nasal_ast nasal_parse::vector_gen()
|
||||||
if(ptr<tok_list_size && tok_list[ptr].type!=tok_comma && tok_list[ptr].type!=tok_right_bracket)
|
if(ptr<tok_list_size && tok_list[ptr].type!=tok_comma && tok_list[ptr].type!=tok_right_bracket)
|
||||||
{
|
{
|
||||||
error_info(tok_list[ptr].line,lack_comma);
|
error_info(tok_list[ptr].line,lack_comma);
|
||||||
|
++error;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,6 +187,7 @@ nasal_ast nasal_parse::hash_gen()
|
||||||
if(ptr<tok_list_size && tok_list[ptr].type!=tok_comma && tok_list[ptr].type!=tok_right_brace)
|
if(ptr<tok_list_size && tok_list[ptr].type!=tok_comma && tok_list[ptr].type!=tok_right_brace)
|
||||||
{
|
{
|
||||||
error_info(tok_list[ptr].line,lack_comma);
|
error_info(tok_list[ptr].line,lack_comma);
|
||||||
|
++error;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -179,11 +208,16 @@ nasal_ast nasal_parse::hash_member_gen()
|
||||||
if(ptr>=tok_list_size || tok_list[ptr].type!=tok_colon)
|
if(ptr>=tok_list_size || tok_list[ptr].type!=tok_colon)
|
||||||
{
|
{
|
||||||
error_info(ptr>=tok_list_size?node.get_line():tok_list[ptr].line,lack_colon);
|
error_info(ptr>=tok_list_size?node.get_line():tok_list[ptr].line,lack_colon);
|
||||||
|
++error;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
++ptr;
|
++ptr;
|
||||||
if(ptr<tok_list_size) node.add_child(calculation());
|
if(ptr<tok_list_size) node.add_child(calculation());
|
||||||
else error_info(node.get_line(),lack_scalar);
|
else
|
||||||
|
{
|
||||||
|
error_info(node.get_line(),lack_scalar);
|
||||||
|
++error;
|
||||||
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
nasal_ast nasal_parse::func_gen()
|
nasal_ast nasal_parse::func_gen()
|
||||||
|
@ -195,16 +229,19 @@ nasal_ast nasal_parse::func_gen()
|
||||||
if(ptr>=tok_list_size)
|
if(ptr>=tok_list_size)
|
||||||
{
|
{
|
||||||
error_info(node.get_line(),lack_left_curve);
|
error_info(node.get_line(),lack_left_curve);
|
||||||
|
++error;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
if(tok_list[ptr].type==tok_left_curve)
|
if(tok_list[ptr].type==tok_left_curve)
|
||||||
{
|
{
|
||||||
node.add_child(args_list_gen());
|
node.add_child(args_list_gen());
|
||||||
|
++error;
|
||||||
++ptr;
|
++ptr;
|
||||||
}
|
}
|
||||||
if(ptr>=tok_list_size)
|
if(ptr>=tok_list_size)
|
||||||
{
|
{
|
||||||
error_info(node.get_line(),lack_left_brace);
|
error_info(node.get_line(),lack_left_brace);
|
||||||
|
++error;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
node.add_child(exprs_gen());
|
node.add_child(exprs_gen());
|
||||||
|
@ -225,11 +262,43 @@ nasal_ast nasal_parse::args_list_gen()
|
||||||
nasal_ast nasal_parse::exprs_gen()
|
nasal_ast nasal_parse::exprs_gen()
|
||||||
{
|
{
|
||||||
nasal_ast node;
|
nasal_ast node;
|
||||||
|
node.set_line(tok_list[ptr].line);
|
||||||
|
node.set_type(ast_block);
|
||||||
|
while(ptr<tok_list_size)
|
||||||
|
{
|
||||||
|
switch(tok_list[ptr].type)
|
||||||
|
{
|
||||||
|
case tok_nil:case tok_number:case tok_string:case tok_identifier:
|
||||||
|
case tok_func:
|
||||||
|
case tok_left_bracket:case tok_left_brace:
|
||||||
|
case tok_sub:
|
||||||
|
case tok_not: node.add_child(calculation()); break;
|
||||||
|
case tok_var: node.add_child(definition()); break;
|
||||||
|
case tok_for:case tok_forindex:case tok_foreach:
|
||||||
|
case tok_while: node.add_child(loop()); break;
|
||||||
|
case tok_if: node.add_child(conditional()); break;
|
||||||
|
case tok_continue:break;
|
||||||
|
case tok_break:break;
|
||||||
|
case tok_return:break;
|
||||||
|
defaut: error_info(tok_list[ptr].line,error_token);++error;break;
|
||||||
|
}
|
||||||
|
++ptr;
|
||||||
|
if(ptr<tok_list_size && tok_list[ptr].type==tok_semi)
|
||||||
|
++ptr;
|
||||||
|
else if(ptr<tok_list_size && tok_list[ptr].type!=tok_semi
|
||||||
|
&& !node.get_children().empty() && !node.get_children().back().get_children().empty()
|
||||||
|
&& node.get_children().back().get_children().back().get_type()!=ast_function)
|
||||||
|
{
|
||||||
|
error_info(node.get_children().back().get_children().back().get_line(),lack_semi);
|
||||||
|
++error;
|
||||||
|
}
|
||||||
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
nasal_ast nasal_parse::calculation()
|
nasal_ast nasal_parse::calculation()
|
||||||
{
|
{
|
||||||
nasal_ast node;
|
nasal_ast node;
|
||||||
|
node.set_line(tok_list[ptr].line);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
nasal_ast nasal_parse::trinocular()
|
nasal_ast nasal_parse::trinocular()
|
||||||
|
@ -332,5 +401,33 @@ nasal_ast nasal_parse::conditional()
|
||||||
nasal_ast node;
|
nasal_ast node;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
nasal_ast nasal_parse::continue_expr()
|
||||||
|
{
|
||||||
|
nasal_ast node;
|
||||||
|
node.set_line(tok_list[ptr].line);
|
||||||
|
node.set_type(ast_continue);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
nasal_ast nasal_parse::break_expr()
|
||||||
|
{
|
||||||
|
nasal_ast node;
|
||||||
|
node.set_line(tok_list[ptr].line);
|
||||||
|
node.set_type(ast_break);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
nasal_ast nasal_parse::return_expr()
|
||||||
|
{
|
||||||
|
nasal_ast node;
|
||||||
|
node.set_line(tok_list[ptr].line);
|
||||||
|
node.set_type(ast_return);
|
||||||
|
++ptr;
|
||||||
|
if(ptr<tok_list_size)
|
||||||
|
{
|
||||||
|
int type=tok_list[ptr].type;
|
||||||
|
if(type==tok_nil || type==tok_number || type==tok_string || type==tok_identifier || type==tok_func ||
|
||||||
|
type==tok_sub || type==tok_not || type==tok_left_curve || type==tok_left_bracket || type==tok_left_brace)
|
||||||
|
node.add_child(calculation());
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
Loading…
Reference in New Issue