yylval.str=strdup(yytext);为什么不能直接用yytext作为token的返回值
时间: 2024-03-29 07:38:11 浏览: 177
在编写词法分析器时,我们需要定义每个 token 的类型和属性值。其中属性值通常是一个字符串,用来表示 token 的具体值。在这个语句中,我们使用了一个名为 yylval 的结构体来保存 token 的属性值。
yytext 是 Flex 自动生成的一个全局变量,用来表示当前识别出的 token 的文本。但是,yytext 的生命周期只在当前识别到的 token 的位置有效。一旦识别到下一个 token,yytext 的值就会被更新。因此,如果我们直接把 yytext 作为 token 的返回值,就会出现错误。
为了避免这种错误,我们通常会使用 strdup 函数来复制 yytext 的值。strdup 函数会在堆上分配一段内存,并将 yytext 的值复制到该内存中。这样,我们就可以在 yylval 中保存一个独立的字符串,而不必担心它的生命周期问题。
相关问题
读取yytext的字符并转化成字符指针赋值给yylval
在 Flex 语法中,要将 yytext 的字符数组转换为字符指针并赋值给 yylval,可以使用 strdup 函数。strdup 函数是 C 标准库中的一个字符串函数,用于复制一个字符串并返回一个指向复制后字符串的指针。使用该函数可以将 yytext 的字符数组复制到动态分配的内存空间中,并返回一个指向该内存空间的指针,然后将该指针赋值给 yylval 即可。
具体来说,可以在 Flex 语法文件中使用以下代码:
```c
%%
/* 定义词法规则 */
...
%%
/* 定义动作 */
{
/* 将 yytext 的字符数组复制到动态分配的内存空间中,并赋值给 yylval */
yylval = strdup(yytext);
/* 返回对应的记号 */
return CHAR_PTR_TOKEN;
}
```
在上面的代码中,使用 strdup 函数将 yytext 的字符数组复制到动态分配的内存空间中,并返回一个指向该内存空间的指针,然后将该指针赋值给 yylval,最后返回对应的记号 CHAR_PTR_TOKEN。
需要注意的是,在使用完 yylval 后,需要手动释放动态分配的内存空间,以免出现内存泄漏。可以在词法分析器的主函数中使用 free 函数释放内存空间,例如:
```c
int main() {
/* 创建词法分析器 */
yylex();
/* 释放动态分配的内存空间 */
if (yylval != NULL) {
free(yylval);
}
return 0;
}
```
json.l:21:7: error: subscripted value is neither array nor pointer nor vector yylval[strlen(yylval)-1]=0;修改后出现以下错误
这个错误是因为 yylval 是一个 YYSTYPE 类型的变量,而不是一个字符串类型的数组,所以不能使用字符串的下标操作。正确的做法是将 yylval 强制转换为字符串类型,然后再使用字符串函数。修改代码如下:
```c
desc : %%
{str} {
yylval.str = strdup(yytext+1);
yylval.str[strlen(yylval.str)-1]=0;
return STR;
}
{def} {
if(strcmp(yytext,"true")==0){
return TRUE;
}else if(strcmp(yytext,"false")==0){
return FALSE;
}else if(strcmp(yytext,"null")==0){
return NIL;
}else{
yylval.str = strdup(yytext);
return STR;
}
}
{num} {
yylval.str = strdup(yytext);
return NUM;
}
{arrs} { return ARRS; }
{arre} { return ARRE; }
{objs} { return OBJS; }
{obje} { return OBJE; }
{desc} { return DESC; }
{split} { return SPLIT; }
{space} {}
%%
```
同时,记得在 json.y 中将 YYSTYPE 定义为:
```c
%union {
char *str;
}
%token<str> STR
%token<str> NUM
```
这样就可以正确地读取字符串并将其保存到 YYSTYPE 类型的变量中了。
阅读全文