From 882bbb2c473d4b448fe8d97cb9c5e1d49b5671a4 Mon Sep 17 00:00:00 2001 From: Valk Richard Li <48872266+ValKmjolnir@users.noreply.github.com> Date: Sun, 8 Sep 2019 15:36:21 +0800 Subject: [PATCH] Update abstract syntax tree --- .../version0.15.1/abstract_syntax_tree.h | 208 +++++++++++++++++- version0.15/version0.15.1/code_generator.h | 81 +++++++ version0.15/version0.15.1/main.cpp | 5 + version0.15/version0.15.1/nasal_parser.h | 44 ++-- version0.15/version0.15.1/test.cpp | 3 +- version0.15/version0.15.1/test.txt | 2 + 6 files changed, 316 insertions(+), 27 deletions(-) create mode 100644 version0.15/version0.15.1/code_generator.h create mode 100644 version0.15/version0.15.1/test.txt diff --git a/version0.15/version0.15.1/abstract_syntax_tree.h b/version0.15/version0.15.1/abstract_syntax_tree.h index f54a945..9306e84 100644 --- a/version0.15/version0.15.1/abstract_syntax_tree.h +++ b/version0.15/version0.15.1/abstract_syntax_tree.h @@ -1,15 +1,215 @@ #ifndef __ABSTRACT_SYNTAX_TREE_H__ #define __ABSTRACT_SYNTAX_TREE_H__ +#include "token_type.h" #include #include #include -#include -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< children; + public: + ASTree() + { + line=0; + type=__root; + children.clear(); + } + virtual std::list& 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::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 diff --git a/version0.15/version0.15.1/code_generator.h b/version0.15/version0.15.1/code_generator.h new file mode 100644 index 0000000..368d5b0 --- /dev/null +++ b/version0.15/version0.15.1/code_generator.h @@ -0,0 +1,81 @@ +#ifndef __CODE_GENERATOR_H__ +#define __CODE_GENERATOR_H__ + +#include "nasal_parser.h" +#include "abstract_syntax_tree.h" +#include + +class code_generator +{ + private: + ASTree root; + std::stack node_stack; + std::stack 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 "<& 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 "< #include @@ -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"<> input [help] to find help."< parser; - //abstract_syntax_tree ast; public: void print_parser_stack() { @@ -59,6 +58,10 @@ class nasal_parser { return; } + std::stack& return_stack() + { + return parser; + } void parse_process(std::list& lexer) { while(!parser.empty()) @@ -191,27 +194,24 @@ class nasal_parser parser.push(temp.top()); temp.pop(); } - std::list 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)."<>[Parse] Complete checking."<::iterator i=error_list.begin();i!=error_list.end();++i) - if(line!=*i) - { - line=*i; - std::cout<<">>[Parse] parse error in line "<>[Parse] Error occurred, stop."< error_list; +// error_list.clear(); +// if(error_list.empty()) +// { +// std::cout<<">>[Parse] 0 error(s)."<>[Parse] Complete checking."<::iterator i=error_list.begin();i!=error_list.end();++i) +// if(line!=*i) +// { +// line=*i; +// std::cout<<">>[Parse] parse error in line "<>[Parse] Error occurred, stop."< children; + public: ASTree() { line=0; diff --git a/version0.15/version0.15.1/test.txt b/version0.15/version0.15.1/test.txt new file mode 100644 index 0000000..66e8831 --- /dev/null +++ b/version0.15/version0.15.1/test.txt @@ -0,0 +1,2 @@ +1+1+1-123-213+1-1-1-2-32-13-423-24-24+213+12312 +