X-Git-Url: https://www.kengrimes.com/gitweb/?p=henge%2Fapc.git;a=blobdiff_plain;f=src%2Flexer.rl;fp=src%2Flexer.rl;h=36a72abf747f0a47de3cc5e999e26734ae824d96;hp=0000000000000000000000000000000000000000;hb=6a37e5819abe57422b43d1b356f97e3191ab8850;hpb=10795ddac027be6e3edff27aa8da8d69aee9e454 diff --git a/src/lexer.rl b/src/lexer.rl new file mode 100644 index 0000000..36a72ab --- /dev/null +++ b/src/lexer.rl @@ -0,0 +1,376 @@ +#include +#include +#include +#include +#include "parser.tab.h" +#include "apc.h" +#include +#include +extern //lexer.c +void lexer_pushtok(int, YYSTYPE); +/* Public */ +int lexer_setdirection(uint8_t*, int); +int lexer_lexstring(uint8_t*, int); +int lexer_setstr(uint8_t*, int); + +%%{ + machine lexstring; + + # set up yylval and tok_t to be pushed to stack + action push_ref { te = NULL; errno = 0; + yylval.ref = strtoll((char*)ts,(char**)&te,16); + if (errno | (te != NULL)) + { fprintf(stderr, "Invalid hex number in file %s\n",(char*)str); + if (te != NULL) + { while (str++ < te) + fputc(' ', stderr); + fputc('^', stderr); + } + exit(1); + } + lexer_pushtok(REF, yylval); ntok++; + } + action push_link { lexer_pushtok(LINK,(YYSTYPE)0); ntok++; } + action push_val { te = NULL; errno = 0; + yylval.val = strtoll((char*)ts,(char**)&te,10); + if (errno) + { fprintf(stderr, "strtoll could not parse %s\n", (char*)str); + exit(1); + } + lexer_pushtok(NUM, yylval); + } + action push_name { printf("Lexer_lexstring:: action:push_name: from %s to %s\n", ts, p); + lexer_pushtok(NAME, yylval); + ntok++; + } + action push_map { printf("Lexer_lexstring:: action:push_map: pushing map token\n"); + yylval.str = (uint8_t*) '~'; + lexer_pushtok(MOPEN, yylval); + ntok++; + } + action set_ts { printf("Lexer_lexstring:: action:set_ts. ts = %s\n", p); ts = p; } + action push_SS { printf("Lexer_lexstring:: action:push_SS. p = %s\n",p); + yylval.str = (uint8_t*) "SS"; + lexer_pushtok(SS, yylval); + ntok++; + } + action push_S { printf("Lexer_lexstring:: action:push_S. p = %s\n", p); + yylval.val = 0; + lexer_pushtok(D, yylval); + } + action push_SW { printf("Lexer_lexstring:: action:push_SW. p = %s\n", p); + yylval.val = 1; + lexer_pushtok(D, yylval); + } + action push_W { printf("Lexer_lexstring:: action:push_W. p = %s\n", p); + yylval.val = 2; + lexer_pushtok(D, yylval); + } + action push_NW { printf("Lexer_lexstring:: action:push_NW. p = %s\n", p); + yylval.val = 3; + lexer_pushtok(D, yylval); + } + action push_N { printf("Lexer_lexstring:: action:push_N. p = %s\n", p); + yylval.val = 4; + lexer_pushtok(D, yylval); + } + action push_NE { printf("Lexer_lexstring:: action:push_NE. p = %s\n", p); + yylval.val = 5; + lexer_pushtok(D, yylval); + } + action push_E { printf("Lexer_lexstring:: action:push_N. p = %s\n", p); + yylval.val = 6; + lexer_pushtok(D, yylval); + } + action push_SE { printf("Lexer_lexstring:: action:push_N. p = %s\n", p); + yylval.val = 7; + lexer_pushtok(D, yylval); + } + #action lex_error { printf("input error: character %c in filename %s is invalid\n p = %s\n", fc, str, p);} + action p { printf("Lexer_lexstring:: p = %s\n", p);} + + N = 'N' %push_N; + W = 'W' %push_W; + S = 'S' %push_S; + E = 'E' %push_E; + NW = 'NW' %push_NW; + NE = 'NE' %push_NW; + SW = 'SW' %push_SW; + SE = 'SE' %push_SE; + + #what goes in between tokens in a filename + tok_delimiter = [_]; + + #types of tokes a filename can contain + direction = (N | W | S | E | NW | NE | SW | SE) ; + #make sure 0x123123 doesnt get mistaken for a ref + dimensions = (digit+ - '0') >set_ts %push_val 'x' (digit+ - '0') >set_ts %push_val; + link = '#' %push_link; + SS = ('+SS' %to(push_SS)) | ('+SS' %to(push_SS) link ) ; + ref = '0x' >set_ts alnum+ %push_ref; + val = digit+ >set_ts %push_val ; + name = (lower+ >set_ts) %push_name ; + map = '+MAP' %to(push_map); + tok = (name | val | ref | dimensions | map | link | SS | direction); + + + main := (tok tok_delimiter)+ tok [\0]; + + write data nofinal noerror noprefix; + +}%% + +int lexer_lexstring +( uint8_t* str, + int size +) +{ uint8_t *p; + uint8_t *ts, *pe, *te; + int cs, ntok;//, tok_t; + + ntok = 0; + p = ts = str; + pe = p + size + 1; + + printf("|---Begin lexstring on p = %s, pe = %s.\n",p, pe); + + %%write init; + %%write exec; + + printf("Ending lexstring of file %s, pushed %d tokens.\n",str, ntok); + + return ntok; +} + + +/**************************/ +/****Abandon All Hope******/ +/**************************/ +/*** ***/ +/*** ***/ +/*** ***/ +/*** ***/ + + +#if 0 + +%%{ + machine setdirection; + + action ret_north {printf("Lexer_setdirection:: direction is north, returning 4\n"); return 4;; } + action ret_west { printf("Lexer_setdirection:: direction is west, returning 2\n");return 2;} + action ret_east { printf("Lexer_setdirection:: direction is east, returning 6\n");return 6;} + action ret_south { printf("Lexer_setdirection:: direction is south, returning 0\n");return 0;} + action ret_northeast { printf("Lexer_setdirection:: direction is northeast, returning 5\n");return 5 ;} + action ret_northwest { printf("Lexer_setdirection:: direction is northwest, returning 3\n");return 3;} + action ret_southeast { printf("Lexer_setdirection:: direction is southeast, returning 7\n");return 7;} + action ret_southwest { printf("Lexer_setdirection:: direction is southwest, returning 1\n");return 1;} + + def = [_\0] %to(ret_south); + N = 'N'[_\0] %to(ret_north); + W = 'W' [_\0] %to(ret_west); + S = 'S' [_\0] %to(ret_south); + E = 'E' [_\0] %to(ret_east); + NW = 'NW' [_\0] %to(ret_northwest); + NE = 'NE' [_\0] %to(ret_northeast); + SW = 'SW' [_\0] %to(ret_southwest); + SE = 'SE' [_\0] %to(ret_southeast); + + direction = (N | W | S | E | NW | NE | SW | SE | def); + + main := direction; + + write data nofinal noprefix noerror; + + +}%% + + +int +lexer_setdirection +(uint8_t* str, int size) +{ uint8_t *p, *pe, *eof; + int cs; + + + p = str; + pe = str + size + 1; + + printf("|--- Begin lexer_setdirection str = %s, p = %s, pe = %s ---|\n", str,p, pe); + + %%write init; + %%write exec noend; + + printf("|--- Error in: lexer_setdirection ---|\n"); + + return -1; +} + + + +%%{ + machine setstr; + + + action lex_setvlink {printf("Lexer_setstr:: Returning setvlink filetype for %s\n", str); type = 5; newstrt = lexer_lexsetvlink(str); fbreak;} + action lex_elevlink {printf("Lexer_setstr:: Returning elevlink filetype for %s\n", str); type = 6; newstrt = lexer_lexelevlink(str); fbreak;} + action lex_setmodel {printf("Lexer_setstr:: Returning setmodel filetype\n"); newstrt = lexer_lexsetmodel(str); type = 1; fbreak;} + action lex_setmap {printf("Lexer_setstr:: Returning setmap filetype\n"); newstrt = lexer_lexsetmap(str); type = 2; fbreak;} + action lex_elemodel {printf("Lexer_setstr:: Returning elemodel filetype for %s\n", str); newstrt = lexer_lexelemodel(str); type = 3; fbreak;} + action lex_elemap {printf("Lexer_setstr:: Returning elemap filetype for %s\n", str); newstrt = lexer_lexelemap(str); type = 4; fbreak;} + action lex_setolink { printf("Lexer_setstr:: Returning setolink filetype\n"); type = 8; newstrt = lexer_lexsetolink(str); fbreak;} + action lex_eleolink { printf("Lexer_setstr:: Returning eleolink filetype\n"); type = 7; newstrt = lexer_lexeleolink(str); fbreak;} + action p {printf("p = %s \n",p);} + 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);} + + + N = 'N'; + W = 'W'; + S = 'S'; + E = 'E'; + NW = 'NW'; + NE = 'NE'; + SW = 'SW'; + SE = 'SE'; + + SS = 'SS'; + direction = (N | W | S | E | NW | NE | SW | SE) $p; + + SSD = SS direction; + + + + name = alpha+ $p - SSD $p; + num = digit+ $p; + ref = '0x' $p alnum+ $p; + + + set_label = name | (name '_' ref); + ele_label = name | (name '_' ref); + + model_types = (name) | (name '_' num '_' num) | (name '_' num); + + + set_model = set_label '_' SS %to(lex_setmodel); + set_map = set_label '_' '~' %to(lex_setmap); + ele_model = set_label '_' ele_label '_' SS %to(lex_elemodel); + ele_map = set_label '_' ele_label '_' '~' %to(lex_elemap); + set_olink = ref %to(lex_setolink) [\0] ; + ele_olink = set_label '_' '~' '_' ref [\0] %to(lex_eleolink); + set_vlink = set_label '_' '#' '_' (ref | ref '_' name) [\0] %to(lex_setvlink); + ele_vlink = set_label '_' ele_label '_' '#' '_' (ref | ref '_' name) [\0] %to(lex_elevlink); + + main := (ele_map | set_model | set_map |ele_model | ele_vlink | set_vlink | set_olink | ele_olink); + + write data; + + +}%% + +int +lexer_setstr +(uint8_t* str, int size) +{ uint8_t *p, *pe, *eof; + int cs, type, newstrt; + + type = newstrt = 0; + + p = str; + pe = str + size + 1; + + printf("|--- Begin lexer_setstr with str = %s, p = %s, pe = %s ---|\n", str,p, pe); + + %%write init; + %%write exec noend; + + printf("|--- End lexer_setstr. Incrementing str by %d, type is %d ---|\n", newstrt, type); + + return newstrt; +} + +#endif + + +/* %%{ */ +/* machine file_matcher; */ + +/* action call_ml { ts = p; fgoto set_hw ;} */ +/* action call_tl { return 0;} */ +/* action set_height {height = ttov(p, p-ts+1); ts = p;} */ +/* action set_width { width = ttov(p, p-ts+1);} */ +/* action call_lmf {lexer_lexmapfile(height, width); } */ +/* action lex_error {printf("input error: character %c in filename %s is invalid\n = %s\n", fc, str, p);} */ + +/* #This machine determines the type of file we are lexing */ +/* #and calls the appropriate machine to handle it. */ + +/* #TODO add mapping name */ +/* width = digit+ %set_width; */ +/* height = digit+ %set_height; */ + +/* set_hw := height . '_' . width [\0] %to(call_lmf); */ + +/* tok_segment = alnum; */ +/* map_end = 'm' . '_' %to(call_ml); */ +/* tok_end = alnum+ . [\0] %to(call_tl); */ + +/* file_matcher := (tok_segment+ . '_' )+ ( map_end | tok_end ); */ + +/* write data; */ +/* }%% */ + +/* int */ +/* lexer_matchfile */ +/* (char* str, int size) */ +/* { *p, *pe; */ +/* char* ts; */ +/* int cs, ntok, height, width; */ + +/* p = str; */ +/* pe = p + size; */ +/* height = width = 0; */ + +/* printf("Checking if filename is a map file:: filename = %s, p = %c, pe = %c\n", str, *p, *pe); */ + +/* %%write init; */ +/* %%write exec noend; */ + +/* printf("Ending lexer_ismapfile on %s\n", str); */ + +/* return ntok; */ +/* } */ + +/* %%{ */ +/* machine vartype; */ + +/* action isele {return 0;} */ +/* action ismodel {return 1;} */ + +/* set_name = alpha+; */ +/* ele_name = alpha+; */ +/* model_name = alpha+; */ + +/* ele = set_name '_' model_name '_' ele_name %isele; */ +/* model = set_name '_' model_name [\0] %ismodel; */ + + +/* ismodel := (ele | model); */ + +/* write data; */ + +/* }%% */ + +/* int */ +/* lexer_ismodel */ +/* (uint8_t* str, int size) */ +/* { uint8_t *p, *pe, *eof; */ +/* int cs; */ + +/* p = str; */ +/* pe = p + size + 1; */ + +/* %%write init; */ +/* %%write exec; */ + + +/* } */