我正在编写一个使用lex和yacc进行汇编的解释器。问题是我需要解析一个严格位于文件末尾的单词。我读到有一个锚$,它可以提供帮助。然而,它并没有像我预期的那样工作。我在我的lex文件中写道:
ABC$ {printf("QWERTY\n");}输入文件为:
ABC没有空格或任何其他不可见的符号。所以我希望输出是QWERTY,但是我得到的是:
ABC我猜这意味着程序无法解析它。然后我想,$可能是lex中的一个常规符号,所以我将输入文件更改为:
ABC$因此,如果$不是一个特殊的符号,那么它将被解析为一个正常的符号,并且输出将是QWERTY。这不会发生,输出是:
ABC$问题是lex中的$是普通符号还是特殊符号。
发布于 2019-05-13 09:10:15
在(f)lex中,$匹配后跟换行符的零个字符。
这与许多正则表达式库不同,在这些库中,$将在输入结束时匹配。因此,如果您的文件末尾没有换行符,如您的问题所示(假设您认为换行符是一个不可见的字符),那么它将不匹配。
正如@sepp2k在评论中建议的那样,如果输入文件碰巧使用Windows行结尾(由序列\r\n组成),则模式也不会匹配,除非生成的flex文件是为Windows编译的。因此,如果您在Windows上创建了该文件,并在Unix环境中运行了flex生成的扫描程序,则\r也会导致模式不匹配。在这种情况下,可以使用(F)lex的尾部上下文运算符:
ABC/\r?\n { puts("Matched ABC at the end of a line"); }有关尾随上下文运算符的完整描述,请参阅flex documentation for patterns。(在该页面上搜索“尾随上下文”;它大致向下了一半。) $完全等同于/\n。
这仍然与文件末尾的ABC不匹配。在文件末尾匹配字符串有点棘手,但如果可以识别文件末尾以外的字符串,则可以使用两种模式进行匹配,从而触发不同的操作:
ABC/. { /* Do nothing. This ABC is not at the end of a line or the file */ }
ABC { puts("ABC recognised at the end of a line"); }这是可行的,因为只要ABC后面有一些非换行符,第一个模式就会匹配。(.可匹配除换行符以外的任何字符。有关详细信息,请参阅上面的链接。)如果您还需要处理Windows行结束,则需要修改第一个模式中的尾随上下文。
https://stackoverflow.com/questions/56102786
复制相似问题