From fcecd0e7dc0bf103986c02e2f29fb518cd5571c5 Mon Sep 17 00:00:00 2001 From: Carlo Zancanaro Date: Thu, 3 May 2012 15:35:39 +1000 Subject: Add a parser for linear equations (Also add the antlr jar and C runtime) --- impl/main.cpp | 138 ++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 87 insertions(+), 51 deletions(-) (limited to 'impl/main.cpp') diff --git a/impl/main.cpp b/impl/main.cpp index a0c6bea..c5a0be6 100644 --- a/impl/main.cpp +++ b/impl/main.cpp @@ -1,5 +1,8 @@ #include #include +#include +#include +#include #include #include "Operator.hpp" @@ -7,6 +10,11 @@ #include "MaxStrategy.hpp" #include "EquationSystem.hpp" +extern "C" { +#include "EquationSystemParser.h" +#include "EquationSystemLexer.h" +} + using namespace std; typedef std::vector*> Args; @@ -15,66 +23,94 @@ typedef Constant C; typedef Addition A; typedef Minimum Min; -std::vector< Expression* > empty; -int main () { - { - EquationSystem sys; - Variable* x = sys.newVariable("x"); - Variable* y = sys.newVariable("y"); - Variable* z = sys.newVariable("z"); - - Args xPlusArgs; - xPlusArgs.push_back(sys.newExpression(x, empty)); - - Args xMinArgs; - xMinArgs.push_back(sys.newExpression(new A(-1), xPlusArgs)); - xMinArgs.push_back(sys.newExpression(y, empty)); - - Args xMaxArgs; - xMaxArgs.push_back(sys.newExpression(new C(0), empty)); - xMaxArgs.push_back(sys.newExpression(new Min(), xMinArgs)); - - sys[*x] = sys.newMaxExpression(xMaxArgs); - // x = max(0, min(x-1, y)) - - - Args yPlusArgs; - yPlusArgs.push_back(sys.newExpression(x, empty)); - - Args yMaxArgs; - yMaxArgs.push_back(sys.newExpression(new C(0), empty)); - yMaxArgs.push_back(sys.newExpression(new A(5), yPlusArgs)); - yMaxArgs.push_back(sys.newExpression(x, empty)); - - sys[*y] = sys.newMaxExpression(yMaxArgs); - // y = max(0, x+5, x) +template +Expression* treeToExpression(pANTLR3_BASE_TREE node, EquationSystem& system) { + ANTLR3_UINT32 num = node->getChildCount(node); + + string name = (char*) node->getText(node)->chars; + + // leaf node - constant or variable + if (num == 0) { + stringstream stream(name); + T output; + if (stream >> output) { + return system.newExpression(new Constant(output), vector*>()); + } else { + return system.newExpression(system.newVariable(name), vector*>()); + } + } + // other operators + std::vector*> args; + 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)); + } - Args zPlusArgs1; - zPlusArgs1.push_back(sys.newExpression(z, empty)); + if (name == "max") { + return system.newMaxExpression(args); + } else { + Operator* op = NULL; + if (name == "min") { + op = new Minimum(); + } else if (name == "+") { + op = new Addition(); + } else if (name == "-") { + op = new Subtraction(); + } + return system.newExpression(op, args); + } +} - Args zPlusArgs2; - zPlusArgs2.push_back(sys.newExpression(x, empty)); +template +void treeToSystem(pANTLR3_BASE_TREE node, EquationSystem& system) { + ANTLR3_UINT32 num = node->getChildCount(node); - Args zMaxArgs; - zMaxArgs.push_back(sys.newExpression(new C(0), empty)); - zMaxArgs.push_back(sys.newExpression(new A(1), zPlusArgs1)); - zMaxArgs.push_back(sys.newExpression(new A(0), zPlusArgs2)); + if (num % 2 == 1) + throw "Big problem here."; - sys[*z] = sys.newMaxExpression(zMaxArgs); - // z = max(0, z+1, x) + pANTLR3_BASE_TREE varNode; + pANTLR3_BASE_TREE exprNode; + for (unsigned int i = 0; i < num; i += 2) { + varNode = (pANTLR3_BASE_TREE) node->getChild(node, i); + exprNode = (pANTLR3_BASE_TREE) node->getChild(node, i+1); + string varName = (char*) varNode->getText(varNode)->chars; + Variable* var = system.newVariable(varName); + system[*var] = treeToExpression(exprNode, system); + } +} - // x = max(0, min(x-1, y)) - // y = max(0, x+5, x) - // z = max(0, z+1, x) - // => x: 0, y: 5, z: inf - VariableAssignment fixpoint = sys.minFixpoint(); - cout << "x = " << fixpoint[*x] << endl; - cout << "y = " << fixpoint[*y] << endl; - cout << "z = " << fixpoint[*z] << endl; +std::vector< Expression* > empty; +int main (int argc, char* argv[]) { + pANTLR3_INPUT_STREAM input; + pEquationSystemLexer lex; + pANTLR3_COMMON_TOKEN_STREAM tokens; + pEquationSystemParser parser; + + input = antlr3FileStreamNew((pANTLR3_UINT8)argv[1], ANTLR3_ENC_8BIT); + lex = EquationSystemLexerNew(input); + tokens = antlr3CommonTokenStreamSourceNew(ANTLR3_SIZE_HINT, TOKENSOURCE(lex)); + parser = EquationSystemParserNew(tokens); + + EquationSystemParser_equation_system_return ret = parser -> equation_system(parser); + + EquationSystem system; + treeToSystem(ret.tree, system); + // DO MORE HERE + + VariableAssignment rho = system.minFixpoint(); + const std::vector*> vars = system.vars(); + for (unsigned int i = 0, size = vars.size(); i < size; ++i) { + cout << vars[i]->name() << " = " << rho[*vars[i]] << endl; } + parser -> free(parser); + tokens -> free(tokens); + lex -> free(lex); + input -> close(input); + return 0; } -- cgit v1.2.3