c - 无法识别 Lex 中的单行注释

标签 c lex compiler-construction

我在这个过程中学习了 lex,我正在为 C 语言生成标记,并试图识别单行注释“//”,但我与除法运算符发生冲突

[1-9][0-9]*|0x[0-9a-fA-F][0-9a-fA-F]*           return NUMBER;
[a-zA-Z][a-zA-Z0-9]*                            return IDENT;
/                                               {return DIVIDE;}

[ \t\r\n]
[//]

但是当我运行示例并输入//时,它会将它们识别为 2 个除法运算符。我应该在哪里修改代码。任何建议。

编辑:

莱克斯代码:

%{
#include "y.tab.h"
%}
%array
%%
if                                              {return IF;}
while                                           {return WHILE;}
else                                            {return ELSE;}
int                                             {return INT;}
return                                          {return RETURN;}
\/\/[^\r\n]*
[1-9][0-9]*|0x[0-9a-fA-F][0-9a-fA-F]*           return NUMBER;
[a-zA-Z][a-zA-Z0-9]*                            return IDENT;

[+]                                             {return ADD;}
[-]                                             {return SUB;}
[<]                                             {return LESS;}
[>]                                             {return GREAT;}
[*]                                             {return MULT;}
[/]                                             {return DIVIDE;}
[;]                                             {return SEMICOLON;}

\{                                              return LBRACE;
\}                                              return RBRACE;

[ \t\r\n]

\(                                              return LPAREN;

\)                                              return RPAREN;

.                                               return BADCHAR;
%%

以下是我使用的头文件

typedef enum {END=0, WHILE, IF, ELSE,RETURN, IDENT, LPAREN, RPAREN,INT,LBRACE,RBRACE, SEMICOLON, EQUALITY, DIVIDE, MULT, LESS, GREAT,
 ADD, SUB, NUMBER,BADCHAR} Token;

下面是运行时的输入,

//
/
p
Token 16, text /
Token 16, text /
Token 16, text /
Token 5, text p

当我运行它时,注释被消耗,甚至除法运算符也被忽略。但是当我输入 p 时检查,它对上面列出的运算符进行了分类,这是它不应该做的。

Note: Am trying to ignore tabs, newline characters and single line comments. 

Note 2: \/\/[^\r\n]* I have understood where I committed the mistake and wanted to share this.

最佳答案

根据 Lex 手册:

The lexical analysis programs written with Lex accept ambiguous specifications and choose the longest match possible at each input point. If necessary, substantial lookahead is performed on the input, but the input stream will be backed up to the end of the current partition, so that the user has general freedom to manipulate it.

所以你不需要做任何特别的事情 - //长于 /所以当它看到两个时,它会更喜欢评论而不是除法运算符。但是,您没有发布您的评论规则 - 它在哪里?

编辑:没关系,我看到了。 [//]是一个字符类。删除方括号。此外,您需要匹配到行尾 - 否则您将只允许空注释。所以你的正则表达式应该是这样的:

//[^\r\n]*\r\n (根据需要为您支持的换行符进行调整 - 这个要求换行符正好是 \r\n )。

编辑 2:@tur1ng 提出了一个很好的观点 - 您文件中的最后一行可能不会以换行符结尾。我查了一下,Lex 支持 <<EOF>>也在其正则表达式中(参见 http://pltplp.net/lex-yacc/lex.html.en )。所以你可以改成:

//[^\r\n]*((\r\n)|<<EOF>>)

关于c - 无法识别 Lex 中的单行注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2249692/

相关文章:

ios - 为什么条件运算符为第一条语句提供所需的结果而不是第二条语句?

c - 解析编译器语法和错误错误恢复

html - 如何使用 lex 在 html 标签内打印文本

c++ - 以零开头的数字有什么特别之处?

php - 如何在测试公共(public)代理时可靠地重现 curl_multi 超时

c - 如何理解程序

parsing - YACC| Bison :How do I manipulate parse tree?

c++ - 在 C++ 中实例化一个类 : Strange Syntax Bug

c++ - 链接器是否存在于所有编译的编程语言中?

c - 求 3X3 矩阵 C 的次矩阵