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