identifiers are now [a-z][a-b0-9]*
[henge/apc.git] / src / lexer.rl
index 36a72ab..9b4dc41 100644 (file)
@@ -10,15 +10,34 @@ extern //lexer.c
 void lexer_pushtok(int, YYSTYPE);
 /* Public */
 int lexer_setdirection(uint8_t*, int);
-int lexer_lexstring(uint8_t*, int);
+int lexer_lexfile(const uint8_t*);
+int lexer_lexstring(const uint8_t*, int);
 int lexer_setstr(uint8_t*, int);
+//apc.c
+extern
+yypstate* apc_pstate;
+extern
+yycstate* apc_cstate;
+#define PUSHTOK(T,L) yypush_parse(apc_pstate, T, (YYSTYPE*)(L), apc_cstate)
+#define LEXTOK(T,L) do {                       \
+    PUSHTOK(T,L);                              \
+    ntok++;                                    \
+  } while (0);
+#define LEXFACE(F) do {                                \
+    lval.face = F;                             \
+    LEXTOK(FACING, &lval.face);                        \
+  } while (0);
+
+/* Lexstring is the main lexer for APC and is generated by ragel. It lexes file names of files 
+   that have been scanned and pushes their types and values into the tok_stack, which yyparse 
+   eventually calls during parsing. */
 
 %%{    
   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);
+                          lval.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)
@@ -28,65 +47,55 @@ int lexer_setstr(uint8_t*, int);
                                }
                              exit(1);
                            }
-                          lexer_pushtok(REF, yylval); ntok++;
+                         LEXTOK(REF, &lval.ref);
                        }
-  action push_link      { lexer_pushtok(LINK,(YYSTYPE)0); ntok++; }
+  action push_link      { lval.val = 0;
+                          PUSHTOK(LINK, &lval.val); }
   action push_val       { te = NULL; errno = 0;
-                          yylval.val = strtoll((char*)ts,(char**)&te,10);
+                          lval.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);
+                         LEXTOK(NUM, &lval.val);
                         }
   action push_name      { printf("Lexer_lexstring:: action:push_name: from %s to %s\n", ts, p);
-                          lexer_pushtok(NAME, yylval);
-                         ntok++;
+                         LEXTOK(NAME, ts);
                         }
   action push_map       { printf("Lexer_lexstring:: action:push_map: pushing map token\n");
-                          yylval.str = (uint8_t*) '~';
-                          lexer_pushtok(MOPEN, yylval);
-                         ntok++;
+                          LEXTOK(MAP, "~");
                        }
   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++;
+                          LEXTOK(SS, "SS");
                         }
   action push_S         { printf("Lexer_lexstring:: action:push_S. p = %s\n", p);
-                          yylval.val = 0;
-                         lexer_pushtok(D, yylval);
+                         LEXFACE(SFACE);
                         }
   action push_SW        { printf("Lexer_lexstring:: action:push_SW. p = %s\n", p);
-                          yylval.val = 1;
-                         lexer_pushtok(D, yylval);
-                        }
+                          LEXFACE(SWFACE);
+                       }
   action push_W         { printf("Lexer_lexstring:: action:push_W. p = %s\n", p);
-                          yylval.val = 2;
-                         lexer_pushtok(D, yylval);
+                          LEXFACE(WFACE);
                         }
   action push_NW        { printf("Lexer_lexstring:: action:push_NW. p = %s\n", p);
-                          yylval.val = 3;
-                         lexer_pushtok(D, yylval);
+                         LEXFACE(NWFACE);
                         }
   action push_N         { printf("Lexer_lexstring:: action:push_N. p = %s\n", p);
-                          yylval.val = 4;
-                         lexer_pushtok(D, yylval);
+                          LEXFACE(NFACE);
                         }
   action push_NE        { printf("Lexer_lexstring:: action:push_NE. p = %s\n", p);
-                          yylval.val = 5;
-                         lexer_pushtok(D, yylval);
+                         LEXFACE(NEFACE);
                         }
   action push_E         { printf("Lexer_lexstring:: action:push_N. p = %s\n", p);
-                          yylval.val = 6;
-                         lexer_pushtok(D, yylval);
+                         LEXFACE(EFACE);
                         }
   action push_SE        { printf("Lexer_lexstring:: action:push_N. p = %s\n", p);
-                          yylval.val = 7;
-                         lexer_pushtok(D, yylval);
+                         LEXFACE(SEFACE);
+                        }
+  action ref_error      { printf("ref from %s to %s has an inappropriate amount of hex digits, it must have eight.\n", ts, p);
+                          exit(1);
                         }
-  #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;
@@ -98,18 +107,15 @@ int lexer_setstr(uint8_t*, int);
   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;
+  ref = '0x' >set_ts alnum{8} $err(ref_error) %push_ref ;
   val = digit+ >set_ts %push_val ;
-  name = (lower+ >set_ts) %push_name ;
+  name = lower >set_ts (lower | digit)*  %push_name ;
   map = '+MAP' %to(push_map);
   tok = (name | val | ref | dimensions | map | link | SS | direction);
   
@@ -121,16 +127,18 @@ int lexer_setstr(uint8_t*, int);
 }%%
 
 int lexer_lexstring
-( uint8_t* str, 
+( const uint8_t* str, 
   int size
 )
-{ uint8_t *p; 
-  uint8_t *ts, *pe, *te;
-  int cs, ntok;//, tok_t;
+{ const uint8_t *p; 
+  const uint8_t *ts, *pe, *te, *eof;
+  int cs, ntok;
+  YYSTYPE lval;
 
   ntok = 0;
   p = ts = str;
-  pe = p + size + 1;
+  pe = eof =  p + size + 1;
+  
 
   printf("|---Begin lexstring on p = %s, pe = %s.\n",p, pe);
 
@@ -142,6 +150,26 @@ int lexer_lexstring
   return ntok;
 }
 
+/* Lexical analysis of a file
+   Strips a filename to its base name, then sends it to lexer_lexstring before
+   pushing a PATH token with the filename
+   Returns the number of tokens pushed to the parser.
+*/
+int lexer_lexfile
+( uint8_t const* filename )
+{ uint8_t const* last_period,* iter;
+  int            ntok;
+  last_period = NULL;
+  for (iter = filename; *iter; iter++)
+    if (*iter ==  '.')
+      last_period = iter;
+  ntok = (last_period) ?
+    lexer_lexstring(filename, (int)(last_period - filename))
+  : lexer_lexstring(filename, (int)(iter - filename));
+  PUSHTOK(PATH,&filename);
+  return ntok + 1;
+  return en_main == 1;
+}
 
 /**************************/
 /****Abandon All Hope******/