且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

的Flex /野牛EOF从标准输入传播VS文件

更新时间:2023-11-17 23:27:10

由于在链接中提到的,弯曲有识别输入文件或流的末尾语法(例如,从字符串输入)。

As noted in your links, flex has syntax for recognizing the end of an input file or stream (e.g., an input from a string).

其实,弯曲实际上有在任何时候都运行这样的规则。默认情况下,规则调用 yywrap 。你把这个关闭(以%noyywrap )。这很好,除了...

In fact, flex effectively has such a rule operating at all times. By default, the rule calls yywrap. You turned this off (with %noyywrap). That's fine, except...

在遇到EOF令牌的默认行为是返回0。

The default action on encountering an "EOF token" is to return 0.

野牛生成解析器(和byacc)需要看到这个零令牌。请参见这个答案来的 END文件标记使用Flex和野牛(只适用于没有它)

The parsers generated by bison (and byacc) need to see this zero token. See this answer to END OF FILE token with flex and bison (only works without it).

您词法分析器返回在遇到一个新行一 0 标记。这将导致各种麻烦。而毫无疑问,导致从文件中读取时,你观察到的东西。

Your lexer returns a 0 token on encountering a newline. That will cause all kinds of trouble. and is no doubt leading to what you observe when reading from a file.

编辑:好了,有了这样的方式应用更新,让我们考虑你的语法

OK, with that out of the way and the update applied, let's consider your grammar.

记住,野牛增加了一个特殊的生产,看起来零令牌。让我们重新present与 $ (因为一般人做的,或者有时是 $结束)。所以,你的整个语法(没有行动,并与错误去掉,因为它也是特殊的)是:

Remember that bison adds a special production that looks for the zero-token. Let's represent that with $ (as people generally do, or sometimes it's $end). So your entire grammar (with no actions and with "error" removed since it's also special) is:

$all : input $;

input: word | eof | /* empty */;

word: TWORD;

eof: TEOF;

这意味着你的语法接受的唯一的句子是:

which means the only sentences your grammar accepts are:

TWORD $

TEOF $

$

所以,当你调用 yyparse(),里面的循环yyparse()将预读从一个令牌词法分析器和接受(并返回)的结果,如果令牌是零值尾文件 $ 。如果不是,令牌必须是一个 TWORD TEOF (别的结果调用的yyerror()并尝试重新同步)。如果令牌是两个有效的一个标记, yyparse()将调用词法再次验证一个标记是零值尾文件 $ 标记。

So when you call yyparse(), the loop inside yyparse() will read-ahead one token from the lexer and accept (and return) the result if the token is the zero-valued end-of-file $. If not, the token needs to be one of TWORD or TEOF (anything else results in a call to yyerror() and an attempt to resync). If the token is one of the two valid tokens, yyparse() will call the lexer once more to verify that the next token is the zero-valued end-of-file $ token.

如果所有这一切成功, yyparse()将返回成功。

If all of that succeeds, yyparse() will return success.

添加行为回来,你应该看到的printf 输出,并获得存储在 parseValue A值,根据上取减少规则用于识别(至多一个)标记

Adding the actions back in, you should see printf output, and get a value stored in parseValue, based on whichever reduction rule is used to recognize the (at most one) token.