So, copying the code from Introduction to Compiler Construction in Unix I wind up with the snippet:
/* samplec.l snipped */
static struct rwtable { /* reserved word table */
char *rw_name; /* representation */
int rw_yylex; /* yylex() value */
} rwtable[] = { /* sorted */
"break", token(BREAK),
"continue", token(CONTINUE),
"else", token(ELSE),
"if", token(IF),
"int", token(INT),
"return", token(RETURN),
"while", token(WHILE)
};
/* samplec.l snipped */
When I lex the code everything seems fine
$ lex -v samplec.l
scanner options: -XvI8 -Cem
94/2000 NFA states
38/1000 DFA states (125 words)
16 rules
Compressed tables always back-up
Beginning-of-line patterns used
1/40 start conditions
60 epsilon states, 27 double epsilon states
10/100 character classes needed 144/500 words of storage, 0 reused
105 state/nextstate pairs created
62/43 unique/duplicate transitions
40/1000 base-def entries created
69/2000 (peak 60) nxt-chk entries created
2/2500 (peak 30) template nxt-chk entries created
0 empty table entries
3 protos created
2 templates created, 3 uses
15/256 equivalence classes created
1/256 meta-equivalence classes created
2 (1 saved) hash collisions, 27 DFAs equal
0 sets of reallocations needed
489 total table entries needed
But, when I try to compile it, it fails:
$ gcc -c lex.yy.c -o lex.yy.o
samplec.l:75: error: initializer element is not constant
samplec.l:75: error: (near initialization for ‘rwtable[0].rw_yylex’)
# etc for each token(T)
What’s up? Is token() a macro that should be evaluated (but isn’t for some reason)? Or, should token() have been evaluated by lex?
Sorry, these sort of naive introductions are bad specifically in this situation – where bugs occur that you weren’t taught to understand 🙁 I guess there’s no skimping in learning tools.
token(x) was in fact a macro defined in the file I was working on viz. samplec.l
but of course I had a typo which omitted the x
Furthermore, I was missing 3 functions (undefined symbols): s_lookup, yyerror and yymark. The following chapter defines a small stub for yyerror and so I simply defined s_lookup and yymark as empty functions.
I don’t know if I should have to stub out s_lookup or yymark but the resulting parser worked.