This commit is contained in:
Valk Richard Li 2019-11-04 23:31:04 +08:00 committed by GitHub
parent 93eb59ef34
commit c2ebe97ff7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 114 additions and 65 deletions

View File

@ -5,35 +5,40 @@ class abstract_syntax_tree
{ {
private: private:
int type; int type;
double var_number; double number;
std::string var_string; std::string str;
std::string var_name; std::string name;
std::list<abstract_syntax_tree> children; std::list<abstract_syntax_tree> children;
public: public:
abstract_syntax_tree() abstract_syntax_tree()
{ {
type=0; type=0;
var_number=0; number=0;
var_string=""; str="";
var_name=""; 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;
var_number=p.var_number; number=p.number;
var_string=p.var_string; str=p.str;
var_name=p.var_name; name=p.name;
children=p.children; children=p.children;
return; return;
} }
~abstract_syntax_tree()
{
children.clear();
return;
}
abstract_syntax_tree& operator=(const abstract_syntax_tree& p) abstract_syntax_tree& operator=(const abstract_syntax_tree& p)
{ {
type=p.type; type=p.type;
var_number=p.var_number; number=p.number;
var_string=p.var_string; str=p.str;
var_name=p.var_name; name=p.name;
children.clear(); children.clear();
children=p.children; children=p.children;
return *this; return *this;
@ -41,27 +46,27 @@ class abstract_syntax_tree
void set_clear() void set_clear()
{ {
type=0; type=0;
var_number=0; number=0;
var_string=""; str="";
var_name=""; name="";
children.clear(); children.clear();
return; return;
} }
void print_tree(const int n) void print_tree(const int n)
{ {
std::string str=""; std::string _str="";
for(int i=0;i<n;++i) for(int i=0;i<n;++i)
str+="| "; _str+="| ";
std::cout<<str; std::cout<<_str;
print_detail_token(type); print_detail_token(type);
switch(type) switch(type)
{ {
case __number:std::cout<<": "<<var_number;break; case __number:std::cout<<": "<<number;break;
case __string:std::cout<<": "<<var_string;break; case __string:std::cout<<": "<<str;break;
case __id: case __id:
case __call_array: case __call_array:
case __call_hash: case __call_hash:
case __call_function:std::cout<<": "<<var_name;break; case __call_function:std::cout<<": "<<name;break;
} }
std::cout<<std::endl; std::cout<<std::endl;
if(!children.empty()) if(!children.empty())
@ -76,87 +81,87 @@ class abstract_syntax_tree
type=_type; type=_type;
return; return;
} }
void set_string(std::string str) void set_string(std::string _str)
{ {
var_string=str; str=_str;
return; return;
} }
void set_number(std::string str) void set_number(std::string _str)
{ {
if(str=="nil") if(_str=="nil")
{ {
var_number=0; number=0;
return; return;
} }
if((int)str.length()>2 && (str[1]=='x' || str[1]=='o')) if((int)_str.length()>2 && (_str[1]=='x' || _str[1]=='o'))
{ {
if(str[1]=='x') if(_str[1]=='x')
{ {
int num=0; double num=0;
int pw=1; double pw=1;
for(int i=(int)str.length()-1;i>1;--i) for(int i=(int)_str.length()-1;i>1;--i)
{ {
if('0'<=str[i] && str[i]<='9') if('0'<=_str[i] && _str[i]<='9')
num+=(str[i]-'0')*pw; num+=(_str[i]-'0')*pw;
else if('a'<=str[i] && str[i]<='f') else if('a'<=_str[i] && _str[i]<='f')
num+=(10+str[i]-'a')*pw; num+=(10+_str[i]-'a')*pw;
else if('A'<=str[i] && str[i]<='F') else if('A'<=_str[i] && _str[i]<='F')
num+=(10+str[i]-'A')*pw; num+=(10+_str[i]-'A')*pw;
pw<<=4; pw*=16;
} }
var_number=(double)num; number=num;
} }
else else
{ {
int num=0; double num=0;
int pw=1; double pw=1;
for(int i=(int)str.length()-1;i>1;--i) for(int i=(int)_str.length()-1;i>1;--i)
{ {
num+=(str[i]-'0')*pw; num+=(_str[i]-'0')*pw;
pw<<=3; pw*=8;
} }
var_number=(double)num; number=num;
} }
return; return;
} }
int dot_place=-1; int dot_place=-1;
for(int i=0;i<(int)str.length();++i) for(int i=0;i<(int)_str.length();++i)
if(str[i]=='.') if(_str[i]=='.')
{ {
dot_place=i; dot_place=i;
break; break;
} }
if(dot_place==-1) if(dot_place==-1)
{ {
var_number=0; number=0;
double pw=1; double pw=1;
for(int i=(int)str.length()-1;i>=0;--i) for(int i=(int)_str.length()-1;i>=0;--i)
{ {
var_number+=(str[i]-'0')*pw; number+=(_str[i]-'0')*pw;
pw*=10; pw*=10;
} }
} }
else else
{ {
var_number=0; number=0;
double pw=0.1; double pw=0.1;
for(int i=dot_place+1;i<(int)str.length();++i) for(int i=dot_place+1;i<(int)_str.length();++i)
{ {
var_number+=(str[i]-'0')*pw; number+=(_str[i]-'0')*pw;
pw/=10; pw/=10;
} }
pw=1; pw=1;
for(int i=dot_place-1;i>=0;--i) for(int i=dot_place-1;i>=0;--i)
{ {
var_number+=(str[i]-'0')*pw; number+=(_str[i]-'0')*pw;
pw*=10; pw*=10;
} }
} }
return; return;
} }
void set_name(std::string& str) void set_name(std::string _str)
{ {
var_name=str; name=_str;
return; return;
} }
void add_child(abstract_syntax_tree p) void add_child(abstract_syntax_tree p)
@ -170,15 +175,15 @@ class abstract_syntax_tree
} }
double get_number() double get_number()
{ {
return var_number; return number;
} }
std::string get_string() std::string get_string()
{ {
return var_string; return str;
} }
std::string get_name() std::string get_name()
{ {
return var_name; return name;
} }
std::list<abstract_syntax_tree>& get_children() std::list<abstract_syntax_tree>& get_children()
{ {

View File

@ -88,7 +88,10 @@ class resource_file
c=fin.get(); c=fin.get();
if(fin.eof()) if(fin.eof())
break; break;
if(0<=c && c<128)
resource.push_back(c); resource.push_back(c);
else
resource.push_back(' ');
} }
resource.push_back('\n'); resource.push_back('\n');
return; return;
@ -103,6 +106,7 @@ class resource_file
std::cout<<line<<" "; std::cout<<line<<" ";
for(std::list<char>::iterator i=resource.begin();i!=resource.end();++i) for(std::list<char>::iterator i=resource.begin();i!=resource.end();++i)
{ {
if(32<=*i && *i<128 || *i=='\n')
std::cout<<*i; std::cout<<*i;
if(*i=='\n') if(*i=='\n')
{ {
@ -163,7 +167,7 @@ class balloon_lexer
int line=1; int line=1;
std::string token_str; std::string token_str;
std::list<char>::iterator ptr=res.begin(); std::list<char>::iterator ptr=res.begin();
while(1) while(ptr!=res.end())
{ {
while(*ptr==' ' || *ptr=='\n' || *ptr=='\t' || *ptr=='\r' || *ptr<0 || *ptr>127) while(*ptr==' ' || *ptr=='\n' || *ptr=='\t' || *ptr=='\r' || *ptr<0 || *ptr>127)
{ {
@ -318,6 +322,12 @@ class balloon_lexer
if(ptr==res.end()) if(ptr==res.end())
break; break;
} }
else
{
++error;
std::cout<<">>[Lexer-error] line "<<line<<": unknown char."<<std::endl;
++ptr;
}
} }
std::cout<<">>[Lexer] complete scanning."<<error<<" error(s)."<<std::endl; std::cout<<">>[Lexer] complete scanning."<<error<<" error(s)."<<std::endl;
return; return;

View File

@ -8,6 +8,7 @@ class balloon_parse
token this_token; token this_token;
int error; int error;
int warning; int warning;
abstract_syntax_tree root;
public: public:
void get_token() void get_token()
{ {
@ -22,6 +23,7 @@ class balloon_parse
} }
void get_detail_token_stream(std::list<token>& tk_list) void get_detail_token_stream(std::list<token>& tk_list)
{ {
root.set_clear();
while(!parse.empty()) while(!parse.empty())
parse.pop(); parse.pop();
if(tk_list.empty()) if(tk_list.empty())
@ -63,7 +65,39 @@ class balloon_parse
std::cout<<std::endl; std::cout<<std::endl;
return; return;
} }
int get_error()
{
return error;
}
void parse_main();
}; };
void balloon_parse::parse_main()
{
root.set_type(__root);
error=0;
warning=0;
while(!parse.empty())
{
get_token();
switch(this_token.type)
{
case __var:parse.push(this_token);break;
case __number:
case __string:parse.push(this_token);break;
case __id:parse.push(this_token);break;
case __if:parse.push(this_token);break;
case __while:parse.push(this_token);break;
default:
++error;
std::cout<<">>[Parse-error] line "<<this_token.line<<": ";
print_detail_token(this_token.type);
std::cout<<" should not appear in this scope."<<std::endl;
break;
}
}
std::cout<<">>[Parse] complete generating."<<error<<" error(s),"<<warning<<" warning(s)."<<std::endl;
return;
}
#endif #endif