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, 6 months ago) by root
Branch: MAIN
CVS Tags: HEAD
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.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