Update abstract syntax tree
This commit is contained in:
parent
97f494c2a7
commit
882bbb2c47
|
@ -1,15 +1,215 @@
|
||||||
#ifndef __ABSTRACT_SYNTAX_TREE_H__
|
#ifndef __ABSTRACT_SYNTAX_TREE_H__
|
||||||
#define __ABSTRACT_SYNTAX_TREE_H__
|
#define __ABSTRACT_SYNTAX_TREE_H__
|
||||||
|
|
||||||
|
#include "token_type.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <list>
|
#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
|
#endif
|
||||||
|
|
|
@ -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
|
|
@ -1,5 +1,7 @@
|
||||||
#include "nasal_lexer.h"
|
#include "nasal_lexer.h"
|
||||||
#include "nasal_parser.h"
|
#include "nasal_parser.h"
|
||||||
|
#include "abstract_syntax_tree.h"
|
||||||
|
#include "code_generator.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
@ -8,6 +10,7 @@ int main()
|
||||||
resource_programme_process prog;
|
resource_programme_process prog;
|
||||||
nasal_lexer lex;
|
nasal_lexer lex;
|
||||||
nasal_parser pas;
|
nasal_parser pas;
|
||||||
|
code_generator cod;
|
||||||
std::string command;
|
std::string command;
|
||||||
std::cout<<">> Nasal interpreter by ValKmjolnir"<<std::endl;
|
std::cout<<">> Nasal interpreter by ValKmjolnir"<<std::endl;
|
||||||
std::cout<<">> input [help] to find help."<<std::endl;
|
std::cout<<">> input [help] to find help."<<std::endl;
|
||||||
|
@ -59,6 +62,8 @@ int main()
|
||||||
{
|
{
|
||||||
lex.lexer_process(prog.use_file());
|
lex.lexer_process(prog.use_file());
|
||||||
pas.parse_process(lex.return_list());
|
pas.parse_process(lex.return_list());
|
||||||
|
cod.stack_input(pas.return_stack());
|
||||||
|
cod.run();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
prog.input_file(command);
|
prog.input_file(command);
|
||||||
|
|
|
@ -18,7 +18,6 @@ class nasal_parser
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::stack<parse_unit> parser;
|
std::stack<parse_unit> parser;
|
||||||
//abstract_syntax_tree ast;
|
|
||||||
public:
|
public:
|
||||||
void print_parser_stack()
|
void print_parser_stack()
|
||||||
{
|
{
|
||||||
|
@ -59,6 +58,10 @@ class nasal_parser
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
std::stack<parse_unit>& return_stack()
|
||||||
|
{
|
||||||
|
return parser;
|
||||||
|
}
|
||||||
void parse_process(std::list<token>& lexer)
|
void parse_process(std::list<token>& lexer)
|
||||||
{
|
{
|
||||||
while(!parser.empty())
|
while(!parser.empty())
|
||||||
|
@ -191,27 +194,24 @@ class nasal_parser
|
||||||
parser.push(temp.top());
|
parser.push(temp.top());
|
||||||
temp.pop();
|
temp.pop();
|
||||||
}
|
}
|
||||||
std::list<int> error_list;
|
// std::list<int> error_list;
|
||||||
error_list.clear();
|
// error_list.clear();
|
||||||
//ast.init_parser_stack(parser);
|
// if(error_list.empty())
|
||||||
//ast.tree_generator(error_list);
|
// {
|
||||||
if(error_list.empty())
|
// std::cout<<">>[Parse] 0 error(s)."<<std::endl;
|
||||||
{
|
// std::cout<<">>[Parse] Complete checking."<<std::endl;
|
||||||
std::cout<<">>[Parse] 0 error(s)."<<std::endl;
|
// }
|
||||||
std::cout<<">>[Parse] Complete checking."<<std::endl;
|
// else
|
||||||
//ast.run();
|
// {
|
||||||
}
|
// int line=0;
|
||||||
else
|
// for(std::list<int>::iterator i=error_list.begin();i!=error_list.end();++i)
|
||||||
{
|
// if(line!=*i)
|
||||||
int line=0;
|
// {
|
||||||
for(std::list<int>::iterator i=error_list.begin();i!=error_list.end();++i)
|
// line=*i;
|
||||||
if(line!=*i)
|
// std::cout<<">>[Parse] parse error in line "<<line<<"."<<std::endl;
|
||||||
{
|
// }
|
||||||
line=*i;
|
// std::cout<<">>[Parse] Error occurred, stop."<<std::endl;
|
||||||
std::cout<<">>[Parse] parse error in line "<<line<<"."<<std::endl;
|
// }
|
||||||
}
|
|
||||||
std::cout<<">>[Parse] Error occurred, stop."<<std::endl;
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,11 +4,12 @@
|
||||||
|
|
||||||
class ASTree
|
class ASTree
|
||||||
{
|
{
|
||||||
public:
|
protected:
|
||||||
int line;
|
int line;
|
||||||
int type;
|
int type;
|
||||||
std::string content;
|
std::string content;
|
||||||
std::list<ASTree> children;
|
std::list<ASTree> children;
|
||||||
|
public:
|
||||||
ASTree()
|
ASTree()
|
||||||
{
|
{
|
||||||
line=0;
|
line=0;
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
1+1+1-123-213+1-1-1-2-32-13-423-24-24+213+12312
|
||||||
|
|
Loading…
Reference in New Issue