ANTLR4 PLSQL 语法 Python 3 缺少函数



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

'NameError: name 'IsNewlineAtPos' 未定义 '

我可以看到有人更新了 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 来运行它,如果有人能告诉我他们为什么"扩展"以及他们创建的这个函数的作用,我将不胜感激。(如果他们能告诉我如何转换为Python 3,那就太棒了(

{...}?

部分称为语义谓词,包含特定于目标的代码(在您的情况下为 Python(。所以,这意味着IsNewlineAtPos(...)应该是在Python风格的PlSqlBaseLexer中定义的函数,就像C#和Java有一个PlSqlBaseLexer实现一样:

# TODO import ANTLR's runtime classes here
class PlSqlBaseLexer(Lexer):
__init__(self, ...):
# TODO
def IsNewlineAtPos(self, pos):
# TODO

通常,ANTLR 会从您的语法创建一个词法分析器,以扩展 ANTLR 自己的Lexer类,但由于 PL-SQL 语法需要更多的目标特定代码,因此在语法中添加了以下内容:

options {
superClass=PlSqlBaseLexer;
}

这告诉ANTLR它需要创建一个"位于"ANTLR自己的Lexer实现和PlSqlLexer之间的PlSqlBaseLexer。所以代替这个继承树:

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(或换行符时,谓词将成功。

另请注意自述文件中的用法,重要说明部分。

相关内容

  • 没有找到相关文章

最新更新