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