- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个扫描仪、解析器和一个主程序,我通过它创建一个可执行文件
bison -d parser.y;柔性扫描仪.l; gcc main.c parer.tab.c lex.yy.c
当我运行 ./a.out
时,它会执行我想要的操作:如果按下 Ctrl+D
,则会检测到 EOF
并且 main
可以采取相应的行动。这意味着:如果yyin
是stdin
,那么点击Return
就会结束该行的解析,并且主循环等待下一个输入行。按 Ctrl+D
在主循环中使用 break
结束解析输入并退出。如果输入来自文件,例如 testFile
,则该文件可以包含 1 个要解析的表达式,直到 EOF。在文件场景中,新行应该像空格和制表符一样被吃掉。当输入来自 stdin 时,所有这些都应该像解释器一样运行;当输入来自文件时,所有这些都应该像脚本评估器一样运行。此类测试文件的示例内容为:test\n
。这里没有检测到 EOF。我很难理解为什么会出现这种情况。换句话说,我想要问题的扩展 here额外处理输入文件
解析器.y:
%{
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
/* stuff from flex that bison needs to know about: */
int yylex();
int yyparse();
FILE *yyin;
static int parseValue;
void yyerror(const char *s);
%}
%token TWORD
%token TEOF
%token TJUNK
%start input
%%
input: word { printf("W"); parseValue = 1; }
| eof { printf("eof"); parseValue = -11;}
| /* empty */ { printf("_"); parseValue = -1; }
| error { printf("E"); parseValue = -2; }
;
eof: TEOF
;
word: TWORD
;
%%
void yyerror(const char *s) {
printf("nope...");
}
int getWord( FILE *file) {
int err;
if (file) {
yyin = file;
} else /* error */ {
printf("file not valid");
return -3;
}
err = yyparse();
if (!err) {
return parseValue;
} else /* error */ {
printf("parse error");
return -4;
}
}
扫描仪.l:
%{
#include <stdio.h>
#include "parser.tab.h"
#define YYSTYPE int
int yylex();
%}
/* avoid: implicit declaration of function ‘fileno’ */
/*%option always-interactive*/
%option noyywrap
/* to avoid warning: ‘yyunput’ defined but not used */
%option nounput
/* to avoid warning: ‘input’ defined but not used */
%option noinput
%%
<<EOF>> { return TEOF; }
[ \t] { }
[\n] { if (yyin == stdin) return 0; }
[a-zA-Z][a-zA-Z0-9]* { return TWORD; }
. { return TJUNK; }
%%
main.c:
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdbool.h>
int main(int argc, char *argv[]) {
int result = 0;
FILE *fOut = stdout, *fIn = stdin;
/* skip over program name */
++argv, --argc;
if ( argc > 0 ) {
fIn = fopen( argv[0], "r" );
}
while (true) {
fprintf(fOut, "\nTEST : ", result);
result = getWord(fIn);
if (result == -11) {
printf(" %i ", result); printf("--> EOF");
break;
}
if (result < 0) {
printf(" %i ", result); printf("--> <0");
/*continue;*/
break;
}
fprintf(fOut, " => %i", result);
}
fprintf(fOut, "\n\n done \n ");
exit(EXIT_SUCCESS);
}
我尝试根据建议重写解析 here或here ,但没有取得太大成功。从文件读取输入时, main 知道 EOF 的正确方法是什么?
更新:一种建议是,该问题可能是由于 \n
上的 return 0;
造成的。作为一个快速测试,如果 yyin == stin
我只返回 0,但调用 ./a.out testFile
仍然无法捕获 EOF
。更新2:我通过使用 yywrap 使其工作。我摆脱了所有 TEOF
的东西。扫描仪有一个部分:
extern int eof;
最后:
int yywrap() {
eof = 1;
return 1;
}
在解析器中有一个:
int eof = 0;
文件中的更下方:
err = yyparse();
if (err != 0) return -4;
else if (eof) return -11;
else return parseValue;
如果有人可以向我展示一个更优雅的解决方案,我仍然会很感激。 This可能是制作干净版本的好方法。
最佳答案
如链接中所述,flex
具有用于识别输入文件或流的末尾(例如,来自字符串的输入)的语法。
事实上,flex
始终有效地运行着这样的规则。默认情况下,该规则调用yywrap
。您将其关闭(使用 %noyywrap
)。没关系,除了...
遇到“EOF token”时的默认操作是返回 0。
由 bison(和 byacc)生成的解析器需要看到这个零标记。请参阅this answer至 END OF FILE token with flex and bison (only works without it) .
您的词法分析器在遇到换行符时返回 0
标记。那会带来各种麻烦。毫无疑问,这会导致您在从文件中读取数据时所观察到的情况。
编辑:好的,解决了这个问题并应用了更新,让我们考虑一下您的语法。
请记住,bison 添加了一个特殊的产生式来寻找零标记。让我们用 $
来表示(正如人们通常所做的那样,或者有时是 $end
)。因此,您的整个语法(没有任何操作,并且删除了“错误”,因为它也很特殊)是:
$all : input $;
input: word | eof | /* empty */;
word: TWORD;
eof: TEOF;
这意味着您的语法仅接受的句子是:
TWORD $
或者:
TEOF $
或者:
$
因此,当您调用 yyparse()
时,yyparse()
内部的循环将从词法分析器中提前读取一个标记,并接受(并返回)结果(如果token 是零值的文件结尾$
。如果不是,则 token 必须是 TWORD
或 TEOF
之一(任何其他值都会导致调用 yyerror()
并尝试重新同步)。如果 token 是两个有效 token 之一,yyparse()
将再次调用词法分析器以验证下一个 token 是否是零值文件结尾$
token 。
如果所有这些都成功,yyparse()
将返回成功。
重新添加操作,您应该看到 printf
输出,并根据用于识别(最多一) token 。
关于c - Flex/Bison EOF 从标准输入与文件传播,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20458469/
我最近在读 CSAPP。在 10.9 节中,它说标准 I/O 不应该与 socket 一起使用,原因如下: (1) The restrictions of standard I/O Restricti
似乎是一个足够标准的问题,可以保证解决方案中的标准设计: 假设我想在文件中写入 x+2(或更少)个字符串。 x 字符串构成一个部分的内容,这两个字符串构成该部分的页眉和页脚。要注意的是,如果内容中没有
代码版本管理 在项目中,代码的版本管理非常重要。每个需求版本的代码开发在版本控制里都应该经过以下几个步骤。 在master分支中拉取该需求版本的两个分支,一个feature分支,
我有以下sql查询,我需要获取相应的hibernate条件查询 SELECT COUNT(DISTINCT employee_id) FROM erp_hr_payment WHERE payment
所以我正在编写一些代码,并且最近遇到了实现一些 mixin 的需要。我的问题是,设计混音的正确方法是什么?我将使用下面的示例代码来说明我的确切查询。 class Projectile(Movable,
我的环境变量包含如下双引号: $echo $CONNECT_SASL_JAAS_CONFIG org.apache.kafka.common.security.plain.PlainLoginModu
示例: /** * This function will determine whether or not one string starts with another string. * @pa
有没有办法在 Grails 中做一个不区分大小写的 in 子句? 我有这个: "in"("name", filters.tags) 我希望它忽略大小写。我想我可以做一个 sqlRestriction
我搜索了很长时间,以查找将哪些boost库添加到std库中,但是我只找到了一个新库的完整列表(如此处:http://open-std.org/jtc1/sc22/wg21/docs/library_t
我已经通过使用这个肮脏的黑客解决了我的问题: ' Filter managerial functions ActiveSheet.Range("$A$1:$BW$2211").Auto
因此,我很难理解我需要遵循的标准,以便我的 Java 程序能够嵌入 HTML。我是否只需将我的主类扩展到 Applet 类,或者我还需要做更多的事情吗?另外,在我见过的每个 Applet 示例中,它都
我对在 Hibernate 中使用限制有疑问。 我必须创建条件,设置一些限制,然后选择日期字段最大值的记录: Criteria query = session.createCriteria(Stora
我有标准: ICriteria criteria = Session.CreateCriteria() .SetFetchMode("Entity1", FetchMo
我很难编写条件来选择所有子集合或孙集合为空的实体。我可以将这些作为单独的条件来执行,但我无法将其组合成一个条件。 类结构: public class Component { p
@Entity class A { @ManyToMany private List list; ... } @Entity class B { ... } 我想使用条件(不是 sql 查询)从 A
我的数据库中有以下表结构: Table A: Table B: Table C: _______________
请帮助我: 我有下一张 table : 单位 ID 姓名 用户 ID 姓名 利率 单位 ID 用户 ID 我不明白如何从 SQL 创建正确的条件结构: 代码: SELECT * FROM Unit W
我正在构建一个包含项目的网站,每个项目都有一个页面,例如: website.com/book/123 website.com/film/456 website.com/game/789 每个项目都可以
我需要使用两个属性的组合来过滤结果列表。一个简单的 SQL 语句如下所示: SELECT TOP 10 * FROM Person WHERE FirstName + ' ' + LastName L
我有一个“ super 实体”SuperEntity 和三个扩展父类(super class)的实体 ChildEntity1、...、ChildEntity3。 搜索数据库中的所有实体很容易,即我们
我是一名优秀的程序员,十分优秀!