ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/lsys/parser.g
Revision: 1.1
Committed: Thu Nov 6 14:31:24 2008 UTC (15 years, 5 months ago) by root
Branch: MAIN
CVS Tags: HEAD
Log Message:
*** empty log message ***

File Contents

# Content
1 #header <<
2 #include "config.h"
3
4 #include <cmath>
5 #include <list>
6
7 #include "lsys.h"
8 #include "util.h"
9
10 #define PURIFY(a,b)
11
12 void parse_file (FILE *file, const string &path, lsys &l) t_err;
13 void parse_file (const string &path, lsys &l) t_err;
14
15 extern list<string> include_dirs;
16 >>
17
18 <<
19 #include <sstream>
20 #include <cstdio>
21
22 #include "DLGLexer.h"
23
24 list<string> include_dirs;
25
26 void parse_file (FILE *file, const string &path, lsys &l) t_err
27 {
28 DLGFileInput in (file);
29 DLGLexer scanner (&in);
30 ANTLRTokenBuffer pipe (&scanner);
31 ANTLRCommonToken token;
32 scanner.setToken (&token);
33 Parser parser (&pipe);
34 parser.init ();
35
36 parser.current_file = path;
37 parser.parse_file (l);
38 }
39
40 void parse_file (const string &path, lsys &l) t_err
41 {
42 string ipath(path);
43 list<string>::const_iterator i = include_dirs.begin ();
44 FILE *f;
45
46 while (!(f = fopen (ipath.c_str (), "r")))
47 {
48 ipath += ".l";
49 if ((f = fopen (ipath.c_str (), "r")))
50 break;
51
52 if (i == include_dirs.end ())
53 throw error ("unable to find or open file '" + path + "'");
54
55 ipath = *i + "/" + path;
56 i++;
57 }
58
59 struct filebuf
60 {
61 FILE *f;
62 filebuf (FILE * file) : f (file) {};
63 ~filebuf () { fclose (f); };
64 } auto_close(f);
65
66 parse_file (f, ipath, l);
67 }
68 >>
69
70 #lexclass COMMENT
71
72 #token "\n" << skip(); newline(); set_endcol(0); >>
73 #token "\*/" << mode(START); skip(); >>
74 #token "~[]" << skip(); >>
75
76 #lexclass QW_STRING
77
78 #token Name "\"" << replchar('\0'); mode(START); >>
79 #token "\\\"" << replchar('\"'); more(); >>
80 #token "~[]" << more(); >>
81
82 #lexclass START
83
84 #token "/\*" << mode(COMMENT); skip(); >>
85 #token "\"" << skip(); mode(QW_STRING); >>
86
87 #token "//~[\n]*" << skip(); >>
88 #token "#~[\n]*" << skip(); >>
89 #token "\n" << skip(); newline(); set_endcol(0); >>
90 #token "[\ ]+" << skip(); >>
91 #token "\t" << skip(); _endcol = ((_endcol-1) & ~7) + 8; >>
92
93 #token Name "[a-zA-Z][a-z0-9_]*"
94 #token Number "[0-9]+{\.[0-9]+}"
95
96 class Parser {
97 <<
98 public:
99 string current_file;
100 protected:
101 void syn(_ANTLRTokenPtr tok, ANTLRChar *egroup, SetWordType *eset,
102 ANTLRTokenType etok, int k);
103
104 bool istok (_ANTLRTokenPtr tok, const char *s)
105 { return strcmp (tok->getText(), s) == 0; };
106
107 file_pos here ()
108 { return file_pos (current_file, LT(1)->getLine (), -1); };
109 >>
110
111 #lexclass START
112
113 parse_file[lsys &l]
114 : parse_lsys[l] "@"
115 ;
116
117 parse_lsys[lsys &l]
118 : ( statement[$l] )+ |
119 ;
120
121 statement[lsys &l]
122 : << string s; lsys *m = 0; /* calm down gcc */ >>
123 << istok(LT(1), "include") >>? .
124 (
125 qw_str:Name
126 <<
127 ::parse_file ($qw_str->getText(), l);
128 >>
129 |
130 "\(" br_str:Name "\)"
131 <<
132 m = new lsys;
133 ::parse_file ($br_str->getText (), *m);
134 l.add_lsys (m);
135 >>
136 )
137 | << istok(LT(1), "ruleset") >>? .
138 { module_name>[s] }
139 "\("
140 << m = new lsys; >>
141 parse_lsys[*m]
142 << l.add_lsys (m); >>
143 "\)"
144 | << istok(LT(1), "define") >>? .
145 module_name>[s] expr_any[$l.defines[s]] ";"
146 | << istok(LT(1), "ignore") >>? .
147 ( module_ref>[s] << $l.ignore_module.insert (s); >> )+ ";"
148 | << !istok(LT(1), ")") >>? /* why is this predicate necessary? */
149 parse_rule[$l]
150 ;
151
152 parse_rule[lsys &l]
153 : << rule r;
154 r.constraint = module (1); r.iterations.is_expr = 1;
155 r.iterations = module (0); r.iterations.is_expr = 1;
156 >>
157 parse_modvec[r.pre]
158 ( "\<" parse_module[*(module *)&r]
159 | <<
160 if (r.pre.size () == 0)
161 throw error ("symbol to be replaced must be a single module, not an empty sequence", LT(1)->getLine ());
162 else if (r.pre.size () != 1)
163 throw error ("symbol to be replaced must be a single module, not more", r.pre.first ());
164 else
165 {
166 *(module *)&r = r.pre.first ();
167 r.pre.erase ();
168 }
169 >>
170 )
171 { "\>" parse_modvec[r.post] }
172 { ":" expr_numeric[r.constraint] }
173 "=>" ( parse_modvec[r.repl] | /* empty */ )
174 { "," expr_numeric[r.iterations] }
175 ";"
176 << $l.add_rule(r); >>
177 ;
178
179 parse_modvec[module_vec &v]
180 : << module m; >>
181 ( parse_module[m] << $v.push_back (m); >> )+
182 ;
183
184 parse_module[module &m]
185 : << module v;
186 m.erase ();
187 >>
188 module_head[$m] {
189 "\("
190 expr_any[v] << $m.push_back (v); v.erase (); >>
191 ( "," expr_any[v] << $m.push_back (v); v.erase (); >> )*
192 "\)"
193 }
194 ;
195
196 module_head[module &m]
197 : n:Number << $m = module (atof ($n->getText ())); $m.where = here (); >>
198 | module_ref>[$m.str] << $m.is_num = 0; $m.where = here (); >>
199 ;
200
201 module_name>[string s]
202 : a:Name << $s = $a->getText(); >>
203 ;
204
205 module_ref>[string s]
206 : module_name>[$s]
207 | "\\" << $s = "\\"; >>
208 | "\+" << $s = "+"; >>
209 | "\-" << $s = "-"; >>
210 | "\*" << $s = "*"; >>
211 | "\/" << $s = "/"; >>
212 | "\^" << $s = "^"; >>
213 | "\{" << $s = "{"; >>
214 | "\}" << $s = "}"; >>
215 | "\." << $s = "."; >>
216 | "\|" << $s = "|"; >>
217 | "\~" << $s = "~"; >>
218 | "\[" << $s = "["; >>
219 | "\]" << $s = "]"; >>
220 | "\!" << $s = "!"; >>
221 | "\&" << $s = "&"; >>
222 | "\%" << $s = "%"; >>
223 ;
224
225 expr_any[module &v]
226 : expr_numeric[$v]
227 | expr_modvec[$v]
228 ;
229
230 expr_modvec[module &v]
231 : "\"" parse_modvec[$v] << $v.str.erase (); $v.is_expr = 0; >> "\""
232 | "\'" parse_modvec[$v] << $v.str.erase (); $v.is_expr = 0; >>
233 ;
234
235 expr_numeric[module &v]
236 : expr_0[$v] << $v.is_expr = 1; >>
237 ;
238
239 expr_0[module &v]
240 : << module r; >>
241 expr_1[$v] ( "\&\&" expr_2[r] << $v = module ("&&", $v, r); >>
242 | "\|\|" expr_2[r] << $v = module ("||", $v, r); >>
243 )*
244 | "\!" expr_1[r] << $v = module ("!", r); >>
245 ;
246
247 expr_1[module &v]
248 : << module r; >>
249 expr_2[$v] { "\>" expr_2[r] << $v = module (">" , $v, r); >>
250 | ">=" expr_2[r] << $v = module (">=", $v, r); >>
251 | "==" expr_2[r] << $v = module ("==", $v, r); >>
252 | "=" expr_2[r] << $v = module ("==", $v, r); >>
253 | "!=" expr_2[r] << $v = module ("!=", $v, r); >>
254 | "\<" expr_2[r] << $v = module ("<" , $v, r); >>
255 | "<=" expr_2[r] << $v = module ("<=", $v, r); >>
256 }
257 ;
258
259 expr_2[module &v]
260 : << module r; >>
261 << $v = module (0); >>
262 {expr_3[$v]} ( "\+" expr_3[r] << $v = module ("+", $v, r); >>
263 | "\-" expr_3[r] << $v = module ("-", $v, r); >>
264 )*
265 ;
266
267 expr_3[module &v]
268 : << module r; >>
269 expr_4[$v] ( "\*" expr_4[r] << $v = module ("*", $v, r); >>
270 | "\/" expr_4[r] << $v = module ("/", $v, r); >>
271 | "\%" expr_4[r] << $v = module ("%", $v ,r); >>
272 )*
273 ;
274
275 expr_4[module &v]
276 : << module r; >>
277 expr_5[$v] ( "\^" expr_5[r] << $v = module ("^", $v, r); >>
278 )*
279 ;
280
281 expr_5[module &v]
282 : "\(" expr_0[$v] << $v.where = here (); >> "\)"
283 | expr_atom[$v]
284 ;
285
286 expr_atom[module &v]
287 : num:Number << $v = module (atof ($num->getText ())); $v.where = here (); >>
288 | expr_module[$v]
289 ;
290
291 expr_module[module &m]
292 : << module v;
293 m.erase ();
294 m.where = here ();
295 >>
296 module_name>[$m.str] {
297 "\("
298 expr_any[v] << $m.push_back (v); v.erase (); >>
299 ( "," expr_any[v] << $m.push_back (v); v.erase (); >> )*
300 "\)"
301 }
302 ;
303
304 }
305
306 <<
307 void Parser::syn (_ANTLRTokenPtr tok, ANTLRChar * egroup, SetWordType * eset,
308 ANTLRTokenType etok, int k)
309 {
310 ostringstream msg;
311
312 syntaxErrCount++;
313
314 msg << current_file << ":" << LT (1)->getLine () << ": syntax error at \"" << LT (1)->getText ();
315
316 if (etok || eset)
317 {
318 if (k == 1)
319 msg << " missing";
320 else
321 {
322 msg << "; \"" << LT (1)->getText () << "\" not";
323 if (set_deg (eset) > 1)
324 msg << " in";
325 }
326
327 if (set_deg (eset) > 0)
328 {
329 SetWordType *p = eset;
330 SetWordType *endp = &(p[bsetsize]);
331 unsigned e = 0;
332
333 if (set_deg (eset) > 1)
334 msg << " {";
335 do
336 {
337 register SetWordType t = *p;
338 register SetWordType *b = &(bitmask[0]);
339 do
340 {
341 if (t & *b)
342 msg << " " << token_tbl[e];
343 e++;
344 }
345 while (++b < &(bitmask[sizeof (SetWordType) * 8]));
346 }
347 while (++p < endp);
348 if (set_deg (eset) > 1)
349 msg << " }";
350 }
351 else
352 msg << " " << token_tbl[etok];
353
354 if (strlen (egroup) > 0)
355 msg << " in " << egroup;
356
357 msg << endl;
358 throw error (msg.str ());
359 }
360 }
361 >>
362
363
364
365
366