Изучаю закон в этом процессе, я генерирую маркеры для языка 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:
Программы лексического анализа, написанные с помощью 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) | <