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