Извлечение условий JOIN из SQL с помощью Antlr4 и Python

Я хотел бы использовать Antrl4 в Python для обработки сценариев SQL/PLSQL и извлечения условий JOIN.

Для этого я пытаюсь, во-первых, понять, как они представлены в дереве парсера, возвращаемом PlSqlParser.sql_script.

У меня есть простой SQL:

SELECT ta.col1, tb.col5
FROM   mytabA ta
JOIN  mayTabB tb ON ta.col1 = tb.col2
WHERE ta.col3 = 'AXA';

Я использую следующий сценарий Python для обработки сценария SQL:

from antlr4 import *
from antlr4.tree.Tree import TerminalNodeImpl
#from antlr4.tree.Tree import ParseTree
from antlr4.tree.Trees import Trees
from PlSqlLexer import PlSqlLexer
from PlSqlParser import PlSqlParser
from PlSqlParserListener import PlSqlParserListener


def handleTree(tree, lvl=0):
    for child in tree.getChildren():
        if isinstance(child, TerminalNode):
            print(lvl*'│ ' + '└─', child)
        else:
            handleTree(child, lvl+1)


class KeyPrinter(PlSqlParserListener):
    def enterSelect_statement(self, ctx):
        handleTree(ctx, 0)

def main():

        with open( "myscript.sql" ) as file:

            filesrc = file.read()

            lexer = PlSqlLexer(InputStream(filesrc))
            tokens = CommonTokenStream(lexer)
            tokens.fill()
            parser = PlSqlParser(tokens)
            tree = parser.sql_script()

            printer = KeyPrinter()
            walker = ParseTreeWalker()
            walker.walk(printer, tree)


if __name__ == '__main__':
    main()

И результат:

│ │ │ │ └─ SELECT
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ ta
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ .
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ col1
│ │ │ │ │ └─ ,
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ tb
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ .
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ col5
│ │ │ │ │ └─ FROM
│ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ mytabA
│ │ │ │ │ │ │ │ │ │ │ │ └─ ta
│ │ │ │ │ │ │ │ └─ JOIN
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ mayTabB
│ │ │ │ │ │ │ │ │ │ │ │ │ └─ tb
│ │ │ │ │ │ │ │ │ └─ ON
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ ta
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ .
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ col1
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ =
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ tb
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ .
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ col2
│ │ │ │ │ └─ WHERE
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ ta
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ .
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ col3
│ │ │ │ │ │ │ │ │ │ │ │ └─ =
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ 'AXA'

Я меняю функцию handleTree, чтобы печатать child, чтобы попытаться понять, какую информацию можно использовать для извлечения нужной мне информации:

def handleTree(tree, lvl=0):
    for child in tree.getChildren():
        print ( child )
        if isinstance(child, TerminalNode):
            print(lvl*'│ ' + '└─', child)
        else:
            handleTree(child, lvl+1)

Теперь вывод:

[16068 15857 2535 2384]
[16066 16068 15857 2535 2384]
[16256 16066 16068 15857 2535 2384]
[16263 16256 16066 16068 15857 2535 2384]
SELECT
│ │ │ │ └─ SELECT
[16284 16263 16256 16066 16068 15857 2535 2384]
[16309 16284 16263 16256 16066 16068 15857 2535 2384]
[16326 16309 16284 16263 16256 16066 16068 15857 2535 2384]
[17255 16326 16309 16284 16263 16256 16066 16068 15857 2535 2384]
[17264 17255 16326 16309 16284 16263 16256 16066 16068 15857 2535 2384]
[17280 17264 17255 16326 16309 16284 16263 16256 16066 16068 15857 2535 2384]
[17318 17280 17264 17255 16326 16309 16284 16263 16256 16066 16068 15857 2535 2384]
[17339 17318 17280 17264 17255 16326 16309 16284 16263 16256 16066 16068 15857 2535 2384]
[17350 17339 17318 17280 17264 17255 16326 16309 16284 16263 16256 16066 16068 15857 2535 2384]
[17409 17350 17339 17318 17280 17264 17255 16326 16309 16284 16263 16256 16066 16068 15857 2535 2384]
[17472 17409 17350 17339 17318 17280 17264 17255 16326 16309 16284 16263 16256 16066 16068 15857 2535 2384]
[17555 17472 17409 17350 17339 17318 17280 17264 17255 16326 16309 16284 16263 16256 16066 16068 15857 2535 2384]
[17669 17555 17472 17409 17350 17339 17318 17280 17264 17255 16326 16309 16284 16263 16256 16066 16068 15857 2535 2384]
[2342 17669 17555 17472 17409 17350 17339 17318 17280 17264 17255 16326 16309 16284 16263 16256 16066 16068 15857 2535 2384]
[19724 2342 17669 17555 17472 17409 17350 17339 17318 17280 17264 17255 16326 16309 16284 16263 16256 16066 16068 15857 2535 2384]
[19747 19724 2342 17669 17555 17472 17409 17350 17339 17318 17280 17264 17255 16326 16309 16284 16263 16256 16066 16068 15857 2535 2384]
[20209 19747 19724 2342 17669 17555 17472 17409 17350 17339 17318 17280 17264 17255 16326 16309 16284 16263 16256 16066 16068 15857 2535 2384]
ta
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ ta
.
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ .
[19733 17669 17555 17472 17409 17350 17339 17318 17280 17264 17255 16326 16309 16284 16263 16256 16066 16068 15857 2535 2384]
[19747 19733 17669 17555 17472 17409 17350 17339 17318 17280 17264 17255 16326 16309 16284 16263 16256 16066 16068 15857 2535 2384]
[20209 19747 19733 17669 17555 17472 17409 17350 17339 17318 17280 17264 17255 16326 16309 16284 16263 16256 16066 16068 15857 2535 2384]
col1
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ col1
,
│ │ │ │ │ └─ ,
[16311 16284 16263 16256 16066 16068 15857 2535 2384]
[16326 16311 16284 16263 16256 16066 16068 15857 2535 2384]
[17255 16326 16311 16284 16263 16256 16066 16068 15857 2535 2384]
[17264 17255 16326 16311 16284 16263 16256 16066 16068 15857 2535 2384]
[17280 17264 17255 16326 16311 16284 16263 16256 16066 16068 15857 2535 2384]
[17318 17280 17264 17255 16326 16311 16284 16263 16256 16066 16068 15857 2535 2384]
[17339 17318 17280 17264 17255 16326 16311 16284 16263 16256 16066 16068 15857 2535 2384]
[17350 17339 17318 17280 17264 17255 16326 16311 16284 16263 16256 16066 16068 15857 2535 2384]
[17409 17350 17339 17318 17280 17264 17255 16326 16311 16284 16263 16256 16066 16068 15857 2535 2384]
[17472 17409 17350 17339 17318 17280 17264 17255 16326 16311 16284 16263 16256 16066 16068 15857 2535 2384]
[17555 17472 17409 17350 17339 17318 17280 17264 17255 16326 16311 16284 16263 16256 16066 16068 15857 2535 2384]
[17669 17555 17472 17409 17350 17339 17318 17280 17264 17255 16326 16311 16284 16263 16256 16066 16068 15857 2535 2384]
[2342 17669 17555 17472 17409 17350 17339 17318 17280 17264 17255 16326 16311 16284 16263 16256 16066 16068 15857 2535 2384]
[19724 2342 17669 17555 17472 17409 17350 17339 17318 17280 17264 17255 16326 16311 16284 16263 16256 16066 16068 15857 2535 2384]
[19747 19724 2342 17669 17555 17472 17409 17350 17339 17318 17280 17264 17255 16326 16311 16284 16263 16256 16066 16068 15857 2535 2384]
[20209 19747 19724 2342 17669 17555 17472 17409 17350 17339 17318 17280 17264 17255 16326 16311 16284 16263 16256 16066 16068 15857 2535 2384]
tb
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ tb
.
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ .
[19733 17669 17555 17472 17409 17350 17339 17318 17280 17264 17255 16326 16311 16284 16263 16256 16066 16068 15857 2535 2384]
[19747 19733 17669 17555 17472 17409 17350 17339 17318 17280 17264 17255 16326 16311 16284 16263 16256 16066 16068 15857 2535 2384]
[20209 19747 19733 17669 17555 17472 17409 17350 17339 17318 17280 17264 17255 16326 16311 16284 16263 16256 16066 16068 15857 2535 2384]
col5
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ col5
[16288 16263 16256 16066 16068 15857 2535 2384]
FROM
│ │ │ │ │ └─ FROM
[16320 16288 16263 16256 16066 16068 15857 2535 2384]
[16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[16340 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[16351 16340 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[16361 16351 16340 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[17152 16361 16351 16340 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[19376 17152 16361 16351 16340 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[20207 19376 17152 16361 16351 16340 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[20209 20207 19376 17152 16361 16351 16340 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
mytabA
│ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ mytabA
[16358 16340 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[19174 16358 16340 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[20207 19174 16358 16340 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[20209 20207 19174 16358 16340 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
ta
│ │ │ │ │ │ │ │ │ │ │ │ └─ ta
[16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
JOIN
│ │ │ │ │ │ │ │ └─ JOIN
[16397 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[16351 16397 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[16361 16351 16397 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[17152 16361 16351 16397 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[19376 17152 16361 16351 16397 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[20207 19376 17152 16361 16351 16397 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[20209 20207 19376 17152 16361 16351 16397 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
mayTabB
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ mayTabB
[16358 16397 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[19174 16358 16397 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[20207 19174 16358 16397 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[20209 20207 19174 16358 16397 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
tb
│ │ │ │ │ │ │ │ │ │ │ │ │ └─ tb
[16401 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
ON
│ │ │ │ │ │ │ │ │ └─ ON
[16414 16401 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[17217 16414 16401 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[17255 17217 16414 16401 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[17264 17255 17217 16414 16401 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[17280 17264 17255 17217 16414 16401 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[17318 17280 17264 17255 17217 16414 16401 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[2070 17318 17280 17264 17255 17217 16414 16401 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[17339 2070 17318 17280 17264 17255 17217 16414 16401 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[17350 17339 2070 17318 17280 17264 17255 17217 16414 16401 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[17409 17350 17339 2070 17318 17280 17264 17255 17217 16414 16401 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[17472 17409 17350 17339 2070 17318 17280 17264 17255 17217 16414 16401 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[17555 17472 17409 17350 17339 2070 17318 17280 17264 17255 17217 16414 16401 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[17669 17555 17472 17409 17350 17339 2070 17318 17280 17264 17255 17217 16414 16401 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[2342 17669 17555 17472 17409 17350 17339 2070 17318 17280 17264 17255 17217 16414 16401 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[19724 2342 17669 17555 17472 17409 17350 17339 2070 17318 17280 17264 17255 17217 16414 16401 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[19747 19724 2342 17669 17555 17472 17409 17350 17339 2070 17318 17280 17264 17255 17217 16414 16401 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[20209 19747 19724 2342 17669 17555 17472 17409 17350 17339 2070 17318 17280 17264 17255 17217 16414 16401 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
ta
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ ta
.
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ .
[19733 17669 17555 17472 17409 17350 17339 2070 17318 17280 17264 17255 17217 16414 16401 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[19747 19733 17669 17555 17472 17409 17350 17339 2070 17318 17280 17264 17255 17217 16414 16401 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[20209 19747 19733 17669 17555 17472 17409 17350 17339 2070 17318 17280 17264 17255 17217 16414 16401 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
col1
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ col1
[17342 17318 17280 17264 17255 17217 16414 16401 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
=
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ =
[17343 17318 17280 17264 17255 17217 16414 16401 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[17339 17343 17318 17280 17264 17255 17217 16414 16401 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[17350 17339 17343 17318 17280 17264 17255 17217 16414 16401 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[17409 17350 17339 17343 17318 17280 17264 17255 17217 16414 16401 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[17472 17409 17350 17339 17343 17318 17280 17264 17255 17217 16414 16401 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[17555 17472 17409 17350 17339 17343 17318 17280 17264 17255 17217 16414 16401 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[17669 17555 17472 17409 17350 17339 17343 17318 17280 17264 17255 17217 16414 16401 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[2342 17669 17555 17472 17409 17350 17339 17343 17318 17280 17264 17255 17217 16414 16401 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[19724 2342 17669 17555 17472 17409 17350 17339 17343 17318 17280 17264 17255 17217 16414 16401 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[19747 19724 2342 17669 17555 17472 17409 17350 17339 17343 17318 17280 17264 17255 17217 16414 16401 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[20209 19747 19724 2342 17669 17555 17472 17409 17350 17339 17343 17318 17280 17264 17255 17217 16414 16401 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
tb
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ tb
.
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ .
[19733 17669 17555 17472 17409 17350 17339 17343 17318 17280 17264 17255 17217 16414 16401 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[19747 19733 17669 17555 17472 17409 17350 17339 17343 17318 17280 17264 17255 17217 16414 16401 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
[20209 19747 19733 17669 17555 17472 17409 17350 17339 17343 17318 17280 17264 17255 17217 16414 16401 16341 16332 16320 16288 16263 16256 16066 16068 15857 2535 2384]
col2
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ col2
[16289 16263 16256 16066 16068 15857 2535 2384]
WHERE
│ │ │ │ │ └─ WHERE
[19182 16289 16263 16256 16066 16068 15857 2535 2384]
[17217 19182 16289 16263 16256 16066 16068 15857 2535 2384]
[17255 17217 19182 16289 16263 16256 16066 16068 15857 2535 2384]
[17264 17255 17217 19182 16289 16263 16256 16066 16068 15857 2535 2384]
[17280 17264 17255 17217 19182 16289 16263 16256 16066 16068 15857 2535 2384]
[17318 17280 17264 17255 17217 19182 16289 16263 16256 16066 16068 15857 2535 2384]
[2070 17318 17280 17264 17255 17217 19182 16289 16263 16256 16066 16068 15857 2535 2384]
[17339 2070 17318 17280 17264 17255 17217 19182 16289 16263 16256 16066 16068 15857 2535 2384]
[17350 17339 2070 17318 17280 17264 17255 17217 19182 16289 16263 16256 16066 16068 15857 2535 2384]
[17409 17350 17339 2070 17318 17280 17264 17255 17217 19182 16289 16263 16256 16066 16068 15857 2535 2384]
[17472 17409 17350 17339 2070 17318 17280 17264 17255 17217 19182 16289 16263 16256 16066 16068 15857 2535 2384]
[17555 17472 17409 17350 17339 2070 17318 17280 17264 17255 17217 19182 16289 16263 16256 16066 16068 15857 2535 2384]
[17669 17555 17472 17409 17350 17339 2070 17318 17280 17264 17255 17217 19182 16289 16263 16256 16066 16068 15857 2535 2384]
[2342 17669 17555 17472 17409 17350 17339 2070 17318 17280 17264 17255 17217 19182 16289 16263 16256 16066 16068 15857 2535 2384]
[19724 2342 17669 17555 17472 17409 17350 17339 2070 17318 17280 17264 17255 17217 19182 16289 16263 16256 16066 16068 15857 2535 2384]
[19747 19724 2342 17669 17555 17472 17409 17350 17339 2070 17318 17280 17264 17255 17217 19182 16289 16263 16256 16066 16068 15857 2535 2384]
[20209 19747 19724 2342 17669 17555 17472 17409 17350 17339 2070 17318 17280 17264 17255 17217 19182 16289 16263 16256 16066 16068 15857 2535 2384]
ta
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ ta
.
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ .
[19733 17669 17555 17472 17409 17350 17339 2070 17318 17280 17264 17255 17217 19182 16289 16263 16256 16066 16068 15857 2535 2384]
[19747 19733 17669 17555 17472 17409 17350 17339 2070 17318 17280 17264 17255 17217 19182 16289 16263 16256 16066 16068 15857 2535 2384]
[20209 19747 19733 17669 17555 17472 17409 17350 17339 2070 17318 17280 17264 17255 17217 19182 16289 16263 16256 16066 16068 15857 2535 2384]
col3
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ col3
[17342 17318 17280 17264 17255 17217 19182 16289 16263 16256 16066 16068 15857 2535 2384]
=
│ │ │ │ │ │ │ │ │ │ │ │ └─ =
[17343 17318 17280 17264 17255 17217 19182 16289 16263 16256 16066 16068 15857 2535 2384]
[17339 17343 17318 17280 17264 17255 17217 19182 16289 16263 16256 16066 16068 15857 2535 2384]
[17350 17339 17343 17318 17280 17264 17255 17217 19182 16289 16263 16256 16066 16068 15857 2535 2384]
[17409 17350 17339 17343 17318 17280 17264 17255 17217 19182 16289 16263 16256 16066 16068 15857 2535 2384]
[17472 17409 17350 17339 17343 17318 17280 17264 17255 17217 19182 16289 16263 16256 16066 16068 15857 2535 2384]
[17555 17472 17409 17350 17339 17343 17318 17280 17264 17255 17217 19182 16289 16263 16256 16066 16068 15857 2535 2384]
[17667 17555 17472 17409 17350 17339 17343 17318 17280 17264 17255 17217 19182 16289 16263 16256 16066 16068 15857 2535 2384]
[20185 17667 17555 17472 17409 17350 17339 17343 17318 17280 17264 17255 17217 19182 16289 16263 16256 16066 16068 15857 2535 2384]
'AXA'
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ 'AXA'

Кажется, мне нужно отслеживать значения массива child и определять, какие из них сигнализируют об имени таблицы, имени столбца, JOIN и т. д.

Неужели использование Antlr должно быть таким сложным?

Есть ли способ «запросить» древовидную структуру для определенных узлов, и если да, то какой запрос для получения этой конкретной информации?

Есть ли способ распечатать уникальные типы узлов, чтобы мы могли понять, какие из них искать?

Вам нужно сделать это с помощью Python3 или это можно реализовать с помощью CSharp (гораздо быстрее)? И нужно ли вам реализовать это как посетитель Antlr или это можно реализовать с помощью программы командной строки? Вы по-прежнему можете использовать Antlr, но писать программы для извлечения данных — это старомодно.

kaby76 09.06.2024 13:06

@ kaby76 Python используется потому, что в системе Linux его удобнее настраивать и использовать. Кроме того, я проделал большую работу, пытаясь настроить и запустить компоненты Pythion Antlr4, я бы не хотел повторять это. У меня нет явных предпочтений в использовании посетителей — мои исследования привели меня к выводу, что вариант «Посетитель/Прослушиватель» будет самым простым способом. Полагаю, что с C# я мог бы использовать dotNet для Linux. Любые практические предложения и помощь будут горячо оценены.

Pro West 09.06.2024 13:16

@ kaby76 также добавлю: мне удалось написать сценарий Python, который сканирует весь код PLSQL и извлекает каждую функцию/процедуру, а также любые функции/процедуры, которые они вызывают, в файл JSON. Я закончил это тем, что получил плоский токенизированный источник в виде одной строки чисел для токенов и имен (например, в вопросе), а затем какой-то очень уродливый re.sub, чтобы свести его к необходимым данным. Это медленно - обработка 400 файлов заняла 40 минут). Так что можно рассмотреть что-нибудь более быстрое.

Pro West 09.06.2024 13:21

Цель Python3 работает очень медленно, поскольку грамматика plsql неоднозначна. Цель CSharp будет примерно в 8 раз быстрее, немного быстрее. Будет ли что-то подобное работать? $ trparse -i "SELECT ta.col1, tb.col5 FROM mytabA ta JOIN mayTabB tb ON ta.col1 = tb.col2 WHERE ta.col3 = 'AXA';" | trxgrep ' //join_clause' | trtext => JOIN mayTabB tb ON ta.col1 = tb.col2

kaby76 09.06.2024 13:44

@ kaby76 Я готов попробовать, да.

Pro West 09.06.2024 13:50

Вот лучший способ распечатать дерево разбора на консоли: gist.github.com/bkiers/13f72ef15d8353814cc7cbb93e9cc742

Bart Kiers 10.06.2024 20:42

@BartKiers Спасибо. Это фантастическая помощь. Я все еще пытаюсь понять, как можно «запросить» такую ​​структуру, чтобы легко выбрать, например, имена таблиц или имена столбцов из SQL.

Pro West 10.06.2024 21:58
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
7
68
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вот краткая демонстрация того, как вы можете использовать прослушиватель в Python для «прослушивания», когда парсер вводит правило синтаксического анализатора tableview_name:

import antlr4
from PlSqlLexer import PlSqlLexer
from PlSqlParser import PlSqlParser
from antlr_utils import to_string_tree  # from: https://gist.github.com/bkiers/13f72ef15d8353814cc7cbb93e9cc742
from PlSqlParserListener import PlSqlParserListener


class TableViewListener(PlSqlParserListener):

    # (part of the) parse tree:
    #
    #    ║                    ║        ║  ║     ╚═ tableview_name
    #    ║                    ║        ║  ║        ╚═ identifier
    #    ║                    ║        ║  ║           ╚═ id_expression
    #    ║                    ║        ║  ║              ╚═ regular_id
    #    ║                    ║        ║  ║                 ╚═ "mytabA" (REGULAR_ID)
    #
    # ANTLR parser rule for `tableview_name`:
    #
    # tableview_name
    #     : identifier ('.' id_expression)? (
    #         AT_SIGN link_name
    #         | partition_extension_clause
    #     )?
    #     | xmltable outer_join_sign?
    #     ;
    def enterTableview_name(self, ctx:PlSqlParser.Tableview_nameContext):
        print('Found a table:', ctx.getText())


if __name__ == '__main__':
    sql = """
        SELECT ta.col1, tb.col5
        FROM   mytabA ta
        JOIN  mayTabB tb ON ta.col1 = tb.col2
        WHERE ta.col3 = 'AXA';
        """
    lexer = PlSqlLexer(antlr4.InputStream(sql))
    parser = PlSqlParser(antlr4.CommonTokenStream(lexer))
    root = parser.sql_script()
    print(to_string_tree(root, lexer.symbolicNames))
    antlr4.ParseTreeWalker.DEFAULT.walk(TableViewListener(), root)

Запуск приведенного выше кода Python выведет:

╚═ sql_script
   ╠═ unit_statement
   ║  ╚═ data_manipulation_language_statements
   ║     ╚═ select_statement
   ║        ╚═ select_only_statement
   ║           ╚═ subquery
   ║              ╚═ subquery_basic_elements
   ║                 ╚═ query_block
   ║                    ╠═ "SELECT" (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
   ║                    ║  ║                                   ║  ╚═ general_element_part
   ║                    ║  ║                                   ║     ╚═ id_expression
   ║                    ║  ║                                   ║        ╚═ regular_id
   ║                    ║  ║                                   ║           ╚═ "ta" (REGULAR_ID)
   ║                    ║  ║                                   ╠═ "." (PERIOD)
   ║                    ║  ║                                   ╚═ general_element_part
   ║                    ║  ║                                      ╚═ id_expression
   ║                    ║  ║                                         ╚═ regular_id
   ║                    ║  ║                                            ╚═ "col1" (REGULAR_ID)
   ║                    ║  ╠═ "," (COMMA)
   ║                    ║  ╚═ 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
   ║                    ║                                      ║  ╚═ general_element_part
   ║                    ║                                      ║     ╚═ id_expression
   ║                    ║                                      ║        ╚═ regular_id
   ║                    ║                                      ║           ╚═ "tb" (REGULAR_ID)
   ║                    ║                                      ╠═ "." (PERIOD)
   ║                    ║                                      ╚═ general_element_part
   ║                    ║                                         ╚═ id_expression
   ║                    ║                                            ╚═ regular_id
   ║                    ║                                               ╚═ "col5" (REGULAR_ID)
   ║                    ╠═ from_clause
   ║                    ║  ╠═ "FROM" (FROM)
   ║                    ║  ╚═ table_ref_list
   ║                    ║     ╚═ table_ref
   ║                    ║        ╠═ table_ref_aux
   ║                    ║        ║  ╠═ table_ref_aux_internal_one
   ║                    ║        ║  ║  ╚═ dml_table_expression_clause
   ║                    ║        ║  ║     ╚═ tableview_name
   ║                    ║        ║  ║        ╚═ identifier
   ║                    ║        ║  ║           ╚═ id_expression
   ║                    ║        ║  ║              ╚═ regular_id
   ║                    ║        ║  ║                 ╚═ "mytabA" (REGULAR_ID)
   ║                    ║        ║  ╚═ table_alias
   ║                    ║        ║     ╚═ identifier
   ║                    ║        ║        ╚═ id_expression
   ║                    ║        ║           ╚═ regular_id
   ║                    ║        ║              ╚═ "ta" (REGULAR_ID)
   ║                    ║        ╚═ join_clause
   ║                    ║           ╠═ "JOIN" (JOIN)
   ║                    ║           ╠═ table_ref_aux
   ║                    ║           ║  ╠═ table_ref_aux_internal_one
   ║                    ║           ║  ║  ╚═ dml_table_expression_clause
   ║                    ║           ║  ║     ╚═ tableview_name
   ║                    ║           ║  ║        ╚═ identifier
   ║                    ║           ║  ║           ╚═ id_expression
   ║                    ║           ║  ║              ╚═ regular_id
   ║                    ║           ║  ║                 ╚═ "mayTabB" (REGULAR_ID)
   ║                    ║           ║  ╚═ table_alias
   ║                    ║           ║     ╚═ identifier
   ║                    ║           ║        ╚═ id_expression
   ║                    ║           ║           ╚═ regular_id
   ║                    ║           ║              ╚═ "tb" (REGULAR_ID)
   ║                    ║           ╚═ join_on_part
   ║                    ║              ╠═ "ON" (ON)
   ║                    ║              ╚═ 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
   ║                    ║                                ║                    ║  ╚═ general_element_part
   ║                    ║                                ║                    ║     ╚═ id_expression
   ║                    ║                                ║                    ║        ╚═ regular_id
   ║                    ║                                ║                    ║           ╚═ "ta" (REGULAR_ID)
   ║                    ║                                ║                    ╠═ "." (PERIOD)
   ║                    ║                                ║                    ╚═ general_element_part
   ║                    ║                                ║                       ╚═ id_expression
   ║                    ║                                ║                          ╚═ regular_id
   ║                    ║                                ║                             ╚═ "col1" (REGULAR_ID)
   ║                    ║                                ╠═ relational_operator
   ║                    ║                                ║  ╚═ " = " (EQUALS_OP)
   ║                    ║                                ╚═ relational_expression
   ║                    ║                                   ╚═ compound_expression
   ║                    ║                                      ╚═ concatenation
   ║                    ║                                         ╚═ model_expression
   ║                    ║                                            ╚═ unary_expression
   ║                    ║                                               ╚═ atom
   ║                    ║                                                  ╚═ general_element
   ║                    ║                                                     ╠═ general_element
   ║                    ║                                                     ║  ╚═ general_element_part
   ║                    ║                                                     ║     ╚═ id_expression
   ║                    ║                                                     ║        ╚═ regular_id
   ║                    ║                                                     ║           ╚═ "tb" (REGULAR_ID)
   ║                    ║                                                     ╠═ "." (PERIOD)
   ║                    ║                                                     ╚═ general_element_part
   ║                    ║                                                        ╚═ id_expression
   ║                    ║                                                           ╚═ regular_id
   ║                    ║                                                              ╚═ "col2" (REGULAR_ID)
   ║                    ╚═ where_clause
   ║                       ╠═ "WHERE" (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
   ║                                         ║                    ║  ╚═ general_element_part
   ║                                         ║                    ║     ╚═ id_expression
   ║                                         ║                    ║        ╚═ regular_id
   ║                                         ║                    ║           ╚═ "ta" (REGULAR_ID)
   ║                                         ║                    ╠═ "." (PERIOD)
   ║                                         ║                    ╚═ general_element_part
   ║                                         ║                       ╚═ id_expression
   ║                                         ║                          ╚═ regular_id
   ║                                         ║                             ╚═ "col3" (REGULAR_ID)
   ║                                         ╠═ relational_operator
   ║                                         ║  ╚═ " = " (EQUALS_OP)
   ║                                         ╚═ relational_expression
   ║                                            ╚═ compound_expression
   ║                                               ╚═ concatenation
   ║                                                  ╚═ model_expression
   ║                                                     ╚═ unary_expression
   ║                                                        ╚═ atom
   ║                                                           ╚═ constant
   ║                                                              ╚═ quoted_string
   ║                                                                 ╚═ "'AXA'" (CHAR_STRING)
   ╠═ ";" (SEMICOLON)
   ╚═ "<EOF>"

Found a table: mytabA
Found a table: mayTabB

Обратите внимание на последние 2 строки:

Found a table: mytabA
Found a table: mayTabB

Потрясающий. Это именно то, что я хотел, и я могу использовать это для получения другой информации, которая мне нужна. Спасибо.

Pro West 13.06.2024 19:44

Существует множество способов решения проблемы извлечения условий JOIN из входных файлов PlSql. Решение, которое я предлагаю здесь, использует Antlr4 , [Dotnet] ( https://dotnet.microsoft.com/en-us/ ), grammars-v4/sql/plsql грамматику и Trash Toolkit, реализующий подход с использованием командной строки. Решение включает в себя создание программы C# для грамматики, запуск программы для создания дерева синтаксического анализа, поиск узлов дерева синтаксического анализа для условий JOIN и распечатку результатов.

Преимущество этого решения с использованием командной строки заключается в том, что вам не нужно писать драйвер и посетитель вручную. Сгенерированный код представляет собой библиотеку, которую trparse использует для анализа входных данных, а затем вывода быстрых стандартизированных деревьев синтаксического анализа, что является лингва франка набора инструментов. Парсер C# примерно на порядок быстрее, чем эквивалентный парсер Python3.

Шаги

Я предполагаю, что вы используете Ubuntu Linux и Bash.

  1. Получите предпосылки.

    i) Установите Dotnet 8. См. https://learn.microsoft.com/en-us/dotnet/core/install/linux-ubuntu-install?pivots=os-linux-ubuntu-2404&tabs=dotnet8

     sudo apt-get update && sudo apt-get install -y dotnet-sdk-8.0
    

    ii) Установите Trash Tool (только необходимые инструменты). Смотрите https://github.com/kaby76/Trash

     for t in trcaret trgen trglob triconv trparse trtext trwdog trxgrep trxml trxml2; do dotnet tool install -g $t; done
    
  2. Клонируйте репозиторий grammars-v4 и перейдите в каталог грамматики plsql.

    git clone https://github.com/antlr/grammars-v4.git
    cd grammars-v4/sql/plsql
    
  3. Создайте программу синтаксического анализа C# для грамматики plsql.

    trgen -t CSharp
    cd Generated-CSharp-full # (directory name varies)
    make
    
  4. Создайте входные файлы (in.sql), проанализируйте входные файлы SQL и извлеките JOIN. Вы можете исключить вывод trparse на предмет ошибок и времени, перенаправив его на stderr.

    $ trparse in.sql 2> /dev/null | trxgrep ' //join_clause' | trtext
    JOIN  mayTabB tb ON ta.col1 = tb.col2
    $ trparse -l in.sql 2> /dev/null | trxgrep ' //join_clause' | trcaret
    L3: JOIN  mayTabB tb ON ta.col1 = tb.col2
        ^
    

trparse может анализировать несколько входных файлов, например, trparse *.sql. trxgrep считывает деревья синтаксического анализа и запускает механизм XPath2 над деревом синтаксического анализа Antlr и выводит деревья синтаксического анализа, удовлетворяющие выражению XPath. trtext читает деревья синтаксического анализа и печатает текст, связанный с каждым узлом дерева синтаксического анализа. trcaret считывает деревья синтаксического анализа и выводит строку текста из ввода, содержащую узел дерева синтаксического анализа, с курсором (требуется добавление информации о строке в деревья синтаксического анализа через trparse). Используя XPath, можно создавать сложные запросы, связывающие разные узлы дерева с определенными значениями.

+10 Каби спасибо. Я выбрал другой ответ как предпочтительный только потому, что думаю, что он поможет мне в работе, которую я выполняю, используя Python для этих целей. Но я также рассмотрю этот инструмент trparse.

Pro West 13.06.2024 19:47

Другие вопросы по теме