This commit is contained in:
Valk Richard Li 2020-06-10 02:07:36 -07:00 committed by GitHub
parent 8affe84f43
commit 82f8e83dfe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 141 additions and 16 deletions

View File

@ -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";

View File

@ -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]
;

View File

@ -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;

View File

@ -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;

View File

@ -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