Antlr4安装在Ubuntu 22.04上,安装了Python,如下所示:

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

安装适用于Python的Antlr4

pip3 install antlr4-python3-runtime==4.13.1

以下测试脚本用于解析简单的SQL、PLSQL文件:

def main():
    with open(sys.argv[1], 'r') as file:
        filesrc = file.read()

    lexer = PlSqlLexer(InputStream(filesrc))
    parser = PlSqlParser(CommonTokenStream(lexer))
    tree = parser.sql_script()
    traverse(tree, parser.ruleNames)

def traverse(tree, rule_names, indent = 0):
    if tree.getText() == "<EOF>":
        return
    elif isinstance(tree, TerminalNodeImpl):
        print("{0}TOKEN='{1}'".format("  " * indent, tree.getText()))
    else:
        print("{0}{1}".format("  " * indent, rule_names[tree.getRuleIndex()]))
        for child in tree.children:
            traverse(child, rule_names, indent + 1)

if __name__ == '__main__':
    main()

我有一个简单的输入文件,如下所示,用于测试上面的内容,Python脚本可以很好地处理它,没有错误:

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

这提供了:

python3 ./runPLSQLFile.py test.sql
sql_script
  unit_statement
    anonymous_block
      TOKEN='DECLARE'
      seq_of_declare_specs
        declare_spec
          variable_declaration
            identifier
              id_expression
                regular_id
                  TOKEN='l_x'
            type_spec
              datatype
                native_datatype_element
                  TOKEN='NUMBER'
            TOKEN=';'
      TOKEN='BEGIN'
      seq_of_statements
        statement
          sql_statement
            data_manipulation_language_statements
              select_statement
                select_only_statement
                  subquery
                    subquery_basic_elements
                      query_block
                        TOKEN='SELECT'
                        selected_list
                          select_list_elements
                            expression
                              logical_expression
                                unary_logical_expression
                                  multiset_expression
                                    relational_expression
                                      compound_expression
                                        concatenation
                                          model_expression
                                            unary_expression
                                              atom
                                                general_element
                                                  general_element_part
                                                    id_expression
                                                      regular_id
                                                        non_reserved_keywords_pre12c
                                                          TOKEN='length'
                                                    function_argument
                                                      TOKEN='('
                                                      argument
                                                        expression
                                                          logical_expression
                                                            unary_logical_expression
                                                              multiset_expression
                                                                relational_expression
                                                                  compound_expression
                                                                    concatenation
                                                                      model_expression
                                                                        unary_expression
                                                                          atom
                                                                            general_element
                                                                              general_element_part
                                                                                id_expression
                                                                                  regular_id
                                                                                    TOKEN='c1'
                                                      TOKEN=')'
                        into_clause
                          TOKEN='INTO'
                          general_element
                            general_element_part
                              id_expression
                                regular_id
                                  TOKEN='l_x'
                        from_clause
                          TOKEN='FROM'
                          table_ref_list
                            table_ref
                              table_ref_aux
                                table_ref_aux_internal
                                  dml_table_expression_clause
                                    tableview_name
                                      identifier
                                        id_expression
                                          regular_id
                                            TOKEN='the_table'
                        where_clause
                          TOKEN='WHERE'
                          condition
                            expression
                              logical_expression
                                unary_logical_expression
                                  multiset_expression
                                    relational_expression
                                      relational_expression
                                        compound_expression
                                          concatenation
                                            model_expression
                                              unary_expression
                                                atom
                                                  general_element
                                                    general_element_part
                                                      id_expression
                                                        regular_id
                                                          TOKEN='c2'
                                      relational_operator
                                        TOKEN='='
                                      relational_expression
                                        compound_expression
                                          concatenation
                                            model_expression
                                              unary_expression
                                                atom
                                                  constant
                                                    quoted_string
                                                      TOKEN=''X''
        TOKEN=';'
      TOKEN='END'
  TOKEN=';'

但是,当我针对此脚本运行时,我得到一个错误:

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)
Name错误: name 'this' is not defined

问题出在哪里?

推荐答案

词法分析器和解析器语法都包含谓词,而这些谓词又包含特定于目标的代码.如来自Python解释器的错误所示的this.IsNewlineAtPos(-4).在您的Python代码中使用生成的词法分析器和解析器之前,您需要将所有这些特定于目标的代码重写为有效的Python代码.最有可能的是,这只会把this.变成self.(虽然没有经过测试).

Python相关问答推荐

如何在Python中将returns.context. DeliverresContext与Deliverc函数一起使用?

Vectorize多个头寸的止盈/止盈回溯测试pythonpandas

管道冻结和管道卸载

' osmnx.shortest_track '返回有效源 node 和目标 node 的'无'

使用setuptools pyproject.toml和自定义目录树构建PyPi包

使用密钥字典重新配置嵌套字典密钥名

字符串合并语法在哪里记录

与命令行相比,相同的Python代码在Companyter Notebook中运行速度慢20倍

Polars asof在下一个可用日期加入

ConversationalRetrivalChain引发键错误

Python—压缩叶 map html作为邮箱附件并通过sendgrid发送

为什么Python内存中的列表大小与文档不匹配?

如何在Python Pandas中填充外部连接后的列中填充DDL值

如何在Python 3.9.6和MacOS Sonoma 14.3.1下安装Pyregion

用来自另一个数据框的列特定标量划分Polars数据框中的每一列,

pytest、xdist和共享生成的文件依赖项

修改.pdb文件中的值并另存为新的

与同步和异步客户端兼容的Python函数

无法使用请求模块从网页上抓取一些产品的名称

按列表分组到新列中