在非结构或联合中要求成员“ sval”

问题描述

我在解析的玩具语言中出现错误。这是我的一些解析器代码

%union {
  char* <sval>;
}

%token INTEGER
%token INTDEC FLODEC AS
%token <sval> VARIABLE
%token POINT LBRACKET RBRACKET
%token SHOW ESC
%left '+' '-'
%left '*' '/' MODULO FACTORIAL FLOOR
%left '^'

%code requires {
  #define YYSTYPE float
}

还有我的一些词法分析器代码

    as                         {return AS;}
float                      {return FLODEC;}
show                       {return SHOW;}
int                        {return INTDEC;}
esc                        {return ESC;}
\.                         {return POINT;}
{integer}                  {yylval = atoi(yytext); return INTEGER;}
[a-zA-Z]+                  {yylval.sval = strdup(yytext); return VARIABLE;}
["\\"]                     {return FLOOR;}
[-+/=*^\n]                 {return *yytext;}
["("]                      {return LBRACKET;}
[")"]                      {return RBRACKET;}
["!"]                      {return FACTORIAL;}
["%%"]                     {return MODULO;}
[" \t\n"]
.                          {printf("Syntax error");}

我认为这实际上是一个工会,但我不确定该怎么办。

解决方法

char* <sval>;

不是有效的C成员声明,​​并且%union成员只是C成员声明。 (Yacc / bison将它们从字面上复制到union声明中。)因此,尝试编译该代码必然会在union YYSTYPE的声明中产生编译时错误消息。后续代码将无法使用union YYSTYPE,因为尚未正确声明,因此将产生显示的错误消息。

此外,一旦您声明语义类型为union,就需要相应地调整词法扫描器操作。您将无法编译

yylval = strdup(yytext);

因为yylval的类型为union YYSTYPE,并且union只能从另一个相同类型的union变量中分配。您需要将其更改为

yylval.sval = strdup(yytext);

您的其他yylval分配也需要以相同的方式处理,但是您在union声明中似乎没有合适的%union成员,因此您必须先解决这个问题。