Lex输入功能的返回值

问题描述 投票:0回答:1

根据POSIX Lex,当到达文件结尾时,函数输入应返回零:

int input(void)返回输入中的下一个字符,或者在文件结尾处返回零。它应该从流指针yyin获得输入,尽管可能通过中间缓冲区。因此,一旦扫描开始,改变yyin值的效果是不确定的。读取的字符应从扫描仪的输入流中删除,而不需要扫描仪进行任何处理。

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/lex.html

但是,至少在Flex中,输入有时会返回-1(EOF)而不是0.此外,我看到的一些示例依赖于EOF而不是0,例如在“Lex and Yacc”一书中:

https://books.google.se/books?id=fMPxfWfe67EC&pg=PA152&lpg=PA152&dq=flex+input+returns+eof&source=bl&ots=RdLSgm5LEO&sig=sXajxhnlydQLz_GcZZuIaUONYlk&hl=sv&sa=X&ved=0ahUKEwjE58OwidDZAhWLiSwKHVdSD8kQ6AEIYDAF#v=onepage&q=flex%20input%20returns%20eof&f=false

使用功能输入后,我真的需要测试0和EOF吗?

posix flex-lexer lex
1个回答
1
投票

我担心你确实需要检查这两个值。

据我所知,Posix总是要求input()在输入结束时返回0,这是基于原始AT&T lex的行为。虽然这个规范使得重新定义input()以接受来自字符串而不是外部文件的输入变得容易,但它也使得基本上不可能区分输入流中的NUL字节和EOF。这对于原始lex实现来说并不是真正的问题,因为它没有尝试处理具有NUL字节的输入流。 (Posix不要求文本文件能够包含NUL字节,所以它也不是Posix的问题。)

Flex,渴望处理任意8位输入,重新定义了input() API以返回EOF(负数,通常为-1)以指示输入结束。这是它的行为直到2016年3月1日发布的版本2.6.1,它改变了接口以符合Posix。至少,我认为这就是界面改变的原因。我找不到任何解释变更的文档,commit不提供任何信息。

这一变化没有反映在文件中,继续包括example code with the old specification。 (此代码与John Levine的书中的示例代码非常相似。)badly-title bug complaining about the change在没有评论的情况下被关闭。这个变化没有出现在Change Log中。

无论如何,Posix不太可能在此时改变,因此lex工具的其他实现可以实现历史性flex约定或Posix要求。 flex生成的分析器返回的值将取决于用于构建分析器的flex版本。因此,可移植代码必须允许这两种约定。

Posix没有明确要求input()返回的值是正数,但似乎有理由假设该值与fgetc()返回的值相同(“下一个字节为unsigned char转换为int” )。这当然是flex的作用。如果您决定依靠该解释,您可以简单地测试input()的返回值是否小于或等于0。

作为一个社论,我从未使用input()而最终没有后悔。几乎总有一种更好的解决方案,通常涉及启动条件。除了这个问题引用的细节,input()与flex基础设施没有很好的集成。使用input()读取的字符不能添加到当前令牌中,也不能使用yyless()重新处理。如果使用yylineno读取换行符,则input()的自动维护将失败,这可能会影响用户提供的列位置维护。等等。

对于AT&T lex,使用input()跳过多行注释的文本有一定的意义。在20世纪70年代,RAM是比现在更宝贵的资源,并且lex在处理大型令牌方面不是很擅长。因此,阅读(和构建)评论标记是不必要且具有潜在危险的一步,因为多行注释可能非常大(相对于标识符标记而言)。 AT&T lex使用input()(通常别名为fgetc)一次读取文件输入一个字符,因此使用input()不会产生任何开销。

这些天来,这一切都没有。 RAM相对便宜,并且flex不会因为必须使用足够大的内部缓冲区来保持多行评论而负担沉重。另一方面,由于flex维护自己的内部缓冲区,因此需要在自己的缓冲区管理之上模拟input(),这会产生一定的开销。因此,看到像我在flex手册中提到的那些片段一样,这应该是不常见的;基于开始条件的评论检测器更高效,更短,并且可读性更强:

"/*"                 BEGIN(COMMENT);
<COMMENT>[*]+/       BEGIN(INITIAL);
<COMMENT>[^*]+|[*]+  ;
© www.soinside.com 2019 - 2024. All rights reserved.