如何给lex和yacc中的文字赋一个索引值?

时间:2015-01-12 14:16:13

标签: c yacc lex

说我的语法如下:

dish: fruit type ';';
fruit: "apple" | "strawberry" | "pear";
type: "pie" | "cheesecake" | "flan";

...我有一个存储这些菜肴的功能:

bool storeDish(int fruit, int type);

我如何有效地告诉lex或yacc(我不知道哪些)我想要" apple"得到一个值0,"草莓"有一个值1,"梨"有一个值2,"馅饼"价值0,"芝士蛋糕"有一个值1和" flan"有一个值2?

2 个答案:

答案 0 :(得分:2)

您可以在%union中定义数字类型,将非终结符定义为该数字类型,存储每个水果和类型的值,然后按索引在菜肴规则中访问它们。枚举将是首选,但这是一个例子。

/* Define types, you will need to define one for each type of nonterminal */
%union
{
    int     numeric;
}

/* Specify the type of the nonterminal */
%type<numeric> fruit type

...

%%

...

/* Fruits value accessible by $1 and type by $2 */
dish
    : fruit type ';';
        { storeDish($1, $2); }
    ;

/* Assign each fruit and type a numeric value */
fruit
    : "apple" 
        { $$ = 0; }
    | "strawberry" 
        { $$ = 1; }
    | "pear"
        { $$ = 2; }
    ;
type
    : "pie" 
        { $$ = 0; }
    | "cheesecake"
        { $$ = 1; } 
    | "flan"
        { $$ = 2; }
    ; 

http://dinosaur.compilertools.net/bison/bison_6.html#SEC53

答案 1 :(得分:0)

@Joe,或者你可以让yylex识别单词,在yylval中放置水果的枚举值,并给yacc标记FRUIT。使用FRUIT的产品的C代码现在可以访问yylval中看到的水果类型:

fruits:
    fruits fruit
    | fruit  
    ;
fruit : FRUIT           {if ($1==1) printf("seen strawberry\n"); }

(注意:我的yacc生锈了;希望我没有错误。)