使用 Flex 和 Bison 解析字符串标记时出现问题
Issue while parsing a string token with Flex and Bison
我是 Flex 和 Bison 的初学者(我对 C 有一些基础知识),我正在创建一个简单的解析器。
这里的目标是填充以下结构:
struct numvariable {
int nodetype; /* type V */
char* value;
};
为了做到这一点,首先,我尝试在词法分析器中打印用户输入的 char*(工作:打印用户输入的值),然后在解析器中打印(不工作,空) .
这里是lexer.l文件中对应的行(这里正确打印了用户输入的字符串):
[a-zA-Z][a-zA-Z0-9]* {
char *yycopy = strdup(yytext);
printf("lexer %s\n", yycopy);
yylval.var == yycopy;
free(yycopy);
return NAME;
}
以下是 parser.y 文件:
%{
#include <stdio.h>
#include <stdlib.h>
#include <cstring>
#include "header.h"
extern int yylex(void);
struct ast *result;
%}
%union {
struct ast *a;
char *var;
}
%token <var> NAME
%type <a> exp
%%
calclist: /* nothing */
| calclist exp { result = ; }
;
exp: NAME { $$ = newvar(); }
;
%%
struct ast *newvar(char *val)
{
printf("parser %s\n", val);
struct numvariable *a =
(struct numvariable *)malloc(sizeof(struct numvariable));
a->nodetype = 'V';
// a->value = val;
return (struct ast *)a;
}
我尽量让它变得简单,如果有任何遗漏的信息需要理解这个问题,请告诉我。
我认为 $1 不是 char* 类型,但是它的类型是什么?以及如何将其转换为 char* ?我想我在词法分析器和解析器之间遗漏了一些东西,因为我不知道为什么 char* 打印在词法分析器中而不是在解析器中......
(应用于数字的相同代码(将 char* 更改为 double)完美运行...)
提前感谢您的帮助:)
I think is not of type char* but then, what is its type ?
如果某些东西没有正确的类型,编译器会产生一个错误或至少一个警告(除非你禁用了警告,正在显式地转换值或使用空指针,而你不在这个案件)。因此,当出现类型错误时,您通常会知道。这不是这里的问题。
char *yycopy = strdup(yytext);
// ...
yylval.var == yycopy;
free(yycopy);
在这里,您让 var
指向 strdup
返回的内存,然后立即释放该内存。所以 var
现在指向释放的内存,任何取消引用它的尝试都会导致未定义的行为。
你不应该为你的字符串释放内存,直到你完成对它们的处理(这很可能是程序的结束,因为这些字符串很可能最终会出现在你的 AST 中,也可能出现在 IR 中).
我是 Flex 和 Bison 的初学者(我对 C 有一些基础知识),我正在创建一个简单的解析器。
这里的目标是填充以下结构:
struct numvariable {
int nodetype; /* type V */
char* value;
};
为了做到这一点,首先,我尝试在词法分析器中打印用户输入的 char*(工作:打印用户输入的值),然后在解析器中打印(不工作,空) .
这里是lexer.l文件中对应的行(这里正确打印了用户输入的字符串):
[a-zA-Z][a-zA-Z0-9]* {
char *yycopy = strdup(yytext);
printf("lexer %s\n", yycopy);
yylval.var == yycopy;
free(yycopy);
return NAME;
}
以下是 parser.y 文件:
%{
#include <stdio.h>
#include <stdlib.h>
#include <cstring>
#include "header.h"
extern int yylex(void);
struct ast *result;
%}
%union {
struct ast *a;
char *var;
}
%token <var> NAME
%type <a> exp
%%
calclist: /* nothing */
| calclist exp { result = ; }
;
exp: NAME { $$ = newvar(); }
;
%%
struct ast *newvar(char *val)
{
printf("parser %s\n", val);
struct numvariable *a =
(struct numvariable *)malloc(sizeof(struct numvariable));
a->nodetype = 'V';
// a->value = val;
return (struct ast *)a;
}
我尽量让它变得简单,如果有任何遗漏的信息需要理解这个问题,请告诉我。
我认为 $1 不是 char* 类型,但是它的类型是什么?以及如何将其转换为 char* ?我想我在词法分析器和解析器之间遗漏了一些东西,因为我不知道为什么 char* 打印在词法分析器中而不是在解析器中...... (应用于数字的相同代码(将 char* 更改为 double)完美运行...)
提前感谢您的帮助:)
I think is not of type char* but then, what is its type ?
如果某些东西没有正确的类型,编译器会产生一个错误或至少一个警告(除非你禁用了警告,正在显式地转换值或使用空指针,而你不在这个案件)。因此,当出现类型错误时,您通常会知道。这不是这里的问题。
char *yycopy = strdup(yytext); // ... yylval.var == yycopy; free(yycopy);
在这里,您让 var
指向 strdup
返回的内存,然后立即释放该内存。所以 var
现在指向释放的内存,任何取消引用它的尝试都会导致未定义的行为。
你不应该为你的字符串释放内存,直到你完成对它们的处理(这很可能是程序的结束,因为这些字符串很可能最终会出现在你的 AST 中,也可能出现在 IR 中).