%{ #include #include #include #include #include #include #include #include "action.h" #include "planner.h" using namespace std; int yyparse(void); int yylex (void); void yyerror (char const *); ifstream* input; int line = 1; vector* actions; EffectsMap* runlevels; %} %union { Preconditions* preconds; Literals* literals; EffectsMap* effects; string* str; /* STR tokens */ int num; /* NUM tokena */ } %type id %type preconds %type exec %type effects %type literals %token STR %token NUM %left ',' %% input : runlvls '\n' actions ; runlvls : '\n' runlvls | effects { runlevels = $1; } ; actions : /* empty */ | actions action | actions '\n' ; action : id preconds '\n' exec effects '\n' { actions->push_back( Action(*$1,*$2,*$4,*$5) ); //--------------------------------------------- // Debug test print : /* cerr << "id: " << *$1 << endl; // Precondition flags: cerr << "a: " << (*$2)["a"] << endl; cerr << "b: " << (*$2)["b"] << endl; cerr << "c: " << (*$2)["c"] << endl; cerr << "d: " << (*$2)["d"] << endl; cerr << "e: " << (*$2)["e"] << endl; cerr << "exe: " << *$4 << endl; // Print number of effects cerr << "0: " << (*$5)[0].size() << endl; cerr << "99: " << (*$5)[99].size() << endl; cerr << "88: " << (*$5)[88].size() << endl; cerr << endl; */ //---------------------------------------------- } ; id : STR '\n' { $$ = $1; } ; /* Preconditions (literals with flag) */ preconds: /* empty */ { $$ = new Preconditions(); } | preconds ',' preconds { $$ = $1; // $3 will only have on element (*$$)[$3->begin()->first] = $3->begin()->second; } | '?' STR { $$ = new Preconditions(); (*$$)[*$2] = false ; } | STR { $$ = new Preconditions(); (*$$)[*$1] = true ; } ; /* Executable */ exec : STR '\n' { $$ = $1; } ; /* EffectMap */ effects : effects NUM ':' literals '\n' { $$ = $1; (*$$)[$2] = *$4; } | NUM ':' literals '\n' { $$ = new EffectsMap(); (*$$)[$1] = *$3 ; } ; /* List of literals (effects) */ literals: literals ',' literals { $$ = $1; $$->push_back( *($3->begin()) ); } | STR { $$ = new Literals(); $$->push_back(*$1); } ; %% int yylex (void) { string str; // Check for end of file if ( input->eof() ) return 0; // Ignore spaces while ( input->peek()==' ' || input->peek()=='\t') input->get(); // Ignore comments while ( input->peek()=='#') while ( input->peek()!='\n' ) input->get(); // Numbers if ( isdigit(input->peek()) ) { *input >> yylval.num; return NUM; } // Alpha strings if ( isalpha(input->peek()) ) { string* str = new string(); int c = input->peek(); while (isalpha(c) || isdigit(c) || c=='_' || c=='.' ) { *str += input->get(); c = input->peek(); } yylval.str = str; return STR; } // String with spaces and other special characters if ( input->peek()=='"' ) { input->get(); // Consume "-character string* str = new string(); while (input->peek()!='"') { *str += input->get(); } input->get(); // Consume "-character yylval.str = str; return STR; } /* Return single char */ int c = input->get(); if ( c=='\n' ) ++line; return c; } void yyerror (char const *s) { cerr << "Line " << line << ": " << s << endl; } vector stringToVector(string str){ vector strings; istringstream ist(str); while (ist >> str){ strings.push_back(str); } return strings; } int main (int argc, char** argv) { if (argc < 3) { cerr << "Syntax: " << argv[0] << " \"init state\"" << endl; return 1; } Literals init = argc >= 4 ? stringToVector(argv[3]) : Literals(); ifstream file(argv[1]); if (!file) { cerr << "Unable to open file: " << argv[1] << endl; exit(2); } // Set global variables input = &file; actions = new vector(); runlevels = new EffectsMap(); yyparse(); /* cerr << (*runlevels)[2].size() << endl; cerr << (*runlevels)[3].size() << endl; cerr << (*runlevels)[4].size() << endl; cerr << (*runlevels)[5].size() << endl; */ Planner p(*actions, init, (*runlevels)[atoi(argv[2])]); p.execute(); delete actions; delete runlevels; }