Bison 打印出特定令牌类型的所有实例

Bison 打印出特定令牌类型的所有实例,bison,Bison,运行yyparse后,我想打印出输入中找到的所有VARNAMEs。我对yacc变量的内部结构知之甚少,不知道从哪里查找,谷歌也没有发现任何明显的问题 我可以修改bison规则,使用C变量跟踪这些标记,因为标记会一个接一个地出现,但是出于代码清晰的原因,如果在解析后一次完成所有这些操作,那就更好了 基本原则1: [A-Za-z_][A-Za-z0-9_]*\$? { yylval.s = yytext; return VARNAME; } 基本y: %un

运行
yyparse
后,我想打印出输入中找到的所有
VARNAME
s。我对yacc变量的内部结构知之甚少,不知道从哪里查找,谷歌也没有发现任何明显的问题

我可以修改bison规则,使用C变量跟踪这些标记,因为标记会一个接一个地出现,但是出于代码清晰的原因,如果在解析后一次完成所有这些操作,那就更好了

基本原则1:

[A-Za-z_][A-Za-z0-9_]*\$? {
          yylval.s = yytext;
          return VARNAME;
}
基本y:

%union {
  double d;
  GString *s;
}
%token <s> VARNAME

variable: VARNAME
{
  variable_t *new = malloc(sizeof(*new));
  new->name = $1;
  $$ = new;
}
%union{
双d;
GString*s;
}
%令牌变量名
变量:VARNAME
{
变量_t*new=malloc(sizeof(*new));
新建->名称=$1;
$$=新的;
}
(f)lex和yacc/bison都没有在令牌被消耗后(通过还原操作)尝试保存令牌。如果你想拯救他们,你需要自己去做


我通常在lexer中这样做,将每个ID标记添加到一个内部字符串表(即散列集)中。这使得存储管理更容易,因为我可以在解析完成后从哈希表中删除所有字符串。它还避免了重复字符串的不必要副本

请注意,您不能在yacc/bison操作中安全地使用
yytext
;因此,如果解析器需要引用具有多个可能字符串值的令牌的文本值,那么扫描器必须制作(或重用)一份
yytext
内容的副本


如果扫描器中的代码是从internet上找到的某个(f)lex文件复制的,我强烈建议您找到不同的型号。代码几乎肯定不起作用,因此它表明从未进行过任何非平凡的测试。

从lexer返回这样的文本是不安全的,因为它只有在读取下一个令牌之前才有效(bison可能需要在减少和运行操作之前先读取令牌)。您应该在lexer中分配
变量\u t
,并将yytext复制到其中。问题是yytext吗?如果是这样,strcpy会修复它吗?还是问题出在yylval方面?“通过将每个ID令牌添加到一个内部字符串表中:“-足够公平!