Update abstract syntax tree

This commit is contained in:
Valk Richard Li 2019-09-08 15:36:21 +08:00 committed by GitHub
parent 97f494c2a7
commit 882bbb2c47
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 316 additions and 27 deletions

View File

@ -1,15 +1,215 @@
#ifndef __ABSTRACT_SYNTAX_TREE_H__
#define __ABSTRACT_SYNTAX_TREE_H__
#include "token_type.h"
#include <iostream>
#include <cstring>
#include <list>
#include <stack>
class ast_tree
enum node_type
{
private:
__root=1,
__subtree,
__leaf,
__numbernode,
__stringnode,
__operator,
__calculation,
};
void print_node_type(int type)
{
std::string str="";
switch(type)
{
case __root:str="root";break;
case __subtree:str="subtree";break;
case __leaf:str="leaf";break;
case __numbernode:str="number";break;
case __stringnode:str="string";break;
case __operator:str="operator";break;
case __calculation:str="calc";break;
}
std::cout<<str;
return;
}
class ASTree
{
protected:
int line;
int type;
std::list<ASTree> children;
public:
ASTree()
{
line=0;
type=__root;
children.clear();
}
virtual std::list<ASTree>& return_child()
{
return children;
}
virtual void set_data(int _line,int _type)
{
line=_line;
type=_type;
return;
}
void print_tree()
{
if(type==__leaf || type==__number || type==__string)
{
std::cout<<"( ";
print_token(type);
std::cout<<" )";
return;
}
std::cout<<"( ";
print_node_type(type);
std::cout<<" ";
for(std::list<ASTree>::iterator i=children.begin();i!=children.end();++i)
{
i->print_tree();
}
std::cout<<" )";
return;
}
virtual int return_type()
{
return type;
}
};
class ASTList:public ASTree
{
public:
ASTList()
{
line=0;
type=__subtree;
children.clear();
}
};
class ASTLeaf:public ASTree
{
public:
ASTLeaf()
{
line=0;
type=__leaf;
children.clear();
}
};
class NumberNode:public ASTLeaf
{
private:
long long int number;
double fnumber;
bool isFloat;
public:
NumberNode()
{
line=0;
type=__numbernode;
number=0;
fnumber=0;
isFloat=false;
children.clear();
}
void setnumber(std::string& str)
{
isFloat=false;
int DotPlace=0;
for(int i=0;i<(int)str.length();++i)
if(str[i]=='.')
{
isFloat=true;
DotPlace=i;
break;
}
if(!isFloat)
{
number=0;
long long int acc=1;
for(int i=(int)str.length()-1;i>=0;--i)
{
number+=acc*((long long int)(str[i]-'0'));
acc*=10;
}
}
else
{
fnumber=0;
double acc=1;
double aff=0.1;
for(int i=DotPlace+1;i<(int)str.length();++i)
{
fnumber+=aff*((double)(str[i]-'0'));
aff*=0.1;
}
for(int i=DotPlace-1;i>=0;--i)
{
fnumber+=acc*((double)(str[i]-'0'));
acc*=10;
}
}
return;
}
};
class StringNode:public ASTLeaf
{
private:
std::string str;
public:
StringNode()
{
line=0;
type=__stringnode;
str="";
children.clear();
}
};
class OperatorNode:public ASTList
{
private:
int operator_type;
public:
OperatorNode()
{
line=0;
type=__operator;
operator_type=0;
children.clear();
}
void set_operator_type(std::string& str)
{
char c=str[0];
switch(c)
{
case '+':operator_type=__add_operator;break;
case '-':operator_type=__sub_operator;break;
case '*':operator_type=__mul_operator;break;
case '/':operator_type=__div_operator;break;
case '~':operator_type=__link_operator;break;
}
return;
}
};
class CalculationNode:public ASTList
{
public:
CalculationNode()
{
line=0;
type=__calculation;
children.clear();
}
};
#endif

View File

@ -0,0 +1,81 @@
#ifndef __CODE_GENERATOR_H__
#define __CODE_GENERATOR_H__
#include "nasal_parser.h"
#include "abstract_syntax_tree.h"
#include <stack>
class code_generator
{
private:
ASTree root;
std::stack<ASTree> node_stack;
std::stack<parse_unit> temp;
public:
code_generator()
{
root.set_data(0,__root);
}
void number_node_gen()
{
NumberNode t;
t.setnumber(temp.top().content);
t.set_data(temp.top().line,__number);
if(node_stack.empty())
node_stack.push(t);
else if(node_stack.top().return_type()==__operator)
node_stack.top().return_child().push_back(t);
else
node_stack.push(t);
return;
}
void operator_node_gen()
{
OperatorNode t;
t.set_operator_type(temp.top().content);
t.set_data(temp.top().line,__operator);
if(node_stack.empty())
{
std::cout<<"line "<<temp.top().line<<":parse error.\n";
return;
}
if(node_stack.top().return_type()==__number || node_stack.top().return_type()==__operator)
{
t.return_child().push_back(node_stack.top());
node_stack.pop();
node_stack.push(t);
}
return;
}
void run()
{
root.print_tree();
std::cout<<std::endl;
return;
}
void stack_input(std::stack<parse_unit>& parse)
{
while(!node_stack.empty())
node_stack.pop();
temp=parse;
while(!temp.empty())
{
switch(temp.top().type)
{
case __number:number_node_gen();break;
case __add_operator:operator_node_gen();break;
case __sub_operator:operator_node_gen();break;
default:std::cout<<"line "<<temp.top().line<<":parse error.\n";break;
}
temp.pop();
}
while(!node_stack.empty())
{
root.return_child().push_back(node_stack.top());
node_stack.pop();
}
return;
}
};
#endif

View File

@ -1,5 +1,7 @@
#include "nasal_lexer.h"
#include "nasal_parser.h"
#include "abstract_syntax_tree.h"
#include "code_generator.h"
#include <iostream>
#include <cstring>
@ -8,6 +10,7 @@ int main()
resource_programme_process prog;
nasal_lexer lex;
nasal_parser pas;
code_generator cod;
std::string command;
std::cout<<">> Nasal interpreter by ValKmjolnir"<<std::endl;
std::cout<<">> input [help] to find help."<<std::endl;
@ -59,6 +62,8 @@ int main()
{
lex.lexer_process(prog.use_file());
pas.parse_process(lex.return_list());
cod.stack_input(pas.return_stack());
cod.run();
}
else
prog.input_file(command);

View File

@ -18,7 +18,6 @@ class nasal_parser
{
private:
std::stack<parse_unit> parser;
//abstract_syntax_tree ast;
public:
void print_parser_stack()
{
@ -59,6 +58,10 @@ class nasal_parser
{
return;
}
std::stack<parse_unit>& return_stack()
{
return parser;
}
void parse_process(std::list<token>& lexer)
{
while(!parser.empty())
@ -191,27 +194,24 @@ class nasal_parser
parser.push(temp.top());
temp.pop();
}
std::list<int> error_list;
error_list.clear();
//ast.init_parser_stack(parser);
//ast.tree_generator(error_list);
if(error_list.empty())
{
std::cout<<">>[Parse] 0 error(s)."<<std::endl;
std::cout<<">>[Parse] Complete checking."<<std::endl;
//ast.run();
}
else
{
int line=0;
for(std::list<int>::iterator i=error_list.begin();i!=error_list.end();++i)
if(line!=*i)
{
line=*i;
std::cout<<">>[Parse] parse error in line "<<line<<"."<<std::endl;
}
std::cout<<">>[Parse] Error occurred, stop."<<std::endl;
}
// std::list<int> error_list;
// error_list.clear();
// if(error_list.empty())
// {
// std::cout<<">>[Parse] 0 error(s)."<<std::endl;
// std::cout<<">>[Parse] Complete checking."<<std::endl;
// }
// else
// {
// int line=0;
// for(std::list<int>::iterator i=error_list.begin();i!=error_list.end();++i)
// if(line!=*i)
// {
// line=*i;
// std::cout<<">>[Parse] parse error in line "<<line<<"."<<std::endl;
// }
// std::cout<<">>[Parse] Error occurred, stop."<<std::endl;
// }
return;
}
};

View File

@ -4,11 +4,12 @@
class ASTree
{
public:
protected:
int line;
int type;
std::string content;
std::list<ASTree> children;
public:
ASTree()
{
line=0;

View File

@ -0,0 +1,2 @@
1+1+1-123-213+1-1-1-2-32-13-423-24-24+213+12312