From 72c98542e0dcbed98ccd9846c6876cb337c74182 Mon Sep 17 00:00:00 2001 From: Michael Uleysky Date: Wed, 2 Sep 2015 16:13:05 +1000 Subject: [PATCH] Build dependency tree --- src/globals.cpp | 107 ++++++++++++++++++++++++++++++++++++++++++++++-- src/globals.h | 31 ++++++++++++-- src/init.cpp | 6 +++ src/init.h | 2 + src/main.cpp | 25 +++++++++++ src/object.h | 23 +++++++++-- 6 files changed, 185 insertions(+), 9 deletions(-) diff --git a/src/globals.cpp b/src/globals.cpp index d1e3686..6962fbc 100644 --- a/src/globals.cpp +++ b/src/globals.cpp @@ -7,10 +7,10 @@ std::map G_vars; std::multimap G_funcs; // List of objects to save -std::list G_tosave; +std::vector G_tosave; // List of objects to print -std::list G_toprint; +std::vector G_toprint; void ClearGlobals() { @@ -26,4 +26,105 @@ void ClearGlobals() void RegisterFunction(const std::string& name, Func func) { G_funcs.emplace(name,func); -} \ No newline at end of file +} + +int DepTree::CreateNodeFromVar(const std::string& var, std::set& used) +{ + if(G_vars.count(var)==0) + { + COUT(ERROR)<<"Definition of variable "< ids; + + used.insert(var); + G_vars[var]->UsedIdents(ids); + type=DepTree::VAR; + name=var; + nchild=ids.size(); + COUT(DEBUG)<parent=this;} + for(unsigned int i=0;iCreateNodeFromVar(ids[i],used); + if(ret!=0) + { + COUT(ERROR)<<" in definition of variable "<::size_type ind, std::set& used) +{ + if(list!=DepTree::SAVE && list!=DepTree::PRINT) + { + COUT(ERROR)<<"Internal error, incorrect NodeType in DepTree::CreateNodeFromSP()."< ids; + + type=list; + index=ind; + + if(type==DepTree::SAVE) G_tosave[index]->UsedIdents(ids); + else if(type==DepTree::PRINT) G_toprint[index]->UsedIdents(ids); + nchild=ids.size(); + if(nchild!=0) + { + childrens=new DepTree*[nchild]; + for(unsigned int i=0;iparent=this;} + for(unsigned int i=0;iCreateNodeFromVar(ids[i],used); + if(ret!=0) + { + COUT(ERROR)<<" in print/save directive "<Dump()<<"."<& used) +{ + if(parent!=0) + { + COUT(ERROR)<<"Internal error, DepTree::CreateGlobalTree() call for non-root node."<parent=this;} + i=0; + for(j=0;jCreateNodeFromSP(DepTree::SAVE,j,used); + if(ret!=0) return ret; + } + for(j=0;jCreateNodeFromSP(DepTree::PRINT,j,used); + if(ret!=0) return ret; + } + + return 0; +} diff --git a/src/globals.h b/src/globals.h index 0b8c5c1..395fd81 100644 --- a/src/globals.h +++ b/src/globals.h @@ -1,7 +1,7 @@ #ifndef GLOBALS_H #define GLOBALS_H #include -#include +#include #include #include "object.h" @@ -13,14 +13,39 @@ typedef ObjectBase* (*Func)(ObjectList*); extern EXPORT std::multimap G_funcs; // List of objects to save -extern EXPORT std::list EXPORT G_tosave; +extern EXPORT std::vector EXPORT G_tosave; // List of objects to print -extern EXPORT std::list EXPORT G_toprint; +extern EXPORT std::vector EXPORT G_toprint; void ClearGlobals(); extern "C" { EXPORT void RegisterFunction(const std::string& name, Func func); } + +class DepTree +{ + enum NodeType {NOTDEF,ROOT,SAVE,PRINT,VAR}; + + DepTree* parent; + unsigned int nchild; + DepTree** childrens; + NodeType type; + std::vector::size_type index; + std::string name; + + int CreateNodeFromVar(const std::string& var, std::set& used); + int CreateNodeFromSP(NodeType list, std::vector::size_type ind, std::set& used); +public: + DepTree():parent(0),nchild(0),childrens(0),type(DepTree::NOTDEF) {} + DepTree(const DepTree&) = delete; + ~DepTree() + { + if(childrens!=0) for(unsigned int i=0; i& used); +}; #endif diff --git a/src/init.cpp b/src/init.cpp index 4a7ae58..44b96c9 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -47,3 +47,9 @@ int RegisterArifmeticFunctions() RegisterFunction("NEG",Arifm_Neg); return 0; } + + +int BuildDepTree(DepTree* deptree,std::set& used) +{ + return deptree->CreateGlobalTree(used); +} diff --git a/src/init.h b/src/init.h index 10b2e51..df124d2 100644 --- a/src/init.h +++ b/src/init.h @@ -4,8 +4,10 @@ #define YY_TYPEDEF_YY_SCANNER_T typedef void* yyscan_t; #endif +#include "globals.h" int ParseConfigFile(char* config); int RegisterArifmeticFunctions(); +int BuildDepTree(DepTree* deptree, std::set& used); #endif diff --git a/src/main.cpp b/src/main.cpp index ac754ee..2a83dda 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,18 +6,43 @@ int main(int argc, char** argv) { if(argc!=2) return 1; int ret; + DepTree* DPTree; SetDebugLevel(INFO); COUT(INFO)<<"Parse config file "< used, all; + for(auto& i:G_vars) all.insert(i.first); + unsigned int tot=G_vars.size(); + + DPTree=new DepTree; + COUT(INFO)<<"Building dependency tree "; + ret=BuildDepTree(DPTree,used); if(ret!=0) { ClearGlobals(); delete DPTree; return 1;} + COUT(INFO)<<"Ok"< #include #include +#include #include #include #include "debug.h" @@ -64,6 +65,8 @@ public: return true; } virtual std::string Dump() const {return "%"+Type()+"%";} + virtual void UsedFuncs(std::vector& funcs) const {} + virtual void UsedIdents(std::vector& ids) const {} }; // Template for objects without specific constructor/destructor @@ -148,6 +151,8 @@ public: const ObjectBase* Value() const {return val;} void SetPair(const std::string& n, ObjectBase* v) {if(!Exist()) {name=n; val=v;}} std::string Dump() const override { return Name()+"="+val->Dump(); } + void UsedFuncs(std::vector& funcs) const override {return val->UsedFuncs(funcs);} + void UsedIdents(std::vector& ids) const override {return val->UsedIdents(ids);} }; // Class for objects list @@ -184,20 +189,30 @@ public: if(vals.size()!=0) s.resize(s.length()-2); return s+")"; } + void UsedFuncs(std::vector& funcs) const override {for(auto& i: vals) i->UsedFuncs(funcs);} + void UsedIdents(std::vector& ids) const override {for(auto& i: vals) i->UsedIdents(ids);} }; // Class for storing identifiers class OId: public ObjectBase { std::string name; + std::string fullname; + + void ParseName(const std::string& s) + { + fullname=s; + name=s.substr(0,s.find_first_of('.')); + } public: - OId(const std::string* t):name(*t) {} + OId(const std::string* t) {ParseName(*t);} ~OId() {} bool Print() const override {return false;} std::string Type() const override {return "IDENT";} std::string Name() const {return name;} - void SetName(std::string s) {name=s;} - std::string Dump() const override {return Name();}; + void SetName(std::string s) {ParseName(s);} + std::string Dump() const override {return fullname;}; + void UsedIdents(std::vector& ids) const override {ids.push_back(name);} }; // Class for storing functions @@ -222,6 +237,8 @@ public: std::string Name() const {return name;} void SetName(std::string s) {name=s;} std::string Dump() const override {return Name()+args->Dump();}; + void UsedFuncs(std::vector& funcs) const override {funcs.push_back(name); args->UsedFuncs(funcs);} + void UsedIdents(std::vector& ids) const override {args->UsedIdents(ids);} }; #endif