This commit is contained in:
Valk Richard Li
2020-06-09 02:13:54 -07:00
committed by GitHub
parent 57f99e9af3
commit f23d124d4c
7 changed files with 407 additions and 28 deletions

View File

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

View File

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

View File

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

View File

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

View File

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