summaryrefslogtreecommitdiff
path: root/impl/main.cpp
diff options
context:
space:
mode:
authorCarlo Zancanaro <carlo@carlo-laptop>2012-05-29 22:42:25 +1000
committerCarlo Zancanaro <carlo@carlo-laptop>2012-05-29 22:42:25 +1000
commite043ee06a51a8d8c68f8cb0984d4f7bd8915bea8 (patch)
treecc8fd32426518808facb2efb496667b92cd22754 /impl/main.cpp
parentf09ce60d45d5524e36d07e76814b6e0cbc554288 (diff)
First attempt a range parser - likely not correct.
Diffstat (limited to 'impl/main.cpp')
-rw-r--r--impl/main.cpp106
1 files changed, 79 insertions, 27 deletions
diff --git a/impl/main.cpp b/impl/main.cpp
index 530556f..21be64b 100644
--- a/impl/main.cpp
+++ b/impl/main.cpp
@@ -19,53 +19,96 @@ extern "C" {
using namespace std;
template<typename T>
-Expression<T>* treeToExpression(pANTLR3_BASE_TREE node, EquationSystem<T>& system) {
+std::pair<Expression<T>*, Expression<T>*> treeToExpression(pANTLR3_BASE_TREE node, EquationSystem<T>& system, bool negative=false) {
ANTLR3_UINT32 num = node->getChildCount(node);
string name = (char*) node->getText(node)->chars;
- // leaf node - constant or variable
+ // leaf node - variable
if (num == 0) {
- if (name == "inf") {
- return system.newExpression(new Constant<T>(infinity<T>()));
- } else {
- stringstream stream(name);
- T output;
- if (stream >> output) {
- return system.newExpression(new Constant<T>(output));
- } else {
- return system.newExpression(system.newVariable(name));
- }
+ return std::pair<Expression<T>*, Expression<T>*>(
+ system.newExpression(system.newVariable(name + "_l")),
+ system.newExpression(system.newVariable(name + "_u")));
+ }
+
+ // a range itself
+ if (name == "RANGE") {
+ pANTLR3_BASE_TREE childNode;
+ string childName;
+ T firstValue, secondValue;
+
+ childNode = (pANTLR3_BASE_TREE) node->getChild(node, 0);
+ childName = (char*) childNode->getText(childNode)->chars;
+ stringstream firstStream(childName);
+ if (!(firstStream >> firstValue)) {
+ throw "Invalid number.";
+ }
+ if (negative) firstValue = -firstValue;
+
+ childNode = (pANTLR3_BASE_TREE) node->getChild(node, 1);
+ childName = (char*) childNode->getText(childNode)->chars;
+ stringstream secondStream(childName);
+ if (!(secondStream >> secondValue)) {
+ throw "Invalid number.";
}
+ if (negative) secondValue = -secondValue;
+
+ return std::pair<Expression<T>*, Expression<T>*>(
+ system.newExpression(new Constant<T>(firstValue)),
+ system.newExpression(new Constant<T>(secondValue)));
}
- // other operators
- std::vector<Expression<T>*> args;
+ if (name == "-") {
+ negative = true;
+ }
+
+ // subexpressions
+ std::vector<Expression<T>*> firstArgs;
+ std::vector<Expression<T>*> secondArgs;
pANTLR3_BASE_TREE childNode;
for (unsigned int i = 0; i < num; ++i) {
childNode = (pANTLR3_BASE_TREE) node->getChild(node, i);
- args.push_back(treeToExpression(childNode, system));
+ std::pair<Expression<T>*, Expression<T>*> expr = treeToExpression(childNode, system, negative);
+ firstArgs.push_back(expr.first);
+ secondArgs.push_back(expr.second);
+ }
+
+ // other operators
+ if (name == "-") {
+ //if (firstArgs.size() == 1) { // secondArgs.size() == firstArgs.size()
+ return std::pair<Expression<T>*, Expression<T>*>(
+ secondArgs[0],
+ firstArgs[0]);
}
if (name == "max") {
- return system.newMaxExpression(args);
+ return std::pair<Expression<T>*, Expression<T>*>(
+ system.newMaxExpression(firstArgs),
+ system.newMaxExpression(secondArgs));
} else {
- Operator<T>* op = NULL;
+ // we need two because expressions delete their operator
+ // bit of a silly design by me
+ Operator<T>* firstOp = NULL;
+ Operator<T>* secondOp = NULL;
if (name == "min") {
- op = new Minimum<T>();
+ firstOp = new Minimum<T>();
+ secondOp = new Minimum<T>();
} else if (name == "+") {
- op = new Addition<T>();
- } else if (name == "-") {
- op = new Subtraction<T>();
+ firstOp = new Addition<T>();
+ secondOp = new Addition<T>();
} else if (name == ";") {
- op = new Comma<T>();
+ firstOp = new Comma<T>();
+ secondOp = new Comma<T>();
} else if (name == "GUARD") {
- op = new Guard<T>();
+ firstOp = new Guard<T>();
+ secondOp = new Guard<T>();
} else {
std::cerr << "Unknown leaf node type: " << name << std::endl;
throw "Unknown leaf node type";
}
- return system.newExpression(op, args);
+ return std::pair<Expression<T>*, Expression<T>*>(
+ system.newExpression(firstOp, firstArgs),
+ system.newExpression(secondOp, secondArgs));
}
}
@@ -82,12 +125,21 @@ void treeToSystem(pANTLR3_BASE_TREE node, EquationSystem<T>& system) {
varNode = (pANTLR3_BASE_TREE) node->getChild(node, i);
exprNode = (pANTLR3_BASE_TREE) node->getChild(node, i+1);
+ Variable<T>* var;
+ vector<Expression<T>*> args;
+
string varName = (char*) varNode->getText(varNode)->chars;
- Variable<T>* var = system.newVariable(varName);
+ std::pair<Expression<T>*, Expression<T>*> exprs = treeToExpression(exprNode, system);
- vector<Expression<T>*> args;
+ var = system.newVariable(varName + "_l");
+ args.push_back(system.newExpression(new Constant<T>(-infinity<T>())));
+ args.push_back(exprs.first);
+ system[*var] = system.newMaxExpression(args);
+
+ args.clear();
+ var = system.newVariable(varName + "_u");
args.push_back(system.newExpression(new Constant<T>(-infinity<T>())));
- args.push_back(treeToExpression(exprNode, system));
+ args.push_back(exprs.second);
system[*var] = system.newMaxExpression(args);
}
}