在静态数组中使用令牌(T)编译lex.yy.c?

时间:2011-06-14 15:02:33

标签: arrays gcc lex

所以,从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()?

对不起,这种天真的介绍在这种情况下是特别糟糕的 - 在那里你没有被教导理解的错误:(我想在学习工具方面没有任何吝啬。

1 个答案:

答案 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但是生成的解析器有效。