summaryrefslogtreecommitdiff
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
parentf09ce60d45d5524e36d07e76814b6e0cbc554288 (diff)
First attempt a range parser - likely not correct.
-rw-r--r--impl/EquationSystem.g10
-rw-r--r--impl/main.cpp106
-rw-r--r--impl/systems/range-test1
-rw-r--r--impl/systems/size-ten6
4 files changed, 89 insertions, 34 deletions
diff --git a/impl/EquationSystem.g b/impl/EquationSystem.g
index 3a6598a..6b721bb 100644
--- a/impl/EquationSystem.g
+++ b/impl/EquationSystem.g
@@ -11,6 +11,7 @@ tokens {
SUB = '-' ;
MULT = '*' ;
COMMA = ';' ;
+ RANGE = 'range' ;
GUARD = 'guard' ;
GREATER_EQUAL = '>=' ;
QUESTION_MARK = '?' ;
@@ -26,14 +27,15 @@ maxExpr : MAXIMUM^ '('! minExpr ( ','! minExpr )* ')'! | minExpr ;
minExpr : MINIMUM^ '('! maxExpr ( ','! maxExpr )* ')'! | expr ;
expr : '(' expr GREATER_EQUAL expr QUESTION_MARK expr ')' -> ^(GUARD expr expr expr)
- | term ( (PLUS | MULT | SUB | COMMA)^ expr )* ;
+ | term ( (PLUS | MULT | COMMA)^ expr )* ;
-term : NUMBER
+term : '[' NUMBER ',' NUMBER ']' -> ^( RANGE NUMBER NUMBER )
| VARIABLE
- | '('! expr ')'! ;
+ | '('! expr ')'!
+ | SUB^ term ;
-NUMBER : (DIGIT)+ ;
+NUMBER : (SUB) (DIGIT)+ | (DIGIT)+ ;
VARIABLE: (LETTER) (LETTER | DIGIT)* ;
WHITESPACE : ( '\t' | ' ' | '\u000C' )+
{
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);
}
}
diff --git a/impl/systems/range-test b/impl/systems/range-test
new file mode 100644
index 0000000..c2ac047
--- /dev/null
+++ b/impl/systems/range-test
@@ -0,0 +1 @@
+x = max([0, 1], -x + [-1, 1])
diff --git a/impl/systems/size-ten b/impl/systems/size-ten
index 71ee74a..9ef3135 100644
--- a/impl/systems/size-ten
+++ b/impl/systems/size-ten
@@ -1,3 +1,3 @@
-x1 = max(0, min(x1-1, x2))
-x2 = max(0, 5+x1, x1)
-x3 = max(0, 1+x3, 0+x1)
+x1 = max([0,0], min(x1-[1,1], x2))
+x2 = max([0,0], [5,5]+x1, x1)
+x3 = max([0,0], [1,1]+x3, [0,0]+x1)