1 %{ 2 3 #include <assert.h> 4 //#define YYSTYPE struct token 5 #include <stdlib.h> 6 #include "ktrfmt.tab.h" 7 #include "tok.h" 8 #include "internal.h" 9 10 enum { 11 NR_TOKENS = 18, 12 }; 13 14 /* XXX: need to switch to reentrant lexer */ 15 static struct token tokens[NR_TOKENS]; 16 static int curr_tok; 17 static struct symtab *strtab; 18 19 static 20 struct token * 21 tok_new(void) 22 { 23 ++curr_tok; 24 if (curr_tok == NR_TOKENS) { 25 /* can't happen */ 26 fprintf(stderr, "Reached max number of tokens\n"); 27 abort(); 28 } 29 return &tokens[curr_tok]; 30 } 31 32 void 33 tok_free(struct token *tok) 34 { 35 assert(&tokens[curr_tok] == tok); 36 --curr_tok; 37 } 38 39 /* 40 * We keep track of strings we've seen before so string comparison 41 * can be done w/ a simple pointer comparison 42 */ 43 static 44 char * 45 newstr(const char *s) 46 { 47 void *r; 48 if (!strtab) 49 strtab = symtab_new(); 50 if ((r = symtab_find(strtab, s))) 51 return r; 52 if (!(r = strdup(s))) 53 return r; 54 symtab_insert(strtab, r, r); 55 return r; 56 } 57 58 %} 59 60 %option prefix="__ktrfmt" 61 %option outfile="ktrfmt.yy.c" 62 %option bison-bridge 63 %option noyywrap 64 %option nounput 65 66 INT [0-9]+ 67 HEX 0x[0-9a-fA-F]+ 68 WHITE [ \t\r] 69 ID [a-z_$][a-zA-Z0-9_]* 70 CTOR [A-Z][a-zA-Z0-9_]* 71 72 %% 73 {WHITE}+ { /* ignore */ } 74 \"(\\\"|[^"\n])+\" { 75 size_t len; 76 yylval->tok = tok_new(); 77 yylval->tok->type = TOK_STR; 78 len = strlen(yytext); 79 assert(yytext[len - 1] == '"'); 80 yytext[len - 1] = '\0'; /* kill trailing quote */ 81 printd(LEX, "newstr(\"%s\")\n", yytext + 1); 82 yylval->tok->str = newstr(yytext + 1); /* parser detects oom */ 83 yytext[len - 1] = '"'; /* restore quote */ 84 printd(LEX, "TOK_STR: \"%s\"\n", yylval->tok->str); 85 return TOK_STR; 86 } 87 {ID} { 88 yylval->tok = tok_new(); 89 yylval->tok->type = TOK_ID; 90 printd(LEX, "tok %p TOK_ID %p:%s\n", yylval->tok, yytext, yytext); 91 yylval->tok->str = newstr(yytext); /* parser detects oom */ 92 return TOK_ID; 93 } 94 {CTOR} { 95 yylval->tok = tok_new(); 96 yylval->tok->type = TOK_CTOR; 97 printd(LEX, "tok %p TOK_CTOR %p:%s\n", yylval->tok, yytext, yytext); 98 yylval->tok->str = newstr(yytext); /* parser detects oom */ 99 return TOK_CTOR; 100 } 101 {INT} { 102 yylval->tok = tok_new(); 103 yylval->tok->type = TOK_INT; 104 yylval->tok->str = strdup(yytext); /* parser detects oom */ 105 printd(LEX, "TOK_INT\n"); 106 return TOK_INT; 107 } 108 {HEX} { 109 yylval->tok = tok_new(); 110 yylval->tok->type = TOK_INT; 111 yylval->tok->str = strdup(yytext); /* parser detects oom */ 112 printd(LEX, "TOK_INT\n"); 113 return TOK_INT; 114 } 115 "=" { 116 yylval = NULL; 117 printd(LEX, "TOK_EQ\n"); 118 return TOK_EQ; 119 } 120 "." { 121 yylval = NULL; 122 printd(LEX, "TOK_DOT\n"); 123 return TOK_DOT; 124 } 125 "[" { 126 yylval = NULL; 127 printd(LEX, "TOK_LEFT_BRACK\n"); 128 return TOK_LEFT_BRACK; 129 } 130 "]" { 131 yylval = NULL; 132 printd(LEX, "TOK_RIGHT_BRACK\n"); 133 return TOK_RIGHT_BRACK; 134 } 135 136 %%