如何给 lex 和 yacc 中的文字一个索引值?
How to give an index value to literals in lex and yacc?
假设我有如下语法:
dish: fruit type ';';
fruit: "apple" | "strawberry" | "pear";
type: "pie" | "cheesecake" | "flan";
...我有一个功能来存储这些菜:
bool storeDish(int fruit, int type);
我如何有效地告诉 lex 或 yacc(我不知道是哪个)我希望 "apple" 的值为 0,"strawberry" 的值为 1,"pear" 的值为 2,"pie" 的值为 0,"cheesecake" 的值为 1,"flan" 的值为 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 and type by */
dish
: fruit type ';';
{ storeDish(, ); }
;
/* Assign each fruit and type a numeric value */
fruit
: "apple"
{ $$ = 0; }
| "strawberry"
{ $$ = 1; }
| "pear"
{ $$ = 2; }
;
type
: "pie"
{ $$ = 0; }
| "cheesecake"
{ $$ = 1; }
| "flan"
{ $$ = 2; }
;
@Joe,或者你可以让 yylex 识别这些词,把在 yylval 中看到的水果的枚举值放在 yylval 中,并给 yacc 令牌 FRUIT。使用 FRUIT 的产品的 C 代码现在可以访问在 yylval 中看到的水果类型:
fruits:
fruits fruit
| fruit
;
fruit : FRUIT {if (==1) printf("seen strawberry\n"); }
(注意:我的 yacc 已经生锈了;希望我没有出错。)
假设我有如下语法:
dish: fruit type ';';
fruit: "apple" | "strawberry" | "pear";
type: "pie" | "cheesecake" | "flan";
...我有一个功能来存储这些菜:
bool storeDish(int fruit, int type);
我如何有效地告诉 lex 或 yacc(我不知道是哪个)我希望 "apple" 的值为 0,"strawberry" 的值为 1,"pear" 的值为 2,"pie" 的值为 0,"cheesecake" 的值为 1,"flan" 的值为 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 and type by */
dish
: fruit type ';';
{ storeDish(, ); }
;
/* Assign each fruit and type a numeric value */
fruit
: "apple"
{ $$ = 0; }
| "strawberry"
{ $$ = 1; }
| "pear"
{ $$ = 2; }
;
type
: "pie"
{ $$ = 0; }
| "cheesecake"
{ $$ = 1; }
| "flan"
{ $$ = 2; }
;
@Joe,或者你可以让 yylex 识别这些词,把在 yylval 中看到的水果的枚举值放在 yylval 中,并给 yacc 令牌 FRUIT。使用 FRUIT 的产品的 C 代码现在可以访问在 yylval 中看到的水果类型:
fruits:
fruits fruit
| fruit
;
fruit : FRUIT {if (==1) printf("seen strawberry\n"); }
(注意:我的 yacc 已经生锈了;希望我没有出错。)