ANTLR4 PLSQL 语法 Python 3 缺少函数

ANTLR4 PLSQL Grammar Python 3 Missing Function

我正在为 Antlr4 使用此语法 https://github.com/antlr/grammars-v4/tree/master/plsql,但出现错误,因为它引用了一个不存在的函数。

'NameError: name 'IsNewlineAtPos' is not defined '

我可以看到有人更新了 csharp 版本的两个文件(这是额外的项目?基础词法分析器和解析器?其中包括引用以下代码中的函数的更新。

// 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 到 运行 这个,如果有人能告诉我他们 'extend' 的原因以及他们创建的这个函数的作用,我将不胜感激。 (如果他们能告诉我如何转换为 python 3 那就太棒了)

{...}? 部分称为 semantic predicates and contain target specific code (Python in your case). So, that means IsNewlineAtPos(...) should be a function defined in a Python-flavored PlSqlBaseLexer, just like there is a PlSqlBaseLexer implementations for C# and Java:

# TODO import ANTLR's runtime classes here

class PlSqlBaseLexer(Lexer):

  __init__(self, ...):
    # TODO

  def IsNewlineAtPos(self, pos):
    # TODO

通常,ANTLR 从扩展 ANTLR 自己的 Lexer class 的语法中创建一个词法分析器,但是由于 PL-SQL 语法需要更多的目标特定代码,下面添加到语法:

options {
    superClass=PlSqlBaseLexer;
}

它告诉 ANTLR 它需要在 ANTLR 自己的 Lexer 实现和 PlSqlLexer 之间创建一个 PlSqlBaseLexer "sits"。所以不是这个继承树:

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(nothing/EOF)或换行符时,谓词将成功.

另请注意自述文件中的 Usage, important note 部分。