Update
This commit is contained in:
parent
3357fa8140
commit
93eb59ef34
|
@ -5,29 +5,185 @@ class abstract_syntax_tree
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
int type;
|
int type;
|
||||||
double number;
|
double var_number;
|
||||||
std::string str;
|
std::string var_string;
|
||||||
std::string name;
|
std::string var_name;
|
||||||
std::list<abstract_syntax_tree> children;
|
std::list<abstract_syntax_tree> children;
|
||||||
public:
|
public:
|
||||||
abstract_syntax_tree()
|
abstract_syntax_tree()
|
||||||
{
|
{
|
||||||
type=__null_node;
|
type=0;
|
||||||
number=0;
|
var_number=0;
|
||||||
str="";
|
var_string="";
|
||||||
name="";
|
var_name="";
|
||||||
children.clear();
|
children.clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
abstract_syntax_tree(const abstract_syntax_tree& p)
|
abstract_syntax_tree(const abstract_syntax_tree& p)
|
||||||
{
|
{
|
||||||
type=p.type;
|
type=p.type;
|
||||||
number=p.number;
|
var_number=p.var_number;
|
||||||
str=p.str;
|
var_string=p.var_string;
|
||||||
name=p.name;
|
var_name=p.var_name;
|
||||||
children=p.children;
|
children=p.children;
|
||||||
return;
|
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
|
#endif
|
||||||
|
|
|
@ -14,7 +14,54 @@ int is_reserve_word(std::string str)
|
||||||
return __reserve_word;
|
return __reserve_word;
|
||||||
return __token_identifier;
|
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
|
class resource_file
|
||||||
|
@ -30,6 +77,11 @@ class resource_file
|
||||||
void input_file(std::string filename)
|
void input_file(std::string filename)
|
||||||
{
|
{
|
||||||
std::ifstream fin(filename,std::ios::binary);
|
std::ifstream fin(filename,std::ios::binary);
|
||||||
|
if(fin.fail())
|
||||||
|
{
|
||||||
|
std::cout<<">>[Resource] cannot find a file named \'"<<filename<<"\' ."<<std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
char c;
|
char c;
|
||||||
while(!fin.eof())
|
while(!fin.eof())
|
||||||
{
|
{
|
||||||
|
@ -164,13 +216,19 @@ class balloon_lexer
|
||||||
else if('0'<=*ptr && *ptr<='9')
|
else if('0'<=*ptr && *ptr<='9')
|
||||||
{
|
{
|
||||||
token_str="";
|
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;
|
token_str+=*ptr;
|
||||||
++ptr;
|
++ptr;
|
||||||
if(ptr==res.end())
|
if(ptr==res.end())
|
||||||
break;
|
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;
|
token new_token;
|
||||||
new_token.line=line;
|
new_token.line=line;
|
||||||
new_token.type=__token_number;
|
new_token.type=__token_number;
|
||||||
|
@ -261,6 +319,7 @@ class balloon_lexer
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
std::cout<<">>[Lexer] complete scanning. "<<error<<" error(s)."<<std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void generate_detail_token()
|
void generate_detail_token()
|
||||||
|
@ -404,11 +463,16 @@ class balloon_lexer
|
||||||
detail_token.push_back(detail);
|
detail_token.push_back(detail);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
std::cout<<">>[Lexer] complete generating. "<<error<<" error(s)."<<std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::list<token>& get_detail_token()
|
std::list<token>& get_detail_token()
|
||||||
{
|
{
|
||||||
return detail_token;
|
return detail_token;
|
||||||
}
|
}
|
||||||
|
int get_error()
|
||||||
|
{
|
||||||
|
return error;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4,17 +4,17 @@
|
||||||
class balloon_parse
|
class balloon_parse
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::stack<token> detail;
|
std::stack<token> parse;
|
||||||
token this_token;
|
token this_token;
|
||||||
int error;
|
int error;
|
||||||
int warning;
|
int warning;
|
||||||
public:
|
public:
|
||||||
void get_token()
|
void get_token()
|
||||||
{
|
{
|
||||||
if(!detail.empty())
|
if(!parse.empty())
|
||||||
{
|
{
|
||||||
this_token=detail.top();
|
this_token=parse.top();
|
||||||
detail.pop();
|
parse.pop();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
this_token.type=0;
|
this_token.type=0;
|
||||||
|
@ -22,16 +22,48 @@ class balloon_parse
|
||||||
}
|
}
|
||||||
void get_detail_token_stream(std::list<token>& tk_list)
|
void get_detail_token_stream(std::list<token>& tk_list)
|
||||||
{
|
{
|
||||||
|
while(!parse.empty())
|
||||||
|
parse.pop();
|
||||||
|
if(tk_list.empty())
|
||||||
|
return;
|
||||||
std::stack<token> temp;
|
std::stack<token> temp;
|
||||||
for(std::list<token>::iterator i=tk_list.begin();i!=tk_list.end();++i)
|
for(std::list<token>::iterator i=tk_list.begin();i!=tk_list.end();++i)
|
||||||
temp.push(*i);
|
temp.push(*i);
|
||||||
while(!temp.empty())
|
while(!temp.empty())
|
||||||
{
|
{
|
||||||
detail.push(temp.top());
|
parse.push(temp.top());
|
||||||
temp.pop();
|
temp.pop();
|
||||||
}
|
}
|
||||||
return;
|
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
|
#endif
|
||||||
|
|
|
@ -39,7 +39,7 @@ class var
|
||||||
balloon_hash=p.balloon_hash;
|
balloon_hash=p.balloon_hash;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var& operator=(const var p)
|
var& operator=(const var& p)
|
||||||
{
|
{
|
||||||
type=p.type;
|
type=p.type;
|
||||||
number=p.number;
|
number=p.number;
|
||||||
|
|
|
@ -3,6 +3,7 @@ int main()
|
||||||
{
|
{
|
||||||
resource_file prog;
|
resource_file prog;
|
||||||
balloon_lexer lex;
|
balloon_lexer lex;
|
||||||
|
balloon_parse pas;
|
||||||
std::string command;
|
std::string command;
|
||||||
std::cout<<">> Balloon interpreter by ValKmjolnir"<<std::endl;
|
std::cout<<">> Balloon interpreter by ValKmjolnir"<<std::endl;
|
||||||
std::cout<<">> Input [help] to find help."<<std::endl;
|
std::cout<<">> Input [help] to find help."<<std::endl;
|
||||||
|
@ -49,10 +50,25 @@ int main()
|
||||||
{
|
{
|
||||||
lex.scanner(prog.get_resource());
|
lex.scanner(prog.get_resource());
|
||||||
lex.generate_detail_token();
|
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")
|
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")
|
else if(command=="run")
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue