仅将字符串与Flex/Bison一起使用

仅将字符串与Flex/Bison一起使用,bison,flex-lexer,Bison,Flex Lexer,我是Flex/Bison的新手。我只想对值使用字符串,这是一个语言转换器。我有这个测试: 例1: 但工作还是如期而至 如果我不使用define YYSTYPE char const*,而是使用%union: %union { char * txt; } %token <txt> NUMBER 并将赋值更改为[0-9]+{yylval.txt=strdupyytext;returnnumber;},它没有警告并且可以工作 我试着在flex文件中定义相同的YYSTYPE并强制执

我是Flex/Bison的新手。我只想对值使用字符串,这是一个语言转换器。我有这个测试:

例1:

但工作还是如期而至

如果我不使用define YYSTYPE char const*,而是使用%union:

%union {
   char * txt;
}

%token <txt> NUMBER
并将赋值更改为[0-9]+{yylval.txt=strdupyytext;returnnumber;},它没有警告并且可以工作

我试着在flex文件中定义相同的YYSTYPE并强制执行分配,但没有成功。怎么了?如何在不使用%union的情况下修复

谢谢。

在包含example.tab.h之前,您需要将define YYSTYPE char const*移动到example.l

如果您查看example.tab.h中的内容,您会发现如下内容:

#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef int YYSTYPE;
// ...
#endif
这意味着您需要在该代码之前定义YYSTYPE,即在include example.tab.h之前。否则,如果此时未定义YYSTYPE,则YYSTYPE将定义为int


另一种可能是使用bison特性%define api.value.type{char const*},这是需要放在example.y中的内容。在这种情况下,示例.tab.h将使用char const*类型的YYSTYPE生成。

最后的工作示例是:

例1:

示例y:


它起作用了!我明白插入.y就足够了。此外,我尝试过,但在加入example.tab.h之后。我看到Flex/Bison有一些手册中没有的技巧。谢谢顺便说一句,你的程序有内存泄漏。strdup使用malloc为string分配内存,但您的程序中没有任何空闲内存。是的,我知道。这不是我的程序,只是一个解释主要问题的例子。顺便说一句:在这个例子中,y必须在每种情况下执行free$1和free$3以确保避免内存泄漏?还有其他有用的选项吗?在你的简单示例中,我认为你找不到其他有用的选项。对于更高级的示例,您需要%union,将令牌类型定义为可以容纳指向char*或list的stringarray的所有指针的结构,并在Expression结束时释放它,在本示例中,您没有标记Expression结束的内容,例如\n或;。对于简单的示例,最好使用char字符串[20]作为YYSTYPE和strncpy,而不是strdup。还有更多好的,我理解。我知道%union,但我的编译器只是语言之间的翻译。我将考虑改用char字符串[NUM]。谢谢Komar。为了避免内存泄漏,您需要使用YYSTYPE作为char*并使用free:NUMBER%s\n,$1,$3;免费1元;免费$3;}等等你可以用valgrind检查你的程序是否有内存泄漏!最后一个示例包括您的建议。我探索了%define api.value.type{char const*}选项,我认为这样更好,因为它只在一个地方。所以,我只在我的.y中,在%标记声明之前使用它。
bison -d example.y
flex example.l
cc -o example example.tab.c lex.yy.c -lfl
example.l: In function ‘yylex’:
example.l:13:9: warning: assignment makes integer from pointer without a cast
 [0-9]+ { yylval=strdup(yytext); return NUMBER; }
         ^
%union {
   char * txt;
}

%token <txt> NUMBER
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef int YYSTYPE;
// ...
#endif
%option noyywrap nodefault

%{
#include <string.h>
#define YYSTYPE char *
#include "example.tab.h"
%}

%%

[ \t\n] {;}
"<="    {return LEFT;}
"=>"    {return RIGHT;}
[0-9]+ { yylval=strdup(yytext); return NUMBER; }
. { return yytext[0]; }

%%
%{
#include <stdio.h>
#define YYSTYPE char *
%}

%token NUMBER
%token LEFT "<=" RIGHT "=>"

%%

start: %empty | start tokens

tokens:
       NUMBER "<=" NUMBER { 
          printf("%s <= %s\n",$1,$3);
          free($1);
          free($3);
       }
     | NUMBER "=>" NUMBER {
          printf("%s => %s\n",$1,$3);
          free($1);
          free($3);
       }
     | NUMBER '>' NUMBER  {
          printf("%s > %s\n",$1,$3);
          free($1);
          free($3);
       }
     | NUMBER '<' NUMBER  {
          printf("%s < %s\n",$1,$3);
          free($1);
          free($3);
       }

%%

main(int argc, char **argv) { yyparse(); }
yyerror(char *s) { fprintf(stderr, "error: %s\n", s); }