You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Antlr4 Python解析PLSQL包时出现NameError问题求助

PLSQL语法解析报错:NameError: name 'this' is not defined分析

问题场景

在Ubuntu 22.04中部署Python版Antlr4 PLSQL解析环境的步骤:

  • 下载基础类与语法文件:
wget https://github.com/antlr/grammars-v4/blob/master/sql/plsql/Python3/PlSqlLexerBase.py
wget https://github.com/antlr/grammars-v4/blob/master/sql/plsql/Python3/PlSqlParserBase.py

wget https://github.com/antlr/grammars-v4/blob/master/sql/plsql/PlSqlLexer.g4
wget https://github.com/antlr/grammars-v4/blob/master/sql/plsql/PlSqlParser.g4
  • 安装运行依赖:
pip3 install antlr4-python3-runtime==4.13.1

测试以下匿名PLSQL块时,解析可正常生成语法树:

DECLARE
    l_x NUMBER;
BEGIN
    SELECT length(c1)
    INTO l_x
    FROM the_table
    WHERE c2 = 'X';
END;

但解析以下PLSQL包定义文件时触发错误:

CREATE OR REPLACE PACKAGE pa_tsheet AS
--
  PROCEDURE pr_new_tsheet_template
  (
    p_act_id     IN     timesheets.act_id            %TYPE,
    p_apd_id     IN     timesheets.apd_id            %TYPE,
    p_weekend_yn IN     VARCHAR2,
    p_job_desc   IN     timesheet_items.job_details  %TYPE,
    p_job_rate   IN     timesheet_items.rate         %TYPE,
    p_job_hours  IN     timesheet_items.hours        %TYPE,
    p_tms_id     IN OUT timesheets.id                %TYPE
  );
--
END pa_tsheet;
/

错误栈信息如下:

python3 ./runPLSQLFiles.py ../pa_tsheet.pkh 2>&1 

Traceback (most recent call last):
  File "antlr_plsql/grammars/./runPLSQLFiles.py", line 33, in <module>
    main()
  File "antlr_plsql/grammars/./runPLSQLFiles.py", line 19, in main
    tree = parser.sql_script()
  File "antlr_plsql/grammars/PlSqlParser.py", line 15340, in sql_script
    self.unit_statement()
  File "antlr_plsql/grammars/PlSqlParser.py", line 16370, in unit_statement
    self.create_package()
  File "antlr_plsql/grammars/PlSqlParser.py", line 25046, in create_package
    self.consume()
  File ".local/lib/python3.10/site-packages/antlr4/Parser.py", line 348, in consume
    self.getInputStream().consume()
  File ".local/lib/python3.10/site-packages/antlr4/BufferedTokenStream.py", line 101, in consume
    self.index = self.adjustSeekIndex(self.index + 1)
  File ".local/lib/python3.10/site-packages/antlr4/CommonTokenStream.py", line 45, in adjustSeekIndex
    return self.nextTokenOnChannel(i, self.channel)
  File ".local/lib/python3.10/site-packages/antlr4/BufferedTokenStream.py", line 214, in nextTokenOnChannel
    self.sync(i)
  File ".local/lib/python3.10/site-packages/antlr4/BufferedTokenStream.py", line 112, in sync
    fetched = self.fetch(n)
  File ".local/lib/python3.10/site-packages/antlr4/BufferedTokenStream.py", line 124, in fetch
    t = self.tokenSource.nextToken()
  File ".local/lib/python3.10/site-packages/antlr4/Lexer.py", line 137, in nextToken
    ttype = self._interp.match(self._input, self._mode)
  File ".local/lib/python3.10/site-packages/antlr4/atn/LexerATNSimulator.py", line 104, in match
    return self.execATN(input, dfa.s0)
  File ".local/lib/python3.10/site-packages/antlr4/atn/LexerATNSimulator.py", line 173, in execATN
    target = self.computeTargetState(input, s, t)
  File ".local/lib/python3.10/site-packages/antlr4/atn/LexerATNSimulator.py", line 231, in computeTargetState
    self.getReachableConfigSet(input, s.configs, reach, t)
  File ".local/lib/python3.10/site-packages/antlr4/atn/LexerATNSimulator.py", line 280, in getReachableConfigSet
    if self.closure(input, config, reach, currentAltReachedAcceptState, True, treatEofAsEpsilon):
  File ".local/lib/python3.10/site-packages/antlr4/atn/LexerATNSimulator.py", line 359, in closure
    currentAltReachedAcceptState = self.closure(input, c, configs, currentAltReachedAcceptState, speculative, treatEofAsEpsilon)
  File ".local/lib/python3.10/site-packages/antlr4/atn/LexerATNSimulator.py", line 357, in closure
    c = self.getEpsilonTarget(input, config, t, configs, speculative, treatEofAsEpsilon)
  File ".local/lib/python3.10/site-packages/antlr4/atn/LexerATNSimulator.py", line 396, in getEpsilonTarget
    if self.evaluatePredicate(input, t.ruleIndex, t.predIndex, speculative):
  File ".local/lib/python3.10/site-packages/antlr4/atn/LexerATNSimulator.py", line 465, in evaluatePredicate
    return self.recog.sempred(None, ruleIndex, predIndex)
  File "antlr_plsql/grammars/PlSqlLexer.py", line 16736, in sempred
    return pred(localctx, predIndex)
  File "antlr_plsql/grammars/PlSqlLexer.py", line 16747, in PROMPT_MESSAGE_sempred
    return this.IsNewlineAtPos(-4)
NameError: name 'this' is not defined

错误原因分析

  1. 生成代码的语法兼容性问题:Antlr生成的PlSqlLexer.py文件中,PROMPT_MESSAGE_sempred方法错误使用了Java风格的this关键字,而Python中应该用self指代当前实例。这是PLSQL语法定义中的语义谓词在生成Python代码时未完成语法适配导致的。
  2. 触发条件:包定义末尾的/符号会触发Lexer中PROMPT_MESSAGE规则的语义检查,而该检查方法中的this未被替换为self,直接抛出NameError。匿名块没有结尾的/,因此不会触发该规则,解析正常。
  3. 根源:antlr/grammars-v4仓库中的PLSQL语法文件(PlSqlLexer.g4)的语义谓词实现,针对Python代码生成的兼容性处理存在缺陷,未适配Python的实例引用语法。

内容的提问来源于stack exchange,提问作者Pro West

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 01:19:56