lexdir
[henge/apc.git] / src / lexer.rl
1 #include <stdio.h>
2 #include <stdint.h>
3 #include <stdlib.h>
4 #include <errno.h>
5 #include "parser.tab.h"
6 #include "apc.h"
7 #include <unistdio.h>
8 #include <unistr.h>
9 extern //lexer.c
10 void lexer_pushtok(int, YYSTYPE);
11 /* Public */
12 int lexer_setdirection(uint8_t*, int);
13 int lexer_lexfile(const uint8_t*);
14 int lexer_lexdir(const uint8_t*);
15 int lexer_lexstring(const uint8_t*, int);
16 int lexer_setstr(uint8_t*, int);
17 //apc.c
18 extern
19 yypstate* apc_pstate;
20 extern
21 yycstate* apc_cstate;
22 #define PUSHTOK(T,L) yypush_parse(apc_pstate, T, (YYSTYPE*)(L), apc_cstate)
23 #define LEXTOK(T,L) do { \
24 PUSHTOK(T,L); \
25 ntok++; \
26 } while (0);
27 #define LEXFACE(F) do { \
28 lval.face = F; \
29 LEXTOK(FACING, &lval.face); \
30 } while (0);
31
32 /* Lexstring is the main lexer for APC and is generated by ragel. It lexes file names of files
33 that have been scanned and pushes their types and values into the tok_stack, which yyparse
34 eventually calls during parsing. */
35
36 %%{
37 machine lexstring;
38
39 # set up yylval and tok_t to be pushed to stack
40 action push_ref { te = NULL; errno = 0;
41 lval.ref = strtoll((char*)ts,(char**)&te,16);
42 if (errno | (te != NULL))
43 { fprintf(stderr, "Invalid hex number in file %s\n",(char*)str);
44 if (te != NULL)
45 { while (str++ < te)
46 fputc(' ', stderr);
47 fputc('^', stderr);
48 }
49 exit(1);
50 }
51 LEXTOK(REF, &lval.ref);
52 }
53 action push_link { lval.val = 0;
54 PUSHTOK(LINK, &lval.val); }
55 action push_val { te = NULL; errno = 0;
56 lval.val = strtoll((char*)ts,(char**)&te,10);
57 if (errno)
58 { fprintf(stderr, "strtoll could not parse %s\n", (char*)str);
59 exit(1);
60 }
61 LEXTOK(NUM, &lval.val);
62 }
63 action push_name { printf("Lexer_lexstring:: action:push_name: from %s to %s\n", ts, p);
64 LEXTOK(NAME, ts);
65 }
66 action push_map { printf("Lexer_lexstring:: action:push_map: pushing map token\n");
67 LEXTOK(MAP, "~");
68 }
69 action set_ts { printf("Lexer_lexstring:: action:set_ts. ts = %s\n", p); ts = p; }
70 action push_SS { printf("Lexer_lexstring:: action:push_SS. p = %s\n",p);
71 LEXTOK(SS, "SS");
72 }
73 action push_S { printf("Lexer_lexstring:: action:push_S. p = %s\n", p);
74 LEXFACE(SFACE);
75 }
76 action push_SW { printf("Lexer_lexstring:: action:push_SW. p = %s\n", p);
77 LEXFACE(SWFACE);
78 }
79 action push_W { printf("Lexer_lexstring:: action:push_W. p = %s\n", p);
80 LEXFACE(WFACE);
81 }
82 action push_NW { printf("Lexer_lexstring:: action:push_NW. p = %s\n", p);
83 LEXFACE(NWFACE);
84 }
85 action push_N { printf("Lexer_lexstring:: action:push_N. p = %s\n", p);
86 LEXFACE(NFACE);
87 }
88 action push_NE { printf("Lexer_lexstring:: action:push_NE. p = %s\n", p);
89 LEXFACE(NEFACE);
90 }
91 action push_E { printf("Lexer_lexstring:: action:push_N. p = %s\n", p);
92 LEXFACE(EFACE);
93 }
94 action push_SE { printf("Lexer_lexstring:: action:push_N. p = %s\n", p);
95 LEXFACE(SEFACE);
96 }
97 action ref_error { printf("ref from %s to %s has an inappropriate amount of hex digits, it must have eight.\n", ts, p);
98 exit(1);
99 }
100 action p { printf("Lexer_lexstring:: p = %s\n", p);}
101
102 N = 'N' %push_N;
103 W = 'W' %push_W;
104 S = 'S' %push_S;
105 E = 'E' %push_E;
106 NW = 'NW' %push_NW;
107 NE = 'NE' %push_NW;
108 SW = 'SW' %push_SW;
109 SE = 'SE' %push_SE;
110
111 tok_delimiter = [_];
112
113 direction = (N | W | S | E | NW | NE | SW | SE) ;
114 dimensions = (digit+ - '0') >set_ts %push_val 'x' (digit+ - '0') >set_ts %push_val;
115 link = '#' %push_link;
116 SS = ('+SS' %to(push_SS)) | ('+SS' %to(push_SS) link ) ;
117 ref = '0x' >set_ts alnum{8} $err(ref_error) %push_ref ;
118 val = digit+ >set_ts %push_val ;
119 name = (lower+ >set_ts) (lower | digit)+ %push_name ;
120 map = '+MAP' %to(push_map);
121 tok = (name | val | ref | dimensions | map | link | SS | direction);
122
123
124 main := (tok tok_delimiter)+ tok [\0];
125
126 write data nofinal noerror noprefix;
127
128 }%%
129
130 int lexer_lexstring
131 ( const uint8_t* str,
132 int size
133 )
134 { const uint8_t *p;
135 const uint8_t *ts, *pe, *te, *eof;
136 int cs, ntok;
137 YYSTYPE lval;
138
139 ntok = 0;
140 p = ts = str;
141 pe = eof = p + size + 1;
142
143
144 printf("|---Begin lexstring on p = %s, pe = %s.\n",p, pe);
145
146 %%write init;
147 %%write exec;
148
149 printf("Ending lexstring of file %s, pushed %d tokens.\n",str, ntok);
150
151 return ntok;
152 }
153
154 /* Lexical analysis of a file
155 Strips a filename to its base name, then sends it to lexer_lexstring before
156 pushing a PATH token with the filename
157 Returns the number of tokens pushed to the parser.
158 */
159 int lexer_lexfile
160 ( uint8_t const* filename )
161 { uint8_t const* last_period,* iter;
162 int ntok;
163 last_period = NULL;
164 for (iter = filename; *iter; iter++)
165 if (*iter == '.')
166 last_period = iter;
167 ntok = (last_period) ?
168 lexer_lexstring(filename, (int)(last_period - filename))
169 : lexer_lexstring(filename, (int)(iter - filename));
170 PUSHTOK(PATH,&filename);
171 return ntok + 1;
172 return en_main == 1;
173 }
174
175 int lexer_lexdir
176 ( uint8_t const* dirname )
177 { uint8_t const* de = dirname;
178 while (*de++);
179 return lexer_lexstring(dirname, (int)(de - dirname));
180 }
181
182 /**************************/
183 /****Abandon All Hope******/
184 /**************************/
185 /*** ***/
186 /*** ***/
187 /*** ***/
188 /*** ***/
189
190
191 #if 0
192
193 %%{
194 machine setdirection;
195
196 action ret_north {printf("Lexer_setdirection:: direction is north, returning 4\n"); return 4;; }
197 action ret_west { printf("Lexer_setdirection:: direction is west, returning 2\n");return 2;}
198 action ret_east { printf("Lexer_setdirection:: direction is east, returning 6\n");return 6;}
199 action ret_south { printf("Lexer_setdirection:: direction is south, returning 0\n");return 0;}
200 action ret_northeast { printf("Lexer_setdirection:: direction is northeast, returning 5\n");return 5 ;}
201 action ret_northwest { printf("Lexer_setdirection:: direction is northwest, returning 3\n");return 3;}
202 action ret_southeast { printf("Lexer_setdirection:: direction is southeast, returning 7\n");return 7;}
203 action ret_southwest { printf("Lexer_setdirection:: direction is southwest, returning 1\n");return 1;}
204
205 def = [_\0] %to(ret_south);
206 N = 'N'[_\0] %to(ret_north);
207 W = 'W' [_\0] %to(ret_west);
208 S = 'S' [_\0] %to(ret_south);
209 E = 'E' [_\0] %to(ret_east);
210 NW = 'NW' [_\0] %to(ret_northwest);
211 NE = 'NE' [_\0] %to(ret_northeast);
212 SW = 'SW' [_\0] %to(ret_southwest);
213 SE = 'SE' [_\0] %to(ret_southeast);
214
215 direction = (N | W | S | E | NW | NE | SW | SE | def);
216
217 main := direction;
218
219 write data nofinal noprefix noerror;
220
221
222 }%%
223
224
225 int
226 lexer_setdirection
227 (uint8_t* str, int size)
228 { uint8_t *p, *pe, *eof;
229 int cs;
230
231
232 p = str;
233 pe = str + size + 1;
234
235 printf("|--- Begin lexer_setdirection str = %s, p = %s, pe = %s ---|\n", str,p, pe);
236
237 %%write init;
238 %%write exec noend;
239
240 printf("|--- Error in: lexer_setdirection ---|\n");
241
242 return -1;
243 }
244
245
246
247 %%{
248 machine setstr;
249
250
251 action lex_setvlink {printf("Lexer_setstr:: Returning setvlink filetype for %s\n", str); type = 5; newstrt = lexer_lexsetvlink(str); fbreak;}
252 action lex_elevlink {printf("Lexer_setstr:: Returning elevlink filetype for %s\n", str); type = 6; newstrt = lexer_lexelevlink(str); fbreak;}
253 action lex_setmodel {printf("Lexer_setstr:: Returning setmodel filetype\n"); newstrt = lexer_lexsetmodel(str); type = 1; fbreak;}
254 action lex_setmap {printf("Lexer_setstr:: Returning setmap filetype\n"); newstrt = lexer_lexsetmap(str); type = 2; fbreak;}
255 action lex_elemodel {printf("Lexer_setstr:: Returning elemodel filetype for %s\n", str); newstrt = lexer_lexelemodel(str); type = 3; fbreak;}
256 action lex_elemap {printf("Lexer_setstr:: Returning elemap filetype for %s\n", str); newstrt = lexer_lexelemap(str); type = 4; fbreak;}
257 action lex_setolink { printf("Lexer_setstr:: Returning setolink filetype\n"); type = 8; newstrt = lexer_lexsetolink(str); fbreak;}
258 action lex_eleolink { printf("Lexer_setstr:: Returning eleolink filetype\n"); type = 7; newstrt = lexer_lexeleolink(str); fbreak;}
259 action p {printf("p = %s \n",p);}
260 action name_error {printf("In %s, there is a syntactic error. Make sure your set/element names dont conflict with the reserved keywords.\n", str);}
261
262
263 N = 'N';
264 W = 'W';
265 S = 'S';
266 E = 'E';
267 NW = 'NW';
268 NE = 'NE';
269 SW = 'SW';
270 SE = 'SE';
271
272 SS = 'SS';
273 direction = (N | W | S | E | NW | NE | SW | SE) $p;
274
275 SSD = SS direction;
276
277
278
279 name = alpha+ $p - SSD $p;
280 num = digit+ $p;
281 ref = '0x' $p alnum+ $p;
282
283
284 set_label = name | (name '_' ref);
285 ele_label = name | (name '_' ref);
286
287 model_types = (name) | (name '_' num '_' num) | (name '_' num);
288
289
290 set_model = set_label '_' SS %to(lex_setmodel);
291 set_map = set_label '_' '~' %to(lex_setmap);
292 ele_model = set_label '_' ele_label '_' SS %to(lex_elemodel);
293 ele_map = set_label '_' ele_label '_' '~' %to(lex_elemap);
294 set_olink = ref %to(lex_setolink) [\0] ;
295 ele_olink = set_label '_' '~' '_' ref [\0] %to(lex_eleolink);
296 set_vlink = set_label '_' '#' '_' (ref | ref '_' name) [\0] %to(lex_setvlink);
297 ele_vlink = set_label '_' ele_label '_' '#' '_' (ref | ref '_' name) [\0] %to(lex_elevlink);
298
299 main := (ele_map | set_model | set_map |ele_model | ele_vlink | set_vlink | set_olink | ele_olink);
300
301 write data;
302
303
304 }%%
305
306 int
307 lexer_setstr
308 (uint8_t* str, int size)
309 { uint8_t *p, *pe, *eof;
310 int cs, type, newstrt;
311
312 type = newstrt = 0;
313
314 p = str;
315 pe = str + size + 1;
316
317 printf("|--- Begin lexer_setstr with str = %s, p = %s, pe = %s ---|\n", str,p, pe);
318
319 %%write init;
320 %%write exec noend;
321
322 printf("|--- End lexer_setstr. Incrementing str by %d, type is %d ---|\n", newstrt, type);
323
324 return newstrt;
325 }
326
327 #endif
328
329
330 /* %%{ */
331 /* machine file_matcher; */
332
333 /* action call_ml { ts = p; fgoto set_hw ;} */
334 /* action call_tl { return 0;} */
335 /* action set_height {height = ttov(p, p-ts+1); ts = p;} */
336 /* action set_width { width = ttov(p, p-ts+1);} */
337 /* action call_lmf {lexer_lexmapfile(height, width); } */
338 /* action lex_error {printf("input error: character %c in filename %s is invalid\n = %s\n", fc, str, p);} */
339
340 /* #This machine determines the type of file we are lexing */
341 /* #and calls the appropriate machine to handle it. */
342
343 /* #TODO add mapping name */
344 /* width = digit+ %set_width; */
345 /* height = digit+ %set_height; */
346
347 /* set_hw := height . '_' . width [\0] %to(call_lmf); */
348
349 /* tok_segment = alnum; */
350 /* map_end = 'm' . '_' %to(call_ml); */
351 /* tok_end = alnum+ . [\0] %to(call_tl); */
352
353 /* file_matcher := (tok_segment+ . '_' )+ ( map_end | tok_end ); */
354
355 /* write data; */
356 /* }%% */
357
358 /* int */
359 /* lexer_matchfile */
360 /* (char* str, int size) */
361 /* { *p, *pe; */
362 /* char* ts; */
363 /* int cs, ntok, height, width; */
364
365 /* p = str; */
366 /* pe = p + size; */
367 /* height = width = 0; */
368
369 /* printf("Checking if filename is a map file:: filename = %s, p = %c, pe = %c\n", str, *p, *pe); */
370
371 /* %%write init; */
372 /* %%write exec noend; */
373
374 /* printf("Ending lexer_ismapfile on %s\n", str); */
375
376 /* return ntok; */
377 /* } */
378
379 /* %%{ */
380 /* machine vartype; */
381
382 /* action isele {return 0;} */
383 /* action ismodel {return 1;} */
384
385 /* set_name = alpha+; */
386 /* ele_name = alpha+; */
387 /* model_name = alpha+; */
388
389 /* ele = set_name '_' model_name '_' ele_name %isele; */
390 /* model = set_name '_' model_name [\0] %ismodel; */
391
392
393 /* ismodel := (ele | model); */
394
395 /* write data; */
396
397 /* }%% */
398
399 /* int */
400 /* lexer_ismodel */
401 /* (uint8_t* str, int size) */
402 /* { uint8_t *p, *pe, *eof; */
403 /* int cs; */
404
405 /* p = str; */
406 /* pe = p + size + 1; */
407
408 /* %%write init; */
409 /* %%write exec; */
410
411
412 /* } */