diff options
author | Carlo Zancanaro <carlo@carlo-laptop> | 2012-05-29 22:42:25 +1000 |
---|---|---|
committer | Carlo Zancanaro <carlo@carlo-laptop> | 2012-05-29 22:42:25 +1000 |
commit | e043ee06a51a8d8c68f8cb0984d4f7bd8915bea8 (patch) | |
tree | cc8fd32426518808facb2efb496667b92cd22754 /impl/main.cpp | |
parent | f09ce60d45d5524e36d07e76814b6e0cbc554288 (diff) |
First attempt a range parser - likely not correct.
Diffstat (limited to 'impl/main.cpp')
-rw-r--r-- | impl/main.cpp | 106 |
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); } } |