forked from xxq250/Nasal-Interpreter
update
This commit is contained in:
@@ -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."<<std::endl;
|
||||
std::cout<<">> [cls ] clear the screen."<<std::endl;
|
||||
std::cout<<">> [del ] clear the resource code."<<std::endl;
|
||||
std::cout<<">> [lib ] add lib file."<<std::endl;
|
||||
std::cout<<">> [rs ] print resource code."<<std::endl;
|
||||
std::cout<<">> [lex ] turn code into tokens."<<std::endl;
|
||||
std::cout<<">> [par ] turn tokens into abstract syntax tree."<<std::endl;
|
||||
std::cout<<">> [ast ] check the abstract syntax tree."<<std::endl;
|
||||
std::cout<<">> [run ] run code."<<std::endl;
|
||||
std::cout<<">> [logo ] print logo of nasal ."<<std::endl;
|
||||
std::cout<<">> [exit ] quit nasal interpreter."<<std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
void logo()
|
||||
{
|
||||
std::cout<<" __ _ "<<std::endl;
|
||||
@@ -10,9 +31,26 @@ void logo()
|
||||
return;
|
||||
}
|
||||
|
||||
nasal_resource resource;
|
||||
nasal_lexer lexer;
|
||||
std::string command;
|
||||
void lex_func()
|
||||
{
|
||||
lexer.scanner(resource.get_file());
|
||||
if(!lexer.get_error()) lexer.print_token();
|
||||
else std::cout<<">> [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."<<std::endl;
|
||||
std::cout<<">> [cls ] clear the screen."<<std::endl;
|
||||
std::cout<<">> [del ] clear the resource code."<<std::endl;
|
||||
std::cout<<">> [lib ] add lib file."<<std::endl;
|
||||
std::cout<<">> [rs ] print resource code."<<std::endl;
|
||||
std::cout<<">> [lex ] turn code into tokens."<<std::endl;
|
||||
std::cout<<">> [par ] turn tokens into abstract syntax tree."<<std::endl;
|
||||
std::cout<<">> [ast ] check the abstract syntax tree."<<std::endl;
|
||||
std::cout<<">> [run ] run code."<<std::endl;
|
||||
std::cout<<">> [logo ] print logo of nasal ."<<std::endl;
|
||||
std::cout<<">> [exit ] quit nasal interpreter."<<std::endl;
|
||||
}
|
||||
help();
|
||||
else if(command=="cls")
|
||||
{
|
||||
#ifdef _WIN32
|
||||
@@ -67,6 +93,8 @@ int main()
|
||||
else if(command=="del")
|
||||
{
|
||||
resource.delete_file();
|
||||
lexer.delete_tokens();
|
||||
parse.clear();
|
||||
std::cout<<">> [Delete] complete."<<std::endl;
|
||||
}
|
||||
else if(command=="lib")
|
||||
@@ -74,17 +102,9 @@ int main()
|
||||
else if(command=="rs")
|
||||
resource.print_file();
|
||||
else if(command=="lex")
|
||||
{
|
||||
lexer.scanner(resource.get_file());
|
||||
if(!lexer.get_error())
|
||||
lexer.print_token();
|
||||
else
|
||||
std::cout<<">> [lexer] error occurred,stop.\n";
|
||||
}
|
||||
lex_func();
|
||||
else if(command=="par")
|
||||
{
|
||||
;
|
||||
}
|
||||
par_func();
|
||||
else if(command=="ast")
|
||||
{
|
||||
;
|
||||
|
||||
118
version3.0/nasal.ebnf
Normal file
118
version3.0/nasal.ebnf
Normal file
@@ -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 ','} <id>
|
||||
;
|
||||
multi_scalar::=
|
||||
'(' {calculation ','} <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]
|
||||
;
|
||||
@@ -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
|
||||
103
version3.0/nasal_ast.h
Normal file
103
version3.0/nasal_ast.h
Normal file
@@ -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<nasal_ast> 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<nasal_ast>& 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>& nasal_ast::get_children()
|
||||
{
|
||||
return this->children;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -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
|
||||
@@ -81,14 +81,15 @@ class nasal_lexer
|
||||
private:
|
||||
int error;
|
||||
std::vector<token> token_list;
|
||||
public:
|
||||
std::string identifier_gen(std::vector<char>&,int&,int&);
|
||||
std::string identifier_gen(std::vector<char>&,int&,int&);
|
||||
std::string number_gen(std::vector<char>&,int&,int&);
|
||||
std::string string_gen(std::vector<char>&,int&,int&);
|
||||
public:
|
||||
void delete_tokens();
|
||||
void scanner(std::vector<char>&);
|
||||
void print_token();
|
||||
int get_error();
|
||||
std::vector<token>& get_token_list();
|
||||
};
|
||||
|
||||
void nasal_lexer::delete_tokens()
|
||||
@@ -323,4 +324,9 @@ int nasal_lexer::get_error()
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
std::vector<token>& nasal_lexer::get_token_list()
|
||||
{
|
||||
return token_list;
|
||||
}
|
||||
#endif
|
||||
@@ -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<token> 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<token>&);
|
||||
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<token>& lex_token)
|
||||
{
|
||||
this->tok_list=lex_token;
|
||||
tok_list_size=this->tok_list.size();
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_parse::main_process()
|
||||
{
|
||||
this->reset();
|
||||
while(ptr<tok_list_size)
|
||||
{
|
||||
if(tok_list[ptr].type);
|
||||
++ptr;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_parse::reset()
|
||||
{
|
||||
this->ptr=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
|
||||
Reference in New Issue
Block a user