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