Как обрабатывать конец файла в комплекте грамматики IntelliJ - PullRequest
0 голосов
/ 10 июня 2019

Я работаю над поддержкой IntelliJ для DSL с использованием Grammar-Kit.У меня есть правило в файле bnf, для которого в конце требуется токен EOF (конец файла): rule ::= ( object | (( LCURL EOL* properties EOL* RCURL ) | properties ) ) EOL* EOF

Я предположил, что могу просто создать правило лексера в файле flex <<EOF>> { return EOF;} и все.К сожалению, где-то глубже в коде IntelliJ логика, которая обрабатывает метод advance() лексера, не завершается, пока не получит нулевое значение от лексера, что приведет к бесконечному циклу, так как конец файла возвращает ненулевой токен.

Существует ли какой-либо элегантный (простой) способ обработки конца файла в грамматическом наборе, позволяющий использовать «конец файла» в определении анализатора (bnf)?

Ответы [ 2 ]

1 голос
/ 10 июня 2019

В .bnf файле вы можете использовать <<eof>>. Это внешнее правило, которое ссылается на метод GeneratedParserUtilBase.eof.

0 голосов
/ 10 июня 2019

В конце я просто поместил адаптер между сгенерированным лексером и его потребителем, который заменяет функциональность метода advance () лексера.Если EOF был достигнут, то в следующий раз он вернет ноль.Примерно так:

`override fun advance(): IElementType? {
    val t: IElementType? = lexer.advance()
    return when {
        eofReached -> null
        t == VUCLTypes.EOF -> {
            eofReached = true
            t
        }
        else -> t
    }
}`

eofReached - это флаг, который устанавливается в значение false при инициализации и при произвольном вызове метода reset() лексера.

`override fun reset(p0: CharSequence, p1: Int, p2: Int, p3: Int) {
    eofReached = false
    lexer.reset(p0, p1, p2, p3)
}`

Надеюсь, яничего не пропустил ..

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...