mirror of
https://github.com/ValKmjolnir/Nasal-Interpreter.git
synced 2026-07-27 05:18:46 +08:00
update
This commit is contained in:
+170
-9
@@ -7,27 +7,64 @@ class nasal_parse
|
||||
std::stack<token> parse_token_stream;
|
||||
std::stack<token> checked_tokens;
|
||||
token this_token;
|
||||
int error;
|
||||
int error;
|
||||
abstract_syntax_tree root;
|
||||
enum parse_error_type
|
||||
{
|
||||
parse_unknown_error=0, // unknown error
|
||||
error_token_in_main, // when a token should not be the begin of a statement in main
|
||||
error_token_in_block, // when a token should not be the begin of a statement in block
|
||||
|
||||
lack_semi,
|
||||
lack_id,
|
||||
lack_left_curve,
|
||||
lack_right_curve,
|
||||
lack_right_brace,
|
||||
|
||||
definition_lack_id, // lack identifier
|
||||
definition_lack_equal, // lack '=' when not getting ';'
|
||||
assignment_begin_error, // assignment begins with more than one identifier_call
|
||||
multi_definition_need_curve, // lack right curve when generating 'var (id,id,id)'
|
||||
|
||||
multi_assignment_need_curve, // lack right curve when generating (scalar,scalar)=(scalar,scalar)
|
||||
multi_assignment_need_equal, // lack '=' when generating (scalar,scalar)=(scalar,scalar)
|
||||
|
||||
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, // 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
|
||||
call_vector_wrong_token, // get wrong token when calling a vector
|
||||
|
||||
vector_gen_lack_end, // lack ',' or ')' when generating a vector
|
||||
hash_gen_lack_id, // lack identifier or string when generating a hash
|
||||
hash_gen_lack_colon, // lack ':' when generating a hash
|
||||
hash_gen_lack_end, // lack ',' or '}' when generating a hash
|
||||
|
||||
ternary_operator_lack_colon, // lack ':'
|
||||
};
|
||||
void print_parse_error(int,int,int);
|
||||
// most important function of parser
|
||||
// these two functions are used to get and push token
|
||||
// by using them,parser can generate ast
|
||||
void get_token();
|
||||
void push_token();
|
||||
|
||||
// block statements generation
|
||||
abstract_syntax_tree block_generate();
|
||||
|
||||
// check ';'
|
||||
void check_semi();
|
||||
|
||||
// check '(' confliction
|
||||
bool check_multi_assignment();// check multi_call_id '=' multi_scalar
|
||||
bool check_multi_scalar(); // check multi_scalar
|
||||
bool check_var_in_curve(); // check multi_definition: (var id,id,id)
|
||||
bool check_function_end(abstract_syntax_tree&); // check end of definition or '=' is a function
|
||||
|
||||
/*
|
||||
calculation() will get elements generated by and_calculation()
|
||||
and_calculation() will get elements generated by or_calculation()
|
||||
@@ -48,14 +85,13 @@ class nasal_parse
|
||||
abstract_syntax_tree additive_calculation();
|
||||
abstract_syntax_tree multive_calculation();
|
||||
abstract_syntax_tree scalar_generate();
|
||||
|
||||
// normal data type generation
|
||||
abstract_syntax_tree hash_generate();
|
||||
abstract_syntax_tree vector_generate();
|
||||
abstract_syntax_tree function_generate();
|
||||
|
||||
// return_expr() generates ebnf: <return> [<calculation>] ';'
|
||||
abstract_syntax_tree return_expr();
|
||||
// normal expressions
|
||||
abstract_syntax_tree multi_scalar_assignment();
|
||||
abstract_syntax_tree definition();
|
||||
abstract_syntax_tree loop_expr();
|
||||
@@ -74,9 +110,8 @@ class nasal_parse
|
||||
}
|
||||
void print_detail_token();
|
||||
void get_token_list(std::list<token>&);
|
||||
int get_error();
|
||||
int get_error();
|
||||
abstract_syntax_tree& get_root();
|
||||
|
||||
// abstract_syntax_tree generation
|
||||
// main process of parser
|
||||
void main_generate();
|
||||
@@ -114,6 +149,8 @@ void nasal_parse::print_detail_token()
|
||||
|
||||
void nasal_parse::get_token_list(std::list<token>& detail_token_stream)
|
||||
{
|
||||
// get detail_token_stream from lexer
|
||||
// clear the parse_token_stream and checked_tokens list
|
||||
while(!parse_token_stream.empty())
|
||||
parse_token_stream.pop();
|
||||
while(!checked_tokens.empty())
|
||||
@@ -142,6 +179,130 @@ void nasal_parse::get_token_list(std::list<token>& detail_token_stream)
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_parse::print_parse_error(int error_type,int line,int error_token_type=__stack_end)
|
||||
{
|
||||
std::string error_info_head=">> [Parse] line ";
|
||||
switch(error_type)
|
||||
{
|
||||
case parse_unknown_error:
|
||||
std::cout<<error_info_head<<line<<": unknown parse error.(token id: "<<error_token_type<<")."<<std::endl;break;
|
||||
case error_token_in_main:
|
||||
std::cout<<error_info_head<<line<<": statements should not begin with \'";
|
||||
print_parse_token(error_token_type);
|
||||
std::cout<<"\' in main scope."<<std::endl;
|
||||
break;
|
||||
case error_token_in_block:
|
||||
std::cout<<error_info_head<<line<<": statements should not begin with \'";
|
||||
print_parse_token(error_token_type);
|
||||
std::cout<<"\' in block scope."<<std::endl;
|
||||
break;
|
||||
case lack_semi:
|
||||
std::cout<<error_info_head<<line<<": expect a \';\' at the end of the statement."<<std::endl;break;
|
||||
case lack_id:
|
||||
std::cout<<error_info_head<<line<<": expect an identifier here."<<std::endl;break;
|
||||
case lack_left_curve:
|
||||
std::cout<<error_info_head<<line<<": expect a \'(\' here."<<std::endl;break;
|
||||
case lack_right_curve:
|
||||
std::cout<<error_info_head<<line<<": expect a \')\' here."<<std::endl;break;
|
||||
case lack_right_brace:
|
||||
std::cout<<error_info_head<<line<<": expect a \'}\' here."<<std::endl;break;
|
||||
case definition_lack_id:
|
||||
std::cout<<error_info_head<<line<<": expect identifier(s) after \'var\'."<<std::endl;break;
|
||||
case definition_lack_equal:
|
||||
std::cout<<error_info_head<<line<<": expect a \'=\' here but get \'";
|
||||
print_parse_token(error_token_type);
|
||||
std::cout<<"\' when generating definition."<<std::endl;
|
||||
break;
|
||||
case assignment_begin_error:
|
||||
std::cout<<error_info_head<<line<<": assignment should begin with one identifier_call."<<std::endl;
|
||||
break;
|
||||
case multi_definition_need_curve:
|
||||
std::cout<<error_info_head<<line<<": expect a \')\' here but get \'";
|
||||
print_parse_token(error_token_type);
|
||||
std::cout<<"\' ."<<std::endl;
|
||||
break;
|
||||
case multi_assignment_need_curve:
|
||||
std::cout<<error_info_head<<line<<": expect a \')\' here but get \'";
|
||||
print_parse_token(error_token_type);
|
||||
std::cout<<"\' ."<<std::endl;
|
||||
break;
|
||||
case multi_assignment_need_equal:
|
||||
std::cout<<error_info_head<<line<<": expect a \'=\' here but get \'";
|
||||
print_parse_token(error_token_type);
|
||||
std::cout<<"\' ."<<std::endl;
|
||||
break;
|
||||
case error_begin_token_of_scalar:
|
||||
std::cout<<error_info_head<<line<<": expect a scalar here but get \'";
|
||||
print_parse_token(error_token_type);
|
||||
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:
|
||||
std::cout<<error_info_head<<line<<": expect a \')\' or \',\' here when generating parameter_list."<<std::endl;break;
|
||||
case special_call_func_lack_id:
|
||||
std::cout<<error_info_head<<line<<": expect an identifier here but get \'";
|
||||
print_parse_token(error_token_type);
|
||||
std::cout<<"\' when calling functions."<<std::endl;
|
||||
break;
|
||||
case special_call_func_lack_colon:
|
||||
std::cout<<error_info_head<<line<<": expect an \':\' here but get \'";
|
||||
print_parse_token(error_token_type);
|
||||
std::cout<<"\' when calling functions."<<std::endl;
|
||||
break;
|
||||
case call_func_lack_comma:
|
||||
std::cout<<error_info_head<<line<<": expect a \',\' when calling a function but get \'";
|
||||
print_parse_token(error_token_type);
|
||||
std::cout<<"\' ."<<std::endl;
|
||||
break;
|
||||
case call_hash_lack_id:
|
||||
std::cout<<error_info_head<<line<<": expect an identifier after \'.\' ."<<std::endl;break;
|
||||
case call_vector_wrong_comma:
|
||||
std::cout<<error_info_head<<line<<": expect a scalar after \',\' but get \']\' ."<<std::endl;
|
||||
break;
|
||||
case call_vector_lack_bracket:
|
||||
std::cout<<error_info_head<<line<<": expect a \']\' here but get \'";
|
||||
print_parse_token(error_token_type);
|
||||
std::cout<<"\' ."<<std::endl;
|
||||
break;
|
||||
case call_vector_wrong_token:
|
||||
std::cout<<error_info_head<<line<<": expect \':\' or ',' or ']' here but get \'";
|
||||
print_parse_token(error_token_type);
|
||||
std::cout<<"\' ."<<std::endl;
|
||||
break;
|
||||
case vector_gen_lack_end:
|
||||
std::cout<<error_info_head<<line<<": expect a \',\' or \')\' here but get \'";
|
||||
print_parse_token(error_token_type);
|
||||
std::cout<<"\' ."<<std::endl;
|
||||
break;
|
||||
case hash_gen_lack_id:
|
||||
std::cout<<error_info_head<<line<<": expect an identifier or string here but get \'";
|
||||
print_parse_token(error_token_type);
|
||||
std::cout<<"\' ."<<std::endl;
|
||||
break;
|
||||
case hash_gen_lack_colon:
|
||||
std::cout<<error_info_head<<line<<": expect a \':\' here but get \'";
|
||||
print_parse_token(error_token_type);
|
||||
std::cout<<"\' ."<<std::endl;
|
||||
break;
|
||||
case hash_gen_lack_end:
|
||||
std::cout<<error_info_head<<line<<": expect a \',\' or \'}\' here but get \'";
|
||||
print_parse_token(error_token_type);
|
||||
std::cout<<"\' ."<<std::endl;
|
||||
break;
|
||||
case ternary_operator_lack_colon:
|
||||
std::cout<<error_info_head<<line<<": expect a \':\' here but get \'";
|
||||
print_parse_token(error_token_type);
|
||||
std::cout<<"\' ."<<std::endl;
|
||||
break;
|
||||
default:
|
||||
std::cout<<error_info_head<<line<<": unknown parse error.(token id: "<<error_token_type<<")."<<std::endl;break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_parse::get_token()
|
||||
{
|
||||
if(!parse_token_stream.empty())
|
||||
|
||||
Reference in New Issue
Block a user