我在Antlr4上使用了这种语法https://github.com/antlr/grammars-v4/tree/master/plsql,但是由于引用了一个不存在的函数而出现错误。
'NameError:名称'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,那将很棒)
答案 0 :(得分:3)
{...}?
部分称为semantic predicates,其中包含目标特定的代码(在您的情况下为Python)。因此,这意味着IsNewlineAtPos(...)
应该是Python风格的PlSqlBaseLexer
中定义的函数,就像C#和Java的PlSqlBaseLexer
实现一样:< / p>
# 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它需要创建一个PlSqlBaseLexer
,它“坐在” ANTLR自己的Lexer
实现和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, important note部分。