+
+%{
+ #include <ctype.h>
+ #include <string>
+ #include <iostream>
+ #include <sstream>
+ #include <fstream>
+ #include <vector>
+
+ #include "action.h"
+
+ using namespace std;
+
+ int yylex (void);
+ void yyerror (char const *);
+
+ ifstream* input;
+ vector<Action>* actions;
+%}
+
+
+
+%union {
+ Preconditions* preconds;
+ Literals* literals;
+ EffectsMap* effects;
+ string* str; /* STR tokens */
+ int num; /* NUM tokena */
+}
+
+%type <str> id
+%type <preconds> preconds
+%type <str> exec
+%type <effects> effects
+%type <literals> literals
+%token <str> STR
+%token <num> NUM
+
+%left ','
+
+%%
+
+input : /* empty */
+ | input action
+ | input '\n'
+;
+
+action : id preconds '\n' exec effects '\n' {
+
+ // Detta vill inte funka för mig!
+ actions->push_back( Action(*$1,*$2,*$4,*$5) );
+
+ //---------------------------------------------
+ // Debug test print :
+ cout << "id: " << *$1 << endl;
+
+ // Precondition flags:
+ cout << "a: " << (*$2)["a"] << endl;
+ cout << "b: " << (*$2)["b"] << endl;
+ cout << "c: " << (*$2)["c"] << endl;
+ cout << "d: " << (*$2)["d"] << endl;
+ cout << "e: " << (*$2)["e"] << endl;
+
+ cout << "exe: " << *$4 << endl;
+
+ // Print number of effects
+ cout << "1: " << (*$5)[1].size() << endl;
+ cout << "99: " << (*$5)[99].size() << endl;
+ cout << "88: " << (*$5)[88].size() << endl;
+
+ cout << endl;
+ //----------------------------------------------
+ }
+ ;
+
+
+
+
+id : STR '\n' { $$ = $1; }
+ ;
+
+/* Preconditions (literals with flag) */
+preconds: 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 */
+ return input->get();
+}
+
+
+void
+yyerror (char const *s)
+{
+ cerr << "Parse error : " << s;
+}
+
+
+int
+main (int argc, char** argv)
+{
+
+ if (argc!=4)
+ {
+ cout << "Syntax: " << argv[0] <<
+ " <file> \"init state\" \"goal state\"" << endl;
+ return 1;
+ }
+
+ ifstream file(argv[1]);
+ if (!file)
+ {
+ cerr << "Unable to open file: " << argv[1] << endl;
+ exit(2);
+ }
+
+ // Set global variables
+ input = &file;
+ actions = new vector<Action>();
+
+ yyparse();
+}