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