This commit is contained in:
Valk Richard Li 2019-11-04 20:16:51 +08:00 committed by GitHub
parent 3357fa8140
commit 93eb59ef34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 287 additions and 19 deletions

View File

@ -5,29 +5,185 @@ class abstract_syntax_tree
{
private:
int type;
double number;
std::string str;
std::string name;
double var_number;
std::string var_string;
std::string var_name;
std::list<abstract_syntax_tree> children;
public:
abstract_syntax_tree()
{
type=__null_node;
number=0;
str="";
name="";
type=0;
var_number=0;
var_string="";
var_name="";
children.clear();
return;
}
abstract_syntax_tree(const abstract_syntax_tree& p)
{
type=p.type;
number=p.number;
str=p.str;
name=p.name;
var_number=p.var_number;
var_string=p.var_string;
var_name=p.var_name;
children=p.children;
return;
}
abstract_syntax_tree& operator=(const abstract_syntax_tree& p)
{
type=p.type;
var_number=p.var_number;
var_string=p.var_string;
var_name=p.var_name;
children.clear();
children=p.children;
return *this;
}
void set_clear()
{
type=0;
var_number=0;
var_string="";
var_name="";
children.clear();
return;
}
void print_tree(const int n)
{
std::string str="";
for(int i=0;i<n;++i)
str+="| ";
std::cout<<str;
print_detail_token(type);
switch(type)
{
case __number:std::cout<<": "<<var_number;break;
case __string:std::cout<<": "<<var_string;break;
case __id:
case __call_array:
case __call_hash:
case __call_function:std::cout<<": "<<var_name;break;
}
std::cout<<std::endl;
if(!children.empty())
{
for(auto i=children.begin();i!=children.end();++i)
i->print_tree(n+1);
}
return;
}
void set_type(const int _type)
{
type=_type;
return;
}
void set_string(std::string str)
{
var_string=str;
return;
}
void set_number(std::string str)
{
if(str=="nil")
{
var_number=0;
return;
}
if((int)str.length()>2 && (str[1]=='x' || str[1]=='o'))
{
if(str[1]=='x')
{
int num=0;
int pw=1;
for(int i=(int)str.length()-1;i>1;--i)
{
if('0'<=str[i] && str[i]<='9')
num+=(str[i]-'0')*pw;
else if('a'<=str[i] && str[i]<='f')
num+=(10+str[i]-'a')*pw;
else if('A'<=str[i] && str[i]<='F')
num+=(10+str[i]-'A')*pw;
pw<<=4;
}
var_number=(double)num;
}
else
{
int num=0;
int pw=1;
for(int i=(int)str.length()-1;i>1;--i)
{
num+=(str[i]-'0')*pw;
pw<<=3;
}
var_number=(double)num;
}
return;
}
int dot_place=-1;
for(int i=0;i<(int)str.length();++i)
if(str[i]=='.')
{
dot_place=i;
break;
}
if(dot_place==-1)
{
var_number=0;
double pw=1;
for(int i=(int)str.length()-1;i>=0;--i)
{
var_number+=(str[i]-'0')*pw;
pw*=10;
}
}
else
{
var_number=0;
double pw=0.1;
for(int i=dot_place+1;i<(int)str.length();++i)
{
var_number+=(str[i]-'0')*pw;
pw/=10;
}
pw=1;
for(int i=dot_place-1;i>=0;--i)
{
var_number+=(str[i]-'0')*pw;
pw*=10;
}
}
return;
}
void set_name(std::string& str)
{
var_name=str;
return;
}
void add_child(abstract_syntax_tree p)
{
children.push_back(p);
return;
}
int get_type()
{
return type;
}
double get_number()
{
return var_number;
}
std::string get_string()
{
return var_string;
}
std::string get_name()
{
return var_name;
}
std::list<abstract_syntax_tree>& get_children()
{
return children;
}
};
#endif

View File

@ -14,7 +14,54 @@ int is_reserve_word(std::string str)
return __reserve_word;
return __token_identifier;
}
bool check_number(std::string str)
{
if(str.length()==1)
return true;
else if(str.length()==2 && '0'<str[0] && str[0]<='9' && '0'<=str[1] && str[1]<='9')
return true;
else if(str.length()>=3 && str[0]=='0' && str[1]=='x')
{
for(int i=2;i<str.length();++i)
{
if('0'<=str[i] && str[i]<='9' || 'a'<=str[i] && str[i]<='f' || 'A'<=str[i] && str[i]<='F')
;
else
return false;
}
return true;
}
else if(str.length()>=3 && str[0]=='0' && str[1]=='o')
{
for(int i=2;i<str.length();++i)
{
if('0'<=str[i] && str[i]<='7')
;
else
return false;
}
return true;
}
else
{
int dotcnt=0;
for(int i=0;i<str.length();++i)
{
if(str[i]=='.')
++dotcnt;
else if(!('0'<=str[i] && str[i]<='9'))
return false;
}
if(dotcnt>1)
return false;
if(str[0]=='.')
return false;
if(!dotcnt && str[0]=='0')
return false;
return true;
}
return false;
}
class resource_file
@ -30,6 +77,11 @@ class resource_file
void input_file(std::string filename)
{
std::ifstream fin(filename,std::ios::binary);
if(fin.fail())
{
std::cout<<">>[Resource] cannot find a file named \'"<<filename<<"\' ."<<std::endl;
return;
}
char c;
while(!fin.eof())
{
@ -164,13 +216,19 @@ class balloon_lexer
else if('0'<=*ptr && *ptr<='9')
{
token_str="";
while(('0'<=*ptr && *ptr<='9') || *ptr=='.' || *ptr=='x' || *ptr=='o')
while(('0'<=*ptr && *ptr<='9') || ('a'<=*ptr && *ptr<='f') || ('A'<=*ptr && *ptr<='F') || *ptr=='.' || *ptr=='x' || *ptr=='o')
{
token_str+=*ptr;
++ptr;
if(ptr==res.end())
break;
}
if(!check_number(token_str))
{
++error;
std::cout<<">>[Lexer-error] line "<<line<<": error number "<<token_str<<"."<<std::endl;
token_str="0";
}
token new_token;
new_token.line=line;
new_token.type=__token_number;
@ -261,6 +319,7 @@ class balloon_lexer
break;
}
}
std::cout<<">>[Lexer] complete scanning. "<<error<<" error(s)."<<std::endl;
return;
}
void generate_detail_token()
@ -404,11 +463,16 @@ class balloon_lexer
detail_token.push_back(detail);
}
}
std::cout<<">>[Lexer] complete generating. "<<error<<" error(s)."<<std::endl;
return;
}
std::list<token>& get_detail_token()
{
return detail_token;
}
int get_error()
{
return error;
}
};
#endif

View File

@ -4,17 +4,17 @@
class balloon_parse
{
private:
std::stack<token> detail;
std::stack<token> parse;
token this_token;
int error;
int warning;
public:
void get_token()
{
if(!detail.empty())
if(!parse.empty())
{
this_token=detail.top();
detail.pop();
this_token=parse.top();
parse.pop();
}
else
this_token.type=0;
@ -22,16 +22,48 @@ class balloon_parse
}
void get_detail_token_stream(std::list<token>& tk_list)
{
while(!parse.empty())
parse.pop();
if(tk_list.empty())
return;
std::stack<token> temp;
for(std::list<token>::iterator i=tk_list.begin();i!=tk_list.end();++i)
temp.push(*i);
while(!temp.empty())
{
detail.push(temp.top());
parse.push(temp.top());
temp.pop();
}
return;
}
void print_parse_stack()
{
if(parse.empty())
return;
std::stack<token> temp;
int line=parse.top().line;
std::cout<<line<<" ";
while(!parse.empty())
{
if(parse.top().line!=line)
{
line=parse.top().line;
std::cout<<std::endl<<line<<" ";
}
temp.push(parse.top());
std::cout<<" ";
print_detail_token(temp.top().type);
parse.pop();
}
while(!temp.empty())
{
parse.push(temp.top());
temp.pop();
}
std::cout<<std::endl;
return;
}
};
#endif

View File

@ -39,7 +39,7 @@ class var
balloon_hash=p.balloon_hash;
return;
}
var& operator=(const var p)
var& operator=(const var& p)
{
type=p.type;
number=p.number;

View File

@ -3,6 +3,7 @@ int main()
{
resource_file prog;
balloon_lexer lex;
balloon_parse pas;
std::string command;
std::cout<<">> Balloon interpreter by ValKmjolnir"<<std::endl;
std::cout<<">> Input [help] to find help."<<std::endl;
@ -49,10 +50,25 @@ int main()
{
lex.scanner(prog.get_resource());
lex.generate_detail_token();
if(!lex.get_error())
{
pas.get_detail_token_stream(lex.get_detail_token());
pas.print_parse_stack();
}
else
std::cout<<">>[Lexer] error(s) found,stop."<<std::endl;
}
else if(command=="ast")
{
;
lex.scanner(prog.get_resource());
lex.generate_detail_token();
if(!lex.get_error())
{
pas.get_detail_token_stream(lex.get_detail_token());
}
else
std::cout<<">>[Lexer] error(s) found,stop."<<std::endl;
}
else if(command=="run")
{