Created a Poset template class. It can store the relationships of a partially ordered set, then generate a topological ordering. It will be used to order the type_def declarations in the CGenerator, as they depend on each other in a poset fashion.

This commit is contained in:
Nathan Braswell
2014-05-21 12:01:45 -04:00
parent 6350f93f24
commit d37a07201a
5 changed files with 124 additions and 10 deletions

118
include/Poset.h Normal file
View File

@@ -0,0 +1,118 @@
#ifndef POSET_H
#define POSET_H
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <cassert>
#include "util.h"
template <class T>
class Poset {
public:
Poset();
~Poset();
void addRelationship(T first, T second);
bool zeroDependencies(T vertex);
std::set<T> getDependsOn(T dependency);
std::vector<T> getTopoSort();
static void test();
private:
//backing data structures
std::map<T, std::map<T,bool>> adjMatrix;
std::set<T> verticies;
};
template <class T>
Poset<T>::Poset() {
//Nothing needed
}
template <class T>
Poset<T>::~Poset() {
//Ditto
}
template <class T>
void Poset<T>::addRelationship(T first, T second) {
verticies.insert(first);
verticies.insert(second);
adjMatrix[first][second] = true;
}
template <class T>
bool Poset<T>::zeroDependencies(T vertex) {
auto depMapItr = adjMatrix.find(vertex);
if (depMapItr == adjMatrix.end())
return true;
for (auto i : depMapItr->second)
if (i.second == true)
return false;
return true;
}
template <class T>
std::set<T> Poset<T>::getDependsOn(T dependency) {
std::set<T> vertsThatDependOn;
for (auto i : adjMatrix) {
auto depItr = i.second.find(dependency);
if (depItr != i.second.end() && depItr->second)
vertsThatDependOn.insert(i.first);
}
return vertsThatDependOn;
}
template <class T>
std::vector<T> Poset<T>::getTopoSort() {
std::vector<T> sorted;
std::queue<T> toDo;
for (auto i : verticies)
if (zeroDependencies(i))
toDo.push(i);
while(!toDo.empty()) {
T current = toDo.front(); toDo.pop();
sorted.push_back(current);
for (T depOnCurrent : getDependsOn(current)) {
adjMatrix[depOnCurrent][current] = false; //Remove the edge to current, since current's now been taken care of
if (zeroDependencies(depOnCurrent))
toDo.push(depOnCurrent);
}
}
return sorted;
}
//int specilization just for testing
template<>
void Poset<int>::test() {
std::string result;
{
Poset<int> poset;
for (int i = 0; i < 20; i++)
poset.addRelationship(i,i+1);
result = "";
for (int i : poset.getTopoSort())
result += intToString(i) + " ";
//std::cout << result << std::endl;
assert(result == "20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 ");
}
{
Poset<int> poset;
for (int i = 0; i < 20; i+=2)
poset.addRelationship(i,i+1);
result = "";
for (int i : poset.getTopoSort())
result += intToString(i) + " ";
//std::cout << result << std::endl;
assert(result == "1 3 5 7 9 11 13 15 17 19 0 2 4 6 8 10 12 14 16 18 ");
}
std::cout << "Poset tests passed" << std::endl;
}
#endif

View File

@@ -14,6 +14,7 @@
#include "Importer.h" #include "Importer.h"
#include "ASTData.h" #include "ASTData.h"
#include "CGenerator.h" #include "CGenerator.h"
#include "Poset.h"
#include "util.h" #include "util.h"
#include "Tester.h" #include "Tester.h"
@@ -27,6 +28,8 @@ int main(int argc, char* argv[]) {
RegEx::test(); RegEx::test();
Lexer::test(); Lexer::test();
//std::cout << strSlice("123", 0, -1) << std::endl; //std::cout << strSlice("123", 0, -1) << std::endl;
Poset<int>::test(); //int specilization just for testing. test() is actually only in the int specilization
if (argc >= 3) { if (argc >= 3) {
std::string testResults, line; std::string testResults, line;
int passed = 0, failed = 0; int passed = 0, failed = 0;

View File

@@ -480,7 +480,7 @@ NodeTree<ASTData>* ASTTransformation::scopeLookup(NodeTree<ASTData>* scope, std:
// the last node is actually a body node, as it may not have been generated yet if we're in the body // the last node is actually a body node, as it may not have been generated yet if we're in the body
//and this function is recursive or if this is a non-instantiated template function //and this function is recursive or if this is a non-instantiated template function
if (types.size() != ((children.size() > 0 && children[children.size()-1]->getDataRef()->type == code_block) ? children.size()-1 : children.size())) { if (types.size() != ((children.size() > 0 && children[children.size()-1]->getDataRef()->type == code_block) ? children.size()-1 : children.size())) {
std::cout << "Type sizes do not match between two " << lookup << "(" << types.size() << "," << ((children.size() > 0) ? children.size()-1 : 0) << "), types are: "; std::cout << "Type sizes do not match between two " << lookup << "(" << types.size() << "," << ((children.size() > 0 && children[children.size()-1]->getDataRef()->type == code_block) ? children.size()-1 : children.size()) << "), types are: ";
for (auto j : types) for (auto j : types)
std::cout << j.toString() << " "; std::cout << j.toString() << " ";
std::cout << std::endl; std::cout << std::endl;

View File

@@ -43,6 +43,8 @@ std::string CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
switch (data.type) { switch (data.type) {
case translation_unit: case translation_unit:
//Do here because we may need the typedefs before the declarations of variables //Do here because we may need the typedefs before the declarations of variables
//Note that we need to be careful of the order, though, as some declarations depend on others.
//What is this then? It's a poset! Wooo posets!
for (int i = 0; i < children.size(); i++) for (int i = 0; i < children.size(); i++)
if (children[i]->getDataRef()->type == type_def) if (children[i]->getDataRef()->type == type_def)
output += generate(children[i], enclosingObject) + "\n"; output += generate(children[i], enclosingObject) + "\n";

View File

@@ -1,9 +0,0 @@
This is the true regex for triple quoted strings, but it segfaults my regex code....
triple_quoted_string = "\"\"\"((\"\"(`|1|2|3|4|5|6|7|8|9|0|-|=| |q|w|e|r|t|y|u|i|o|p|[|]|\\|a|s|d|f|g|h|j|k|l|;|'|
|z|x|c|v|b|n|m|,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|Q|W|E|R|T|Y|U|I|O|P|{|}|\||A|S|D|F|G|H|J|K|L|:|Z|X|C|V|B|N|M|<|>|\?| )+)|(\"(`|1|2|3|4|5|6|7|8|9|0|-|=| |q|w|e|r|t|y|u|i|o|p|[|]|\\|a|s|d|f|g|h|j|k|l|;|'|
|z|x|c|v|b|n|m|,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|Q|W|E|R|T|Y|U|I|O|P|{|}|\||A|S|D|F|G|H|J|K|L|:|Z|X|C|V|B|N|M|<|>|\?| )+))*(`|1|2|3|4|5|6|7|8|9|0|-|=| |q|w|e|r|t|y|u|i|o|p|[|]|\\|a|s|d|f|g|h|j|k|l|;|'|
|z|x|c|v|b|n|m|,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|Q|W|E|R|T|Y|U|I|O|P|{|}|\||A|S|D|F|G|H|J|K|L|:|Z|X|C|V|B|N|M|<|>|\?| )*(((`|1|2|3|4|5|6|7|8|9|0|-|=| |q|w|e|r|t|y|u|i|o|p|[|]|\\|a|s|d|f|g|h|j|k|l|;|'|
|z|x|c|v|b|n|m|,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|Q|W|E|R|T|Y|U|I|O|P|{|}|\||A|S|D|F|G|H|J|K|L|:|Z|X|C|V|B|N|M|<|>|\?| )+\")|((`|1|2|3|4|5|6|7|8|9|0|-|=| |q|w|e|r|t|y|u|i|o|p|[|]|\\|a|s|d|f|g|h|j|k|l|;|'|
|z|x|c|v|b|n|m|,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|Q|W|E|R|T|Y|U|I|O|P|{|}|\||A|S|D|F|G|H|J|K|L|:|Z|X|C|V|B|N|M|<|>|\?| )+\"\")|((`|1|2|3|4|5|6|7|8|9|0|-|=| |q|w|e|r|t|y|u|i|o|p|[|]|\\|a|s|d|f|g|h|j|k|l|;|'|
|z|x|c|v|b|n|m|,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|Q|W|E|R|T|Y|U|I|O|P|{|}|\||A|S|D|F|G|H|J|K|L|:|Z|X|C|V|B|N|M|<|>|\?| )+))*\"\"\"" ;