Вот начало:
from antlr4 import *
from antlr4.tree.Tree import TerminalNodeImpl
from PlSqlLexer import PlSqlLexer
from PlSqlParser import PlSqlParser
# Generate the lexer nad parser like this:
#
# java -jar antlr-4.7.1-complete.jar -Dlanguage=Python3 *.g4
#
def main():
lexer = PlSqlLexer(InputStream("SELECT * FROM TABLE_NAME"))
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()
, которое печатает:
sql_script
unit_statement
data_manipulation_language_statements
select_statement
subquery
subquery_basic_elements
query_block
TOKEN='SELECT'
TOKEN='*'
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='TABLE_NAME'
Обратите внимание, что для правильной работы лексера и анализатора я добавил следующие классы Python:
# PlSqlBaseLexer.py
from antlr4 import *
class PlSqlBaseLexer(Lexer):
def IsNewlineAtPos(self, pos):
la = self._input.LA(pos)
return la == -1 or la == '\n'
и:
# PlSqlBaseParser.py
from antlr4 import *
class PlSqlBaseParser(Parser):
_isVersion10 = False
_isVersion12 = True
def isVersion10(self):
return self._isVersion10
def isVersion12(self):
return self._isVersion12
def setVersion10(self, value):
self._isVersion10 = value
def setVersion12(self, value):
self._isVersion12 = value
, которые я поместил в ту же папку, что и сгенерированные классы Python.Мне также нужно было добавить оператор импорта from PlSqlBaseLexer import PlSqlBaseLexer
в сгенерированный класс PlSqlLexer.py
и исправить оператор импорта в PlSqlParser.py
с from ./PlSqlBaseParser import PlSqlBaseParser
до from PlSqlBaseParser import PlSqlBaseParser
.
Обратите внимание, что запуск демо-версии довольномедленный.Если у вас нет строгих требований сделать это в Python, я рекомендую вместо этого использовать (намного!) Более быструю цель Java или C #.