Ограниченное регулярное выражение комментариев в JFlex - PullRequest
0 голосов
/ 28 октября 2018

Я создаю лексер для выдуманного языка, и у меня проблема с определением регулярного выражения для однострочного комментария.

Проблема в том, что разрешенные символы комментария ограничены.Допускаются только некоторые символы, и они включают в себя: пробелы, цифры, буквы и несколько символов (скажем, *, /, +, -).Однострочный комментарий начинается (как в C и Java) с //, а его определение (за исключением ограниченных символов) такое же, как в C и Java.

Сначала я попробовал следующее регулярное выражение:

"//" ([a-zA-Z0-9] | [*] | [/] | [+] | [-] | [ \t\f])* (\r|\n|\r\n)

Мы надеемся, что это поймает однострочные комментарии, но, к сожалению, это не поймает однострочный комментарий в конце файла, так как он нев конце есть разделитель строки.

Я пытался изменить его на:

"//" ([a-zA-Z0-9] | [*] | [/] | [+] | [-] | [ \t\f])* ((\r|\n|\r\n) | [^.])

Надеюсь, [^.] поймал бы тот факт, что естьпосле комментария не допускаются символы (как-то эмулировать EOF?), но это не сработало, и регулярное выражение перехватывает все до запрещенного символа, например: // comment = 1 переводится в single line comment, = 1.

Я не могу использовать JFlex <<EOF>>, так как он не может быть частью регулярного выражения.

Есть ли хорошее регулярное выражение решение этой проблемы?(Предполагая, что я не могу изменить ввод).

Спасибо!

1 Ответ

0 голосов
/ 01 ноября 2018

Из руководства jflex здесь:
http://jflex.de/manual.html#Example

TraditionalComment   = "/*" [^*] ~"*/" | "/*" "*"+ "/"
// Comment can be the last line of the file, without line terminator.
EndOfLineComment     = "//" {InputCharacter}* {LineTerminator}?
DocumentationComment = "/**" {CommentContent} "*"+ "/"
CommentContent       = ( [^*] | \*+ [^/*] )*

Также обратите внимание, что вы можете использовать конкретное значение eof, используя% eofval, также обсуждаемое в руководстве, которое я опубликовал выше.

Я понимаю, что вы специально запрашиваете решение для регулярных выражений, но также может быть лучший способ упростить эту проблему за счет использования ваших лексических состояний - вы могли бы иметь символ "//", указывающий на вход в состояние комментария;Оказавшись в этом состоянии, вы можете захватить все буквенно-цифровые символы, пока не достигнете конца строки для одной строки, верните токен tag.comment, а затем вернетесь в исходное состояние и продолжите лексирование.

Например, включая все, что я обсуждал выше:

%%
%state COMMENT
%%
%eofval{
    return getToken(tag.EOF, null);
%eofval}


comment = "//"
eol = "\r\n\"
characters = [a-zA-Z0-9] | [*] | [/] | [+] | [-]
%%
<YYINITIAL> {comment}{
    yybegin(COMMENT);
    return getToken(tag.Comment, yytext());
}

<COMMENT> {characters}{eol}{
    yybegin(YYINITIAL);
}

** отказ от ответственности, это неполно, как лексер и сделано из головы.Это больше, чтобы продемонстрировать мой пример, обсужденный выше

...