This commit is contained in:
Valk Richard Li 2020-06-14 02:41:45 -07:00 committed by GitHub
parent 6fcd3ecdc0
commit 7f73a2f5ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 222 additions and 51 deletions

View File

@ -31,6 +31,15 @@ void logo()
return;
}
void del_func()
{
resource.clear();
lexer.clear();
parse.clear();
std::cout<<">> [Delete] complete."<<std::endl;
return;
}
void lex_func()
{
lexer.scanner(resource.get_file());
@ -92,12 +101,7 @@ int main()
#endif
}
else if(command=="del")
{
resource.delete_file();
lexer.delete_tokens();
parse.clear();
std::cout<<">> [Delete] complete."<<std::endl;
}
del_func();
else if(command=="lib")
resource.load_lib();
else if(command=="rs")

View File

@ -39,20 +39,19 @@ expressions::=
'{' {expr} '}'
;
calculation::=
'(' calculation ')'
|scalar
|trinocular
|and_expr
|or_expr
|calculation ('=' | '+=' | '-=' | '*=' | '/=' | '~=') calculation
;
trinocular::=
calculation '?' calculation ':' calculation
;
and_expr::=
or_expr and or_expr
;
or_expr::=
cmp_expr or cmp_expr
and_expr or and_expr
;
and_expr::=
cmp_expr and cmp_expr
;
cmp_expr::=
additive_expr ('==' | '!=' | '>' | '<' | '>=' | '<=') additive_expr
@ -61,10 +60,10 @@ additive_expr::=
multive_expr ('+' | '-' | '~') multive_expr
;
multive_expr::=
unary ('*' | '/') unary
(unary|scalar) ('*' | '/') (unary|scalar)
;
unary::=
('-'|'!') calculation
('-'|'!') scalar
;
scalar::=
function_call
@ -73,6 +72,7 @@ scalar::=
|hash_call
|number
|string
|'(' calculation ')'
;
function_call::=
function {call_scalar}
@ -112,9 +112,18 @@ multi_assignment::=
multi_scalar '=' multi_scalar
;
loop::=
while_loop
|for_loop
|forei_loop
;
while_loop::=
while '(' calculation ')' expressions
|for '(' [definition] ';' [calculation] ';' [calculation] ')' expressions
|(forindex | foreach) '(' (definition | assignment) ';' calculation ')' expressions
;
for_loop::=
for '(' [definition] ';' [calculation] ';' [calculation] ')' expressions
;
forei_loop::=
(forindex | foreach) '(' (definition | assignment) ';' calculation ')' expressions
;
conditional::=
if '(' calculation ')' expressions

View File

@ -24,8 +24,13 @@ enum ast_node
ast_nil,ast_number,ast_string,ast_identifier,ast_function,ast_hash,ast_vector,
ast_hashmember,
ast_args,
ast_and,ast_or,
ast_equal,ast_add_equal,ast_sub_equal,ast_mult_equal,ast_div_equal,ast_link_equal,
ast_cmp_equal,ast_cmp_not_equal,ast_less_than,ast_less_equal,ast_greater_than,ast_greater_equal,
ast_add,ast_sub,ast_mult,ast_div,ast_link,
ast_unary_sub,ast_unary_not,
ast_for,ast_forindex,ast_foreach,ast_while,
ast_definition,ast_assignment,ast_calculation,
ast_definition,ast_multi_assign,ast_calculation,
ast_continue,ast_break,ast_return,
};
@ -35,6 +40,7 @@ enum parse_error
error_token,
lack_id,
lack_left_curve,
lack_right_curve,
lack_left_bracket,
lack_left_brace,
lack_right_brace,
@ -54,7 +60,8 @@ void error_info(int line,int error_type)
case unknown: detail="unknown error."; break;
case error_token: detail="this token should not exist here."; break;
case lack_id: detail="lack identifier."; break;
case lack_left_curve: detail="lack left curve."; break;
case lack_left_curve: detail="lack \'(\'."; break;
case lack_right_curve: detail="lack \')\'."; break;
case lack_left_bracket: detail="lack left bracket."; break;
case lack_left_brace: detail="lack left brace."; break;
case lack_right_brace: detail="lack right brace."; break;

View File

@ -85,14 +85,14 @@ private:
std::string number_gen(std::vector<char>&,int&,int&);
std::string string_gen(std::vector<char>&,int&,int&);
public:
void delete_tokens();
void clear();
void scanner(std::vector<char>&);
void print_token();
int get_error();
std::vector<token>& get_token_list();
};
void nasal_lexer::delete_tokens()
void nasal_lexer::clear()
{
token_list.clear();
return;

View File

@ -10,6 +10,7 @@ private:
nasal_ast root;
std::vector<token> tok_list;
void reset();
bool check_function_end(nasal_ast&);
nasal_ast nil_gen();
nasal_ast number_gen();
nasal_ast string_gen();
@ -23,8 +24,8 @@ private:
nasal_ast exprs_gen();
nasal_ast calculation();
nasal_ast trinocular();
nasal_ast and_expr();
nasal_ast or_expr();
nasal_ast and_expr();
nasal_ast cmp_expr();
nasal_ast additive_expr();
nasal_ast multive_expr();
@ -96,6 +97,17 @@ void nasal_parse::reset()
return;
}
bool nasal_parse::check_function_end(nasal_ast& node)
{
if(node.get_type()==ast_function)
return true;
if(node.get_children().empty() || (node.get_type()!=ast_definition && node.get_type()!=ast_equal))
return false;
else
return check_function_end(node.get_children().back());
return false;
}
nasal_ast nasal_parse::nil_gen()
{
nasal_ast node;
@ -245,31 +257,26 @@ nasal_ast nasal_parse::expr()
node.set_line(tok_list[ptr].line);
switch(tok_list[ptr].type)
{
case tok_nil:case tok_number:case tok_string:case tok_identifier:
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_left_bracket:
case tok_left_brace:
case tok_sub:
case tok_not: node=calculation(); break;
case tok_var: node=definition(); break;
case tok_for:case tok_forindex:case tok_foreach:
case tok_while: node=loop(); break;
case tok_if: node=conditional(); break;
case tok_continue:break;
case tok_break:break;
case tok_return:break;
case tok_semi:--ptr;break;
defaut: error_info(tok_list[ptr].line,error_token);++error;break;
}
++ptr;
if(ptr>=tok_list_size || (ptr<tok_list_size && tok_list[ptr].type!=tok_semi))
{
bool tmp=node.get_children().empty();
if(tmp || (!tmp && node.get_children().back().get_type()!=ast_function))
{
error_info(node.get_children().back().get_line(),lack_semi);
++error;
}
if(ptr<tok_list_size) --ptr;
case tok_not: node=calculation(); break;
case tok_var: node=definition(); break;
case tok_for:
case tok_forindex:
case tok_foreach:
case tok_while: node=loop(); break;
case tok_if: node=conditional(); break;
case tok_continue: node=continue_expr(); break;
case tok_break: node=break_expr(); break;
case tok_return: node=return_expr(); break;
case tok_semi: --ptr; break;
default: error_info(tok_list[ptr].line,error_token);++error;break;
}
return node;
}
@ -284,6 +291,12 @@ nasal_ast nasal_parse::exprs_gen()
{
node.add_child(expr());
++ptr;
if(ptr<tok_list_size && tok_list[ptr].type==tok_semi) ++ptr;
else if(ptr<tok_list_size && (node.get_children().empty() || !check_function_end(node.get_children().back())))
{
++error;
error_info(tok_list[ptr].line,lack_semi);
}
}
if(ptr>=tok_list_size)
{
@ -292,13 +305,19 @@ nasal_ast nasal_parse::exprs_gen()
}
}
else
{
node.add_child(expr());
++ptr;
if(ptr>=tok_list_size || tok_list[ptr].type!=tok_semi)
--ptr;
}
return node;
}
nasal_ast nasal_parse::calculation()
{
nasal_ast node;
node.set_line(tok_list[ptr].line);
int tok_type=tok_list[ptr].type;
return node;
}
nasal_ast nasal_parse::trinocular()
@ -306,39 +325,171 @@ nasal_ast nasal_parse::trinocular()
nasal_ast node;
return node;
}
nasal_ast nasal_parse::and_expr()
{
nasal_ast node;
return node;
}
nasal_ast nasal_parse::or_expr()
{
nasal_ast node;
node=and_expr();
++ptr;
while(ptr<tok_list_size && tok_list[ptr].type==tok_or)
{
nasal_ast tmp;
tmp.set_line(tok_list[ptr].line);
tmp.set_type(ast_or);
tmp.add_child(node);
++ptr;
tmp.add_child(and_expr());
node=tmp;
++ptr;
}
--ptr;
return node;
}
nasal_ast nasal_parse::and_expr()
{
nasal_ast node;
node=cmp_expr();
++ptr;
while(ptr<tok_list_size && tok_list[ptr].type==tok_and)
{
nasal_ast tmp;
tmp.set_line(tok_list[ptr].line);
tmp.set_type(ast_and);
tmp.add_child(node);
++ptr;
tmp.add_child(cmp_expr());
node=tmp;
++ptr;
}
--ptr;
return node;
}
nasal_ast nasal_parse::cmp_expr()
{
nasal_ast node;
node=additive_expr();
++ptr;
while(
ptr<tok_list_size &&
(
tok_list[ptr].type==tok_cmp_equal ||
tok_list[ptr].type==tok_cmp_not_equal ||
tok_list[ptr].type==tok_less_than ||
tok_list[ptr].type==tok_less_equal ||
tok_list[ptr].type==tok_greater_than ||
tok_list[ptr].type==tok_greater_equal
)
)
{
nasal_ast tmp;
tmp.set_line(tok_list[ptr].line);
switch(tok_list[ptr].type)
{
case tok_cmp_equal: tmp.set_type(ast_cmp_equal); break;
case tok_cmp_not_equal: tmp.set_type(ast_cmp_not_equal); break;
case tok_less_than: tmp.set_type(ast_less_than); break;
case tok_less_equal: tmp.set_type(ast_less_equal); break;
case tok_greater_than: tmp.set_type(ast_greater_than); break;
case tok_greater_equal: tmp.set_type(ast_greater_equal); break;
}
tmp.add_child(node);
++ptr;
tmp.add_child(additive_expr());
node=tmp;
++ptr;
}
--ptr;
return node;
}
nasal_ast nasal_parse::additive_expr()
{
nasal_ast node;
node=multive_expr();
++ptr;
while(ptr<tok_list_size && (tok_list[ptr].type==tok_add || tok_list[ptr].type==tok_sub || tok_list[ptr].type==tok_link))
{
nasal_ast tmp;
tmp.set_line(tok_list[ptr].line);
switch(tok_list[ptr].type)
{
case tok_add: tmp.set_type(ast_add); break;
case tok_sub: tmp.set_type(ast_sub); break;
case tok_link: tmp.set_type(ast_link); break;
}
tmp.add_child(node);
++ptr;
tmp.add_child(multive_expr());
node=tmp;
++ptr;
}
--ptr;
return node;
}
nasal_ast nasal_parse::multive_expr()
{
nasal_ast node;
if(tok_list[ptr].type==tok_sub || tok_list[ptr].type==tok_not)
node=unary();
++ptr;
while(ptr<tok_list_size && (tok_list[ptr].type==tok_mult || tok_list[ptr].type==tok_div))
{
nasal_ast tmp;
tmp.set_line(tok_list[ptr].line);
switch(tok_list[ptr].type)
{
case tok_mult:tmp.set_type(ast_mult);break;
case tok_div: tmp.set_type(ast_div); break;
}
tmp.add_child(node);
++ptr;
if(ptr<tok_list_size && (tok_list[ptr].type==tok_sub || tok_list[ptr].type==tok_not))
tmp.add_child(unary());
else if(ptr<tok_list_size && tok_list[ptr].type!=tok_sub && tok_list[ptr].type!=tok_not)
tmp.add_child(scalar());
node=tmp;
++ptr;
}
--ptr;
return node;
}
nasal_ast nasal_parse::unary()
{
nasal_ast node;
node.set_line(tok_list[ptr].line);
switch(tok_list[ptr].type)
{
case tok_sub:node.set_type(ast_unary_sub);break;
case tok_not:node.set_type(ast_unary_not);break;
}
node.add_child(scalar());
return node;
}
nasal_ast nasal_parse::scalar()
{
nasal_ast node;
node.set_line(tok_list[ptr].line);
if(tok_list[ptr].type==tok_number)
node=number_gen();
else if(tok_list[ptr].type==tok_string)
node=string_gen();
else if(
tok_list[ptr].type==tok_func ||
tok_list[ptr].type==tok_identifier ||
tok_list[ptr].type==tok_left_bracket ||
tok_list[ptr].type==tok_left_brace
)
node=call_scalar();
else if(tok_list[ptr].type==tok_left_curve)
{
int curve_line=tok_list[ptr].line;
++ptr;
node=calculation();
++ptr;
if(ptr>=tok_list_size || tok_list[ptr].type!=tok_right_curve)
{
++error;
error_info(curve_line,lack_right_curve);
}
}
return node;
}
nasal_ast nasal_parse::func_call()

View File

@ -27,7 +27,7 @@ private:
public:
void input_file(std::string);
void load_lib();
void delete_file();
void clear();
void print_file();
std::vector<char>& get_file();
};
@ -58,7 +58,7 @@ void nasal_resource::load_lib()
return;
}
void nasal_resource::delete_file()
void nasal_resource::clear()
{
res.clear();
return;