仅使用带 Flex/Bison 的字符串
Using only string with Flex/Bison
我是 Flex/Bison 的新人。我只想使用字符串作为值(是语言翻译器)。我有这个要测试:
example.l:
%option noyywrap nodefault
%{
#include <string.h>
#include "example.tab.h"
%}
%%
[ \t\n] {;}
"<=" {return LEFT;}
"=>" {return RIGHT;}
[0-9]+ { yylval=strdup(yytext); return NUMBER; }
. { return yytext[0]; }
%%
example.y:
%{
#include <stdio.h>
#define YYSTYPE char const *
%}
%token NUMBER
%token LEFT "<=" RIGHT "=>"
%%
start: %empty | start tokens
tokens:
NUMBER "<=" NUMBER { printf("%s <= %s\n",,); }
| NUMBER "=>" NUMBER { printf("%s => %s\n",,); }
| NUMBER '>' NUMBER { printf("%s > %s\n",,); }
| NUMBER '<' NUMBER { printf("%s < %s\n",,); }
%%
main(int argc, char **argv) { yyparse(); }
yyerror(char *s) { fprintf(stderr, "error: %s\n", s); }
我编译的时候:
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; }
^
但如期而至。
如果我不使用 #define YYSTYPE char const *
而是使用 %union:
%union {
char * txt;
}
%token <txt> NUMBER
并将分配更改为 [0-9]+ { yylval.txt=strdup(yytext); return NUMBER; }
,它没有警告并且有效。
我试过在 flex 文件中定义相同的 YYSTYPE 并转换分配但没有成功。怎么了?如何在不使用 %union 的情况下修复?
谢谢。
您需要在 #include "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 中输入什么。在这种情况下,将使用 char const *
类型的 YYSTYPE 生成 example.tab.h。
最终的工作示例是:
example.l:
%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]; }
%%
example.y:
%{
#include <stdio.h>
#define YYSTYPE char *
%}
%token NUMBER
%token LEFT "<=" RIGHT "=>"
%%
start: %empty | start tokens
tokens:
NUMBER "<=" NUMBER {
printf("%s <= %s\n",,);
free();
free();
}
| NUMBER "=>" NUMBER {
printf("%s => %s\n",,);
free();
free();
}
| NUMBER '>' NUMBER {
printf("%s > %s\n",,);
free();
free();
}
| NUMBER '<' NUMBER {
printf("%s < %s\n",,);
free();
free();
}
%%
main(int argc, char **argv) { yyparse(); }
yyerror(char *s) { fprintf(stderr, "error: %s\n", s); }
我是 Flex/Bison 的新人。我只想使用字符串作为值(是语言翻译器)。我有这个要测试:
example.l:
%option noyywrap nodefault
%{
#include <string.h>
#include "example.tab.h"
%}
%%
[ \t\n] {;}
"<=" {return LEFT;}
"=>" {return RIGHT;}
[0-9]+ { yylval=strdup(yytext); return NUMBER; }
. { return yytext[0]; }
%%
example.y:
%{
#include <stdio.h>
#define YYSTYPE char const *
%}
%token NUMBER
%token LEFT "<=" RIGHT "=>"
%%
start: %empty | start tokens
tokens:
NUMBER "<=" NUMBER { printf("%s <= %s\n",,); }
| NUMBER "=>" NUMBER { printf("%s => %s\n",,); }
| NUMBER '>' NUMBER { printf("%s > %s\n",,); }
| NUMBER '<' NUMBER { printf("%s < %s\n",,); }
%%
main(int argc, char **argv) { yyparse(); }
yyerror(char *s) { fprintf(stderr, "error: %s\n", s); }
我编译的时候:
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; }
^
但如期而至。
如果我不使用 #define YYSTYPE char const *
而是使用 %union:
%union {
char * txt;
}
%token <txt> NUMBER
并将分配更改为 [0-9]+ { yylval.txt=strdup(yytext); return NUMBER; }
,它没有警告并且有效。
我试过在 flex 文件中定义相同的 YYSTYPE 并转换分配但没有成功。怎么了?如何在不使用 %union 的情况下修复?
谢谢。
您需要在 #include "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 中输入什么。在这种情况下,将使用 char const *
类型的 YYSTYPE 生成 example.tab.h。
最终的工作示例是:
example.l:
%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]; }
%%
example.y:
%{
#include <stdio.h>
#define YYSTYPE char *
%}
%token NUMBER
%token LEFT "<=" RIGHT "=>"
%%
start: %empty | start tokens
tokens:
NUMBER "<=" NUMBER {
printf("%s <= %s\n",,);
free();
free();
}
| NUMBER "=>" NUMBER {
printf("%s => %s\n",,);
free();
free();
}
| NUMBER '>' NUMBER {
printf("%s > %s\n",,);
free();
free();
}
| NUMBER '<' NUMBER {
printf("%s < %s\n",,);
free();
free();
}
%%
main(int argc, char **argv) { yyparse(); }
yyerror(char *s) { fprintf(stderr, "error: %s\n", s); }