Не мог распознать одну строку комментирует в 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.
9
задан user265867 13 February 2010 в 02:30
поделиться

1 ответ

Согласно руководству Lex:

Программы лексического анализа, написанные с помощью Lex, принимают неоднозначные спецификации и выбирают самые длинные {{1} } совпадение возможно в каждой точке ввода. Если необходимо, для входных данных выполняется существенный просмотр вперед , но для входящего потока будет сохранена резервная копия до конца текущего раздела, так что Пользователь имеет общую свободу манипулировать им .

Таким образом, вам не нужно делать ничего особенного - // длиннее, чем / , поэтому он предпочтет комментарий оператору деления, когда увидит два. Однако вы не разместили свое правило комментариев - где оно?

Edit : неважно, я его вижу. [//] - это класс символов. Снимите квадратные скобки. Кроме того, вы захотите сопоставить с концом строки - в противном случае вы разрешите только пустые комментарии. Таким образом, ваше регулярное выражение должно быть примерно таким:

// [^ \ r \ n] * \ r \ n (при необходимости отрегулируйте символы новой строки, которые вы поддерживаете - для этого требуется, чтобы новая строка была точно \ r \ n ).

Edit 2 : @ tur1ng поднимает хороший вопрос - последняя строка в вашем файле не может заканчиваться новой строкой. Я нашел его, и Lex также поддерживает <> в своих регулярных выражениях (см. http://pltplp.net/lex-yacc/lex.html.en ). Таким образом, вы можете изменить на:

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

6
ответ дан 4 December 2019 в 23:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: