所以,从Introduction to Compiler Construction in Unix复制代码我最后会看到代码片段:
/* 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 */
当我把代码搞错时,一切都很好
$ 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
但是,当我尝试编译它时,它失败了:
$ 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)
怎么了? token()是一个应该被评估的宏(但不是出于某种原因)?或者,是否应该由lex评估token()?
对不起,这种天真的介绍在这种情况下是特别糟糕的 - 在那里你没有被教导理解的错误:(我想在学习工具方面没有任何吝啬。
答案 0 :(得分:0)
token(x)实际上是我正在处理的文件中定义的宏 viz。 samplec.l
#define token(x) x
但当然我有一个错字,省略了x
#define token(x)
此外,我缺少3个函数(未定义的符号):s_lookup,yyerror和yymark。下一章为yyerror定义了一个小存根,因此我只是将s_lookup和yymark定义为空函数。
我不知道是否应该删除s_lookup或yymark但是生成的解析器有效。