Browse Source

Build dependency tree

test
Michael Uleysky 9 years ago
parent
commit
72c98542e0
  1. 107
      src/globals.cpp
  2. 31
      src/globals.h
  3. 6
      src/init.cpp
  4. 2
      src/init.h
  5. 25
      src/main.cpp
  6. 23
      src/object.h

107
src/globals.cpp

@ -7,10 +7,10 @@ std::map<std::string,ObjectBase*> G_vars;
std::multimap<std::string,Func> G_funcs;
// List of objects to save
std::list<ObjectList*> G_tosave;
std::vector<ObjectList*> G_tosave;
// List of objects to print
std::list<ObjectList*> G_toprint;
std::vector<ObjectList*> G_toprint;
void ClearGlobals()
{
@ -26,4 +26,105 @@ void ClearGlobals()
void RegisterFunction(const std::string& name, Func func)
{
G_funcs.emplace(name,func);
}
}
int DepTree::CreateNodeFromVar(const std::string& var, std::set<std::string>& used)
{
if(G_vars.count(var)==0)
{
COUT(ERROR)<<"Definition of variable "<<var<<" not found."<<std::endl;
return 1;
}
std::vector<std::string> ids;
used.insert(var);
G_vars[var]->UsedIdents(ids);
type=DepTree::VAR;
name=var;
nchild=ids.size();
COUT(DEBUG)<<ids.size()<<std::endl;
if(nchild!=0)
{
childrens=new DepTree*[nchild];
for(unsigned int i=0;i<nchild;i++) {childrens[i]=new DepTree; childrens[i]->parent=this;}
for(unsigned int i=0;i<nchild;i++)
{
int ret;
ret=childrens[i]->CreateNodeFromVar(ids[i],used);
if(ret!=0)
{
COUT(ERROR)<<" in definition of variable "<<var<<"."<<std::endl;
return ret;
}
}
}
return 0;
}
int DepTree::CreateNodeFromSP(DepTree::NodeType list, std::vector<ObjectList*>::size_type ind, std::set<std::string>& used)
{
if(list!=DepTree::SAVE && list!=DepTree::PRINT)
{
COUT(ERROR)<<"Internal error, incorrect NodeType in DepTree::CreateNodeFromSP()."<<std::endl;
return 2;
}
std::vector<std::string> 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;i<nchild;i++) {childrens[i]=new DepTree; childrens[i]->parent=this;}
for(unsigned int i=0;i<nchild;i++)
{
int ret;
ret=childrens[i]->CreateNodeFromVar(ids[i],used);
if(ret!=0)
{
COUT(ERROR)<<" in print/save directive "<<G_toprint[index]->Dump()<<"."<<std::endl;
return ret;
}
}
}
return 0;
}
int DepTree::CreateGlobalTree(std::set<std::string>& used)
{
if(parent!=0)
{
COUT(ERROR)<<"Internal error, DepTree::CreateGlobalTree() call for non-root node."<<std::endl;
return 2;
}
unsigned int i,j;
int ret;
type=DepTree::ROOT;
nchild=G_toprint.size()+G_tosave.size();
if(nchild!=0) childrens=new DepTree*[nchild];
for(i=0;i<nchild;i++) {childrens[i]=new DepTree; childrens[i]->parent=this;}
i=0;
for(j=0;j<G_tosave.size();j++)
{
ret=childrens[i++]->CreateNodeFromSP(DepTree::SAVE,j,used);
if(ret!=0) return ret;
}
for(j=0;j<G_toprint.size();j++)
{
ret=childrens[i++]->CreateNodeFromSP(DepTree::PRINT,j,used);
if(ret!=0) return ret;
}
return 0;
}

31
src/globals.h

@ -1,7 +1,7 @@
#ifndef GLOBALS_H
#define GLOBALS_H
#include <map>
#include <list>
#include <vector>
#include <string>
#include "object.h"
@ -13,14 +13,39 @@ typedef ObjectBase* (*Func)(ObjectList*);
extern EXPORT std::multimap<std::string,Func> G_funcs;
// List of objects to save
extern EXPORT std::list<ObjectList*> EXPORT G_tosave;
extern EXPORT std::vector<ObjectList*> EXPORT G_tosave;
// List of objects to print
extern EXPORT std::list<ObjectList*> EXPORT G_toprint;
extern EXPORT std::vector<ObjectList*> 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<ObjectList*>::size_type index;
std::string name;
int CreateNodeFromVar(const std::string& var, std::set<std::string>& used);
int CreateNodeFromSP(NodeType list, std::vector<ObjectList*>::size_type ind, std::set<std::string>& 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<nchild; i++) delete childrens[i];
delete[] childrens;
}
int CreateGlobalTree(std::set<std::string>& used);
};
#endif

6
src/init.cpp

@ -47,3 +47,9 @@ int RegisterArifmeticFunctions()
RegisterFunction("NEG",Arifm_Neg);
return 0;
}
int BuildDepTree(DepTree* deptree,std::set<std::string>& used)
{
return deptree->CreateGlobalTree(used);
}

2
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<std::string>& used);
#endif

25
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 "<<argv[1]<<" ";
ret=ParseConfigFile(argv[1]); if(ret!=0) { ClearGlobals(); return 1;}
COUT(INFO)<<"Ok"<<std::endl;
if(G_tosave.size()==0 && G_toprint.size()==0)
{
COUT(INFO)<<"No actions needed, exiting"<<std::endl;
ClearGlobals();
return 0;
}
{
std::set<std::string> 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"<<std::endl;
COUT(INFO)<<"Remove unneeded definitions: ";
for(auto& i:all) if(used.count(i)==0) { delete G_vars[i]; G_vars.erase(i);};
COUT(INFO)<<(tot-G_vars.size())<<" removed, "<<G_vars.size()<<" remains."<<std::endl;
}
RegisterArifmeticFunctions();
COUT(INFO)<<G_vars.size()<<std::endl;
for(auto& i: G_vars) COUT(INFO)<<i.first<<"="+i.second->Dump()<<";"<<std::endl;
ClearGlobals();
delete DPTree;
return 0;
}

23
src/object.h

@ -6,6 +6,7 @@
#include <inttypes.h>
#include <vector>
#include <sstream>
#include <set>
#include <typeinfo>
#include <typeindex>
#include "debug.h"
@ -64,6 +65,8 @@ public:
return true;
}
virtual std::string Dump() const {return "%"+Type()+"%";}
virtual void UsedFuncs(std::vector<std::string>& funcs) const {}
virtual void UsedIdents(std::vector<std::string>& 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<std::string>& funcs) const override {return val->UsedFuncs(funcs);}
void UsedIdents(std::vector<std::string>& 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<std::string>& funcs) const override {for(auto& i: vals) i->UsedFuncs(funcs);}
void UsedIdents(std::vector<std::string>& 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<std::string>& 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<std::string>& funcs) const override {funcs.push_back(name); args->UsedFuncs(funcs);}
void UsedIdents(std::vector<std::string>& ids) const override {args->UsedIdents(ids);}
};
#endif

Loading…
Cancel
Save