flex bison,从文件读取时遇到标记后标记化停止
flex bison, tokenizing stops after encountering a token while reading from a file
我是 flex 和 bison 的新手。我正在尝试编写一个接受字符串的简单语法:一个小写字母后跟一个大写字母。以下是我的文件-
file.l
%{
#include<stdio.h>
#include<string.h>
#include "y.tab.h"
int yywrap(void)
{
printf("parsing is done*\n");
//yylex();
//return 0;
}
%}
%%
[a-z]* { printf("found lower\n");
yylval=yytext;
return LOWER;
}
[A-Z]* { printf("found upper\n");
yylval=yytext;
return UPPER;
}
[ \n] ;
. ;
%%
void main()
{
yyin = fopen("file.txt", "r");
yylex();//this function will start the rules section.... it starts the parsing.....
fclose(yyin);
}//main ends
file.y
%{
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define YYSTYPE char *
int yylex(void);
void yyerror(const char *str)
{
fprintf(stderr,"error: %s\n",str);
}
%}
%token LOWER UPPER
%%
start :
|
start LOWER UPPER
{
printf("%s--%s\n",,);
}
%%
file.txt的内容是:
代币TOKEN
这就是我编译的方式 运行:
弹性file.l
yacc -d file.y
gcc lex.yy.c y.tab.c -o 文件
./文件
程序发出警告
警告:赋值从指针生成整数而不进行强制转换 [-Wint-conversion]
yylval=yytext;
当我 运行 程序(忽略警告)时,输出是 "found lower" 即程序在 return LOWER
后停止读取标记。任何人都可以帮助并告诉我为什么这个 运行ning 是这样的吗?还有为什么即使我在 file.y
中指定了 #define YYSTYPE char *
也会生成警告
1。为什么即使我在 file.y
中指定了 #define YYSTYPE char *
也会生成警告?
因为该定义在 file.l
中不可见。两个文件必须具有一致的 yytext
.
定义
此外,您应该知道简单地设置 yylval = yytext
永远是不正确的,因为 yytext
指向的缓冲区是词法扫描器的私有数据结构的一部分。如果需要将令牌的字符串值传递给解析器,则必须复制一份。
2。为什么 main
没有读取整个文件?
因为您从未实际调用名称为 yyparse
的解析器。如果你使用的是标准的 bison 解析器,你不应该直接调用 yylex
; yylex
由解析器在需要令牌时调用。 [注1]
因为yylex
只是returns一个单独的令牌,调用一次就会产生一个令牌。您可以按照评论中的建议在循环中调用它,但这仍然不会解析文件。
备注
- Bison 可以生成“push-parsers”,当词法分析器有可用的标记时,它会被调用。在那种情况下,词法分析器操作不会
return
直到整个输入被解析,并且你会调用 yylex
而不是 yyparse
。那可以简化某些语言的解析,但这里肯定不是这样。
我是 flex 和 bison 的新手。我正在尝试编写一个接受字符串的简单语法:一个小写字母后跟一个大写字母。以下是我的文件-
file.l
%{
#include<stdio.h>
#include<string.h>
#include "y.tab.h"
int yywrap(void)
{
printf("parsing is done*\n");
//yylex();
//return 0;
}
%}
%%
[a-z]* { printf("found lower\n");
yylval=yytext;
return LOWER;
}
[A-Z]* { printf("found upper\n");
yylval=yytext;
return UPPER;
}
[ \n] ;
. ;
%%
void main()
{
yyin = fopen("file.txt", "r");
yylex();//this function will start the rules section.... it starts the parsing.....
fclose(yyin);
}//main ends
file.y
%{
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define YYSTYPE char *
int yylex(void);
void yyerror(const char *str)
{
fprintf(stderr,"error: %s\n",str);
}
%}
%token LOWER UPPER
%%
start :
|
start LOWER UPPER
{
printf("%s--%s\n",,);
}
%%
file.txt的内容是:
代币TOKEN
这就是我编译的方式 运行:
弹性file.l
yacc -d file.y
gcc lex.yy.c y.tab.c -o 文件
./文件
程序发出警告 警告:赋值从指针生成整数而不进行强制转换 [-Wint-conversion] yylval=yytext;
当我 运行 程序(忽略警告)时,输出是 "found lower" 即程序在 return LOWER
后停止读取标记。任何人都可以帮助并告诉我为什么这个 运行ning 是这样的吗?还有为什么即使我在 file.y
#define YYSTYPE char *
也会生成警告
1。为什么即使我在 file.y
中指定了 #define YYSTYPE char *
也会生成警告?
因为该定义在 file.l
中不可见。两个文件必须具有一致的 yytext
.
此外,您应该知道简单地设置 yylval = yytext
永远是不正确的,因为 yytext
指向的缓冲区是词法扫描器的私有数据结构的一部分。如果需要将令牌的字符串值传递给解析器,则必须复制一份。
2。为什么 main
没有读取整个文件?
因为您从未实际调用名称为 yyparse
的解析器。如果你使用的是标准的 bison 解析器,你不应该直接调用 yylex
; yylex
由解析器在需要令牌时调用。 [注1]
因为yylex
只是returns一个单独的令牌,调用一次就会产生一个令牌。您可以按照评论中的建议在循环中调用它,但这仍然不会解析文件。
备注
- Bison 可以生成“push-parsers”,当词法分析器有可用的标记时,它会被调用。在那种情况下,词法分析器操作不会
return
直到整个输入被解析,并且你会调用yylex
而不是yyparse
。那可以简化某些语言的解析,但这里肯定不是这样。