ANTLR4 PLSQL грамматика Python 3 отсутствует функция - PullRequest
0 голосов
/ 08 октября 2018

Я использую эту грамматику https://github.com/antlr/grammars-v4/tree/master/plsql для Antlr4, но получаю ошибку, поскольку она ссылается на функцию, которой не существует.

'NameError: name' IsNewlineAtPos'не определено'

Я вижу, что кто-то обновил два файла csharp версии (которые являются дополнительными элементами? Base lexer и Parser? К ним относится обновление, относящееся к функции в приведенном ниже коде.

// https://docs.oracle.com/cd/E11882_01/server.112/e16604/ch_twelve034.htm#SQPUG054
REMARK_COMMENT:      'REM' {IsNewlineAtPos(-4)}? 'ARK'? (' ' ~('\r' | '\n')*)? NEWLINE_EOF -> channel(HIDDEN);

// https://docs.oracle.com/cd/E11882_01/server.112/e16604/ch_twelve032.htm#SQPUG052
PROMPT_MESSAGE:      'PRO' {IsNewlineAtPos(-4)}? 'MPT'? (' ' ~('\r' | '\n')*)? NEWLINE_EOF;

// TODO: should starts with newline
START_CMD
    //: 'STA' 'RT'? SPACE ~('\r' | '\n')* NEWLINE_EOF
    // https://docs.oracle.com/cd/B19306_01/server.102/b14357/ch12002.htm
    // https://docs.oracle.com/cd/B19306_01/server.102/b14357/ch12003.htm
    : '@' {IsNewlineAtPos(-2)}? '@'? ~('\r' | '\n')* NEWLINE_EOF
    ;

Это обновление для git

https://github.com/antlr/grammars-v4/commit/94887a3f4c9040578ef01b561e1d5e0ec54cbe9b

Я использую Python для запуска этого и буду признателен, если кто-нибудь скажет мне, почему они 'расширение 'и что делает эта функция, которую они создают. (и если они могут показать мне, как конвертировать в Python 3, это было бы здорово)

1 Ответ

0 голосов
/ 09 октября 2018

{...}? части называются семантическими предикатами и содержат целевой код (Python в вашем случае).Таким образом, это означает, что IsNewlineAtPos(...) должна быть функцией, определенной в Python со вкусом PlSqlBaseLexer, точно так же, как есть PlSqlBaseLexer реализации для C # и Java :

# TODO import ANTLR's runtime classes here

class PlSqlBaseLexer(Lexer):

  __init__(self, ...):
    # TODO

  def IsNewlineAtPos(self, pos):
    # TODO

Обычно ANTLR создает из вашей грамматики лексер, который расширяет собственный класс Lexer ANTLR, но поскольку грамматике PL-SQL требуется немного больший целевой код, к грамматике добавляется следующее:

options {
    superClass=PlSqlBaseLexer;
}

, который сообщает ANTLR, что ему нужно создать PlSqlBaseLexer, который "сидит" между собственной реализацией Lexer ANTLR и PlSqlLexer.Таким образом, вместо этого дерева наследования:

Lexer
 '- PlSqlLexer

теперь оно становится:

Lexer
 '- PlSqlBaseLexer (including the `IsNewlineAtPos` function)
   '- PlSqlLexer

Так что на самом деле нет ничего более, чем копирование того, что было сделано для версии Java (или C #).Если посмотреть на реализацию Java:

protected boolean IsNewlineAtPos(int pos)
{
    int la = _input.LA(pos);
    return la == -1 || la == '\n';
}

в сочетании с предикатом {IsNewlineAtPos(-4)}?, то предикат будет успешным, когда 4 символа от текущей позиции символа лексера (отсюда и минус 4) равны -1 (ничего /EOF) или символ новой строки.

Также обратите внимание на раздел Usage, важное примечание в README.

...