]> ruin.nu Git - popboot.git/blob - parser.y
adding parser and test file
[popboot.git] / parser.y
1
2 %{
3     #include <ctype.h>
4     #include <string>
5     #include <iostream>
6     #include <sstream>
7     #include <fstream>
8     #include <vector>
9
10     #include "action.h"
11
12     using namespace std;
13
14     int yylex (void);
15     void yyerror (char const *);
16
17     ifstream* input;
18     vector<Action>* actions;
19 %}
20
21
22
23 %union {
24     Preconditions* preconds;
25     Literals* literals;
26     EffectsMap* effects;
27     string* str;   /* STR tokens */
28     int num;       /* NUM tokena */
29 }
30
31 %type <str> id
32 %type <preconds> preconds
33 %type <str> exec
34 %type <effects> effects
35 %type <literals> literals 
36 %token <str> STR 
37 %token <num> NUM
38
39 %left ','
40
41 %%
42
43 input   :  /* empty */
44         | input action  
45         | input '\n'
46 ;
47
48 action  : id preconds '\n' exec effects '\n' {  
49     
50                                 // Detta vill inte funka för mig!  
51                                 actions->push_back( Action(*$1,*$2,*$4,*$5) ); 
52
53                                 //---------------------------------------------
54                                 // Debug test print :   
55                                 cout << "id:  " << *$1 << endl;
56
57                                 // Precondition flags:
58                                 cout << "a: " << (*$2)["a"] << endl;
59                                 cout << "b: " << (*$2)["b"] << endl;
60                                 cout << "c: " << (*$2)["c"] << endl;
61                                 cout << "d: " << (*$2)["d"] << endl;
62                                 cout << "e: " << (*$2)["e"] << endl;
63
64                                 cout << "exe: " << *$4 << endl;
65
66                                 // Print number of effects
67                                 cout << "1: " << (*$5)[1].size() << endl;
68                                 cout << "99: " << (*$5)[99].size() << endl;
69                                 cout << "88: " << (*$5)[88].size() << endl;
70
71                                 cout << endl;
72                                 //----------------------------------------------
73                                             }
74         ;
75
76
77
78
79 id      : STR '\n'                  { $$ = $1; }
80         ;
81
82 /* Preconditions (literals with flag) */
83 preconds: preconds ','  preconds    {  
84                                         $$ = $1;
85                                         // $3 will only have on element
86                                         (*$$)[$3->begin()->first] =
87                                             $3->begin()->second;
88                                     }
89         | '?' STR                   {   
90                                         $$ = new Preconditions();
91                                         (*$$)[*$2] = false ;
92                                     } 
93         | STR                       {   
94                                         $$ = new Preconditions();
95                                         (*$$)[*$1] = true ;
96                                     }
97         ;
98
99 /* Executable */
100 exec    : STR '\n'                  { $$ = $1; }
101         ;
102
103 /* EffectMap */
104 effects : effects NUM ':' literals '\n' {
105                                         $$ = $1;
106                                         (*$$)[$2] = *$4;
107                                         }
108         | NUM ':' literals '\n'         {
109                                         $$ = new EffectsMap();
110                                         (*$$)[$1] = *$3 ;
111                                         }
112         ;
113
114
115 /* List of literals (effects) */
116 literals: literals ',' literals     { 
117                                         $$ = $1;
118                                         $$->push_back( *($3->begin()) ); 
119                                     }
120         | STR                       { 
121                                         $$ = new Literals();
122                                         $$->push_back(*$1); 
123                                     }
124         ;
125
126
127 %%
128
129 int 
130 yylex (void)
131 {
132     string str;
133
134     // Check for end of file
135     if ( input->eof() )
136         return 0;
137
138     // Ignore spaces
139     while ( input->peek()==' ' || input->peek()=='\t')
140         input->get();
141
142     // Ignore comments
143     while ( input->peek()=='#')
144         while ( input->peek()!='\n' )
145             input->get();
146
147
148
149
150     // Numbers
151     if ( isdigit(input->peek()) )
152     {
153         *input >> yylval.num;
154         return NUM;
155     }
156
157     // Alpha strings
158     if ( isalpha(input->peek()) )
159     {  
160         string* str = new string();
161         
162         int c = input->peek();
163         while (isalpha(c) || isdigit(c) || c=='_' || c=='.' )   
164         {
165             *str += input->get();
166             c = input->peek();
167         }
168         yylval.str = str;
169         return STR;
170     }
171
172     // String with spaces and other special characters
173     if ( input->peek()=='"' )
174     {
175         input->get();               // Consume "-character
176         string* str = new string();
177         while (input->peek()!='"')
178         {
179             *str += input->get();
180         }
181         input->get();               // Consume "-character
182
183         yylval.str = str;
184         return STR;
185     }
186
187     /* Return single char */
188     return input->get();           
189 }
190
191
192 void 
193 yyerror (char const *s)
194 {
195     cerr << "Parse error : " << s;
196 }
197
198
199 int 
200 main (int argc, char** argv)
201 {
202
203     if (argc!=4)
204     {
205         cout << "Syntax: " << argv[0] << 
206                 " <file> \"init state\" \"goal state\"" << endl;
207         return 1;
208     }
209
210     ifstream file(argv[1]);
211     if (!file)
212     {
213         cerr << "Unable to open file: " << argv[1] << endl;
214         exit(2);
215     }
216
217     // Set global variables
218     input = &file;
219     actions = new vector<Action>();
220
221     yyparse();
222 }