Flex 和 Bison $variables 给出意想不到的值

Flex and Bison $variables giving unexpected values

在我的词法分析器文件中,我为标记“name”设置了“yylval.str = yytext”。然后在我的野牛文件中,我尝试读取该 str 值以获取字符串形式的名称。但是,当我读到 $2 时,我最终不仅得到了令牌名称,还得到了该行的其余部分。

例如,一行可以是“MOVE Z TO XY”,其中 Z 和 XY 都是名称。在这种情况下,我希望 $2 的值为“Z”,$4 的值为“XY”。 但实际发生的是 $2 的值为“Z TO XY”,而 $4 的值为“XY”。我想 $4 也有同样的问题,但行尾没有其他内容,所以不会引起任何问题。

为什么 $2 会像这样给出该行的其余部分?如何获取变量名称?



(缩短)词法分析器代码:

"MOVE"                  {return (MOVE);}
"TO"                    {return (TO);}
([0-9])+                {yylval.num = atoi(yytext); return (INTEGER);}
[a-z][a-z0-9\-]*        {yylval.str = _strlwr(yytext); return (NAME);}

(缩短)解析器代码:

%token MOVE
%token TO
%token <num> INTEGER
%token <str> NAME
%union{
    int num;
    char *str;
}

move:
    MOVE NAME TO NAME PERIOD { printf("<Var1: %s>, <Var2: %s>", , );}
    | MOVE INTEGER TO NAME PERIOD { printf("<Val: %d>, <Var: %s>", , ); }

输入:

MOVE Z TO XY-1
MOVE 15 TO XY-1

输出:

<Var1: z TO xy-1>, <Var2: xy-1>
<Val: 15>, <Var: xy-1>

In my lexer file I set "yylval.str = yytext" for the token "name". Then in my bison file I try to read that str value to get the name as a string. However, when I read I end up getting not only the token name, but also the rest of the line.

这一点也不奇怪。 yytext 是指向输入缓冲区的指针(in),从当前匹配项的位置开始。当解析器查看 pointed-to 数据时,它们通常不是字符串,因为在标记字符之后通常没有字符串终止符(但请参见下文)。

此外,当解析器着手查看标记的语义值时,词法分析器可能已将新数据读入输入缓冲区,将原始标记文本从您的下方拉出。

How do I just get the variable name?

要将令牌文本作为您以后可以访问的字符串获取,并确保它不会被您修改,您需要复制它。那可能需要在 dynamically-allocated 内存中。 仅在词法分析器操作中,您可以依靠 Flex 提供的临时字符串终止符,因此您可以使用 strdup()(如果有)来制作这样的副本。您似乎正在使用 Microsoft 的 C 库,它确实有 strdup.

然后:

[a-z][a-z0-9\-]*        {
                            char *temp = strdup(yytext);
                            if (temp == NULL) { /* handle allocation error*/}
                            else {
                                yylval.str = _strlwr(temp); return (NAME);
                            }
                        }

您将需要确保在不再需要时,在指向它们的指针丢失之前,解析器释放您的标记的动态分配的语义值。