#include #include #include #include #include #include #include using namespace std; using namespace boost::spirit; map varmap; unsigned varcnt = 1; bool sign; void PrintVar(const char *b, const char *e) { string varname(b, e); unsigned varnum; map::iterator it = varmap.find(varname); if (it == varmap.end()) { varnum = varmap[varname] = varcnt++; } else { varnum = it->second; } printf(" v%d", varnum); } void PrintNum(int x) { printf(" %d", x); } struct mygram : public grammar { template struct SetSign { template void operator()(IteratorT first, IteratorT last) const { sign = s; } }; struct Emit { Emit(const char *s) : str(s) {} template void operator()(IteratorT first, IteratorT last) const { printf(" %s", str); } const char *str; }; struct EmitCoef { void operator()(int v) const { printf(" %s %d", sign?"+":"-", v); } }; template struct definition { definition(const mygram &self) { // Terminals MIN = str_p("minimize") | "min"; MAX = str_p("maximize") | "max"; IDENT = lexeme_d[(alpha_p | '_' ) >> *(alnum_p | '_' )]; PLUS = ch_p('+'); MINUS = ch_p('-'); NEG = ch_p('~'); NUMBER = int_p; LT_REL = str_p("<=") | "=<" | "<"; GT_REL = str_p(">=") | "=>" | "<"; EQ_REL = str_p("="); // Nonterminals product = !(int_p[EmitCoef()] >> !ch_p('*')) >> !NEG[Emit("~")] >> IDENT[&PrintVar]; sum_of_p = ((PLUS|eps_p)[SetSign()]|MINUS[SetSign()]) >> product >> *((PLUS[SetSign()]|MINUS[SetSign()]) >> product); relation = LT_REL[Emit("<=")] | GT_REL[Emit(">=")] | EQ_REL[Emit("=")] ; constraint = !(IDENT>>':') >> sum_of_p >> relation >> int_p[&PrintNum] >> !ch_p(';'); objective = MIN[Emit("min:")] >>':' >> sum_of_p >> !ch_p(';') | MAX[Emit("max:")] >>':' >> sum_of_p >> !ch_p(';') ; problem = !objective[Emit("\n")] >> *constraint[Emit("\n")]; } rule MIN, MAX, PLUS, MINUS, NEG, NUMBER, IDENT, LT_REL, GT_REL, EQ_REL; rule product, sum_of_p, constraint, relation, objective, problem; rule const& start() const { return problem;} }; }; int main() { mygram calc; string str; while (getline(cin, str)) { if (str[0] == '*') continue; parse_info<> info = parse(str.c_str(), calc, space_p); if (!info.full) { cout << "-------------------------\n"; cout << "Parsing failed\n"; cout << "stopped at: \": " << info.stop << "\"\n"; cout << "-------------------------\n"; } } return 0; }