diff --git a/version3.0/main.cpp b/version3.0/main.cpp index 9025e7e..ddd1392 100644 --- a/version3.0/main.cpp +++ b/version3.0/main.cpp @@ -1,5 +1,26 @@ #include "nasal.h" +nasal_resource resource; +nasal_lexer lexer; +nasal_parse parse; +std::string command; + +void help() +{ + std::cout<<">> [\'file\'] input a file."<> [cls ] clear the screen."<> [del ] clear the resource code."<> [lib ] add lib file."<> [rs ] print resource code."<> [lex ] turn code into tokens."<> [par ] turn tokens into abstract syntax tree."<> [ast ] check the abstract syntax tree."<> [run ] run code."<> [logo ] print logo of nasal ."<> [exit ] quit nasal interpreter."<> [lexer] error occurred,stop.\n"; + return; +} + +void par_func() +{ + lexer.scanner(resource.get_file()); + if(!lexer.get_error()) + { + parse.set_toklist(lexer.get_token_list()); + if(parse.get_error()) std::cout<<">> [parse] error occurred,stop.\n"; + } + else std::cout<<">> [lexer] error occurred,stop.\n"; + return; +} + int main() { #ifdef _WIN32 @@ -39,19 +77,7 @@ int main() std::cout<<">> "; std::cin>>command; if(command=="help") - { - std::cout<<">> [\'file\'] input a file."<> [cls ] clear the screen."<> [del ] clear the resource code."<> [lib ] add lib file."<> [rs ] print resource code."<> [lex ] turn code into tokens."<> [par ] turn tokens into abstract syntax tree."<> [ast ] check the abstract syntax tree."<> [run ] run code."<> [logo ] print logo of nasal ."<> [exit ] quit nasal interpreter."<> [Delete] complete."<> [lexer] error occurred,stop.\n"; - } + lex_func(); else if(command=="par") - { - ; - } + par_func(); else if(command=="ast") { ; diff --git a/version3.0/nasal.ebnf b/version3.0/nasal.ebnf new file mode 100644 index 0000000..7de9ee0 --- /dev/null +++ b/version3.0/nasal.ebnf @@ -0,0 +1,118 @@ +(* + <> must choose + [] can choose + {} can repeat 0 to infinite time(s) + | or + ::= is defined as +*) + +nil ::= nil; +id ::= identifier; +number::= number; +string::= string; +vector::= + '[' {calculation ','} ']' +; +hash ::= + '{' {hashmember ','} '}' +; +hashmember::= + id ':' calculation +; +function::= + func argument_list expressions +; +argument_list::= + '(' [{id ','} ([id '...']|{id '=' calculation ','})] ')' +; +expressions::= + '{' {definition|assignment|calculation|loop|conditional} '}' + |definition ';' + |multi_assignment ';' + |calculation ';' + |loop + |conditional +; +calculation::= + '(' calculation ')' + |scalar_gen + |trinocular + |and_expr + |calculation ('=' | '+=' | '-=' | '*=' | '/=' | '~=') calculation +; +trinocular::= + calculation '?' calculation ':' calculation +; +and_expr::= + or_expr and or_expr +; +or_expr::= + cmp_expr or cmp_expr +; +cmp_expr::= + additive_expr ('==' | '!=' | '>' | '<' | '>=' | '<=') additive_expr +; +additive_expr::= + multive_expr ('+' | '-' | '~') multive_expr +; +multive_expr::= + unary ('*' | '/') unary +; +unary::= + ('-'|'!') calculation +; +scalar_gen::= + function_call + |identifier_call + |vector_call + |hash_call + |number + |string +; +function_call::= + function {call_scalar} +; +identifier_call::= + id {call_scalar} +; +vector_call::= + vector {call_scalar} +; +hash_call::= + hash {call_scalar} +; +call_scalar::= + '.' id + |'[' {(calculation | subvec) ','} ']' + |'(' {calculation ','} ')' + |'(' {hashmember ','} ')' +; +subvec::= + calculation ':' calculation + |calculation ':' + |':' calculation +; +definition::= + var id '=' calculation + |var '(' multi_id ')' '=' (calculation | multi_scalar) + |'(' var multi_id ')' '=' (calculation | multi_scalar) +; +multi_id::= + {id ','} +; +multi_scalar::= + '(' {calculation ','} ')' +; +multi_assignment::= + multi_scalar '=' multi_scalar +; +loop::= + while '(' calculation ')' expressions + |for '(' [definition] ';' [calculation] ';' [calculation] ')' expressions + |(forindex | foreach) '(' (definition | assignment) ';' calculation ')' expressions +; +conditional::= + if '(' calculation ')' expressions + {elsif '(' calculation ')' expressions} + [else expressions] +; \ No newline at end of file diff --git a/version3.0/nasal.h b/version3.0/nasal.h index 69e817b..1fb3418 100644 --- a/version3.0/nasal.h +++ b/version3.0/nasal.h @@ -19,6 +19,7 @@ #include "nasal_misc.h" #include "nasal_resource.h" #include "nasal_lexer.h" +#include "nasal_ast.h" #include "nasal_parse.h" #endif \ No newline at end of file diff --git a/version3.0/nasal_ast.h b/version3.0/nasal_ast.h new file mode 100644 index 0000000..c5c5ff6 --- /dev/null +++ b/version3.0/nasal_ast.h @@ -0,0 +1,103 @@ +#ifndef __NASAL_AST_H__ +#define __NASAL_AST_H__ + +class nasal_ast +{ +private: + int line; + int type; + std::string str; + std::vector children; +public: + nasal_ast(); + nasal_ast(const nasal_ast&); + ~nasal_ast(); + void clear(); + void set_line(int); + void set_type(int); + void set_str(std::string&); + void add_child(nasal_ast&); + int get_line(); + int get_type(); + std::string get_str(); + std::vector& get_children(); +}; + +nasal_ast::nasal_ast() +{ + this->line=0; + this->type=ast_null; + this->str=""; + return; +} + +nasal_ast::nasal_ast(const nasal_ast& tmp) +{ + this->line=tmp.line; + this->type=tmp.type; + this->str=tmp.str; + this->children=tmp.children; + return; +} + +nasal_ast::~nasal_ast() +{ + this->str.clear(); + this->children.clear(); + return; +} + +void nasal_ast::clear() +{ + this->line=0; + this->type=ast_null; + this->str=""; + this->children.clear(); + return; +} + +void nasal_ast::set_line(int l) +{ + this->line=l; + return; +} + +void nasal_ast::set_type(int t) +{ + this->type=t; + return; +} + +void nasal_ast::set_str(std::string& s) +{ + this->str=s; + return; +} + +void nasal_ast::add_child(nasal_ast& ast) +{ + children.push_back(ast); + return; +} + +int nasal_ast::get_line() +{ + return this->line; +} + +int nasal_ast::get_type() +{ + return this->type; +} + +std::string nasal_ast::get_str() +{ + return this->str; +} + +std::vector& nasal_ast::get_children() +{ + return this->children; +} + +#endif \ No newline at end of file diff --git a/version3.0/nasal_enum.h b/version3.0/nasal_enum.h index b7ed275..513d7f1 100644 --- a/version3.0/nasal_enum.h +++ b/version3.0/nasal_enum.h @@ -18,4 +18,12 @@ enum token_type tok_cmp_equal,tok_cmp_not_equal,tok_less_than,tok_greater_than,tok_less_equal,tok_greater_equal }; +enum ast_node +{ + ast_null=0, + ast_nil,ast_number,ast_string,ast_identifier, + ast_for,ast_forindex,ast_foreach,ast_while, + ast_definition,ast_assignment +}; + #endif \ No newline at end of file diff --git a/version3.0/nasal_lexer.h b/version3.0/nasal_lexer.h index 889b9f3..f74b3f6 100644 --- a/version3.0/nasal_lexer.h +++ b/version3.0/nasal_lexer.h @@ -81,14 +81,15 @@ class nasal_lexer private: int error; std::vector token_list; -public: - std::string identifier_gen(std::vector&,int&,int&); + std::string identifier_gen(std::vector&,int&,int&); std::string number_gen(std::vector&,int&,int&); std::string string_gen(std::vector&,int&,int&); +public: void delete_tokens(); void scanner(std::vector&); void print_token(); int get_error(); + std::vector& get_token_list(); }; void nasal_lexer::delete_tokens() @@ -323,4 +324,9 @@ int nasal_lexer::get_error() { return error; } + +std::vector& nasal_lexer::get_token_list() +{ + return token_list; +} #endif \ No newline at end of file diff --git a/version3.0/nasal_parse.h b/version3.0/nasal_parse.h index c722b55..31b3d96 100644 --- a/version3.0/nasal_parse.h +++ b/version3.0/nasal_parse.h @@ -1,4 +1,127 @@ #ifndef __NASAL_PARSE_H__ #define __NAsAL_PARSE_H__ +class nasal_parse +{ +private: + int tok_list_size; + int ptr; + int error; + nasal_ast root; + std::vector tok_list; + void reset(); + nasal_ast nil_gen(); + nasal_ast number_gen(); + nasal_ast string_gen(); + nasal_ast id_gen(); + nasal_ast vector_gen(); + nasal_ast hash_gen(); + nasal_ast hash_member_gen(); + nasal_ast func_gen(); + nasal_ast args_list_gen(); + nasal_ast exprs_gen(); + nasal_ast calculation(); + nasal_ast trinocular(); + nasal_ast and_expr(); + nasal_ast or_expr(); + nasal_ast cmp_expr(); + nasal_ast additive_expr(); + nasal_ast multive_expr(); + nasal_ast unary(); + nasal_ast scalar_gen(); + nasal_ast func_call(); + nasal_ast id_call(); + nasal_ast vector_call(); + nasal_ast hash_call(); + nasal_ast call_scalar(); + nasal_ast subvec(); + nasal_ast definition(); + nasal_ast multi_id(); + nasal_ast multi_scalar(); + nasal_ast multi_assgin(); + nasal_ast loop(); + nasal_ast conditional(); +public: + int get_error(); + void clear(); + void set_toklist(std::vector&); + void main_process(); +}; + +int nasal_parse::get_error() +{ + return this->error; +} + +void nasal_parse::clear() +{ + this->tok_list_size=0; + this->ptr=0; + this->error=0; + this->tok_list.clear(); + this->root.clear(); + return; +} + +void nasal_parse::set_toklist(std::vector& lex_token) +{ + this->tok_list=lex_token; + tok_list_size=this->tok_list.size(); + return; +} + +void nasal_parse::main_process() +{ + this->reset(); + while(ptrptr=0; + this->error=0; + this->root.clear(); + return; +} + +nasal_ast nasal_parse::nil_gen() +{ + nasal_ast node; + node.set_line(tok_list[ptr].line); + node.set_type(ast_nil); + return node; +} + +nasal_ast nasal_parse::number_gen() +{ + nasal_ast node; + node.set_line(tok_list[ptr].line); + node.set_type(ast_number); + node.set_str(tok_list[ptr].str); + return node; +} + +nasal_ast nasal_parse::string_gen() +{ + nasal_ast node; + node.set_line(tok_list[ptr].line); + node.set_type(ast_string); + node.set_str(tok_list[ptr].str); + return node; +} + +nasal_ast nasal_parse::id_gen() +{ + nasal_ast node; + node.set_line(tok_list[ptr].line); + node.set_type(ast_identifier); + node.set_str(tok_list[ptr].str); + return node; +} + #endif \ No newline at end of file