ANTLR 4 Python 3 Runtime
ANTLR (ANother Tool for Language Recognition) is a powerful parser generator. This library provides the Python 3 runtime for lexers and parsers generated by the ANTLR 4 tool. It enables Python applications to process structured text, validate input, and build abstract syntax trees (ASTs) for executing or translating languages. The current version is 4.13.2, with releases typically tied to the main ANTLR tool's irregular but generally annual or bi-annual update cycle.
Warnings
- breaking ANTLR 4.10 and newer versions drop support for Python 3.5. Attempts to install or run the runtime on Python 3.5 will result in `SyntaxError` due to the use of f-strings in the codebase.
- gotcha The `antlr4-python3-runtime` package only provides the runtime libraries. To generate Python lexer/parser source files (`.py` files) from your `.g4` grammar, you *must* have a Java Runtime Environment (JRE) installed and download the ANTLR 4 tool (a `.jar` file).
- breaking A known issue existed in version 4.13.1 where the ANTLR runtime's internal version check might conflict with the version of the generated code, leading to runtime errors.
- gotcha Care must be taken when choosing input streams. For string input, `InputStream` is generally used. For file input, `FileStream` is suitable. For reading from `sys.stdin`, `StdinStream` is available. Mismatching can lead to unexpected behavior or errors.
- gotcha ANTLR 4 provides both Listener and Visitor patterns for traversing parse trees. Listeners are event-driven and perform an LR traversal, calling `enter` and `exit` methods. Visitors offer more control by explicitly requiring you to call `visit()` methods, making them more flexible for complex tree manipulations.
Install
-
pip install antlr4-python3-runtime
Imports
- InputStream, CommonTokenStream, Lexer, Parser, ParseTreeWalker, ParserRuleContext
from antlr4 import InputStream, CommonTokenStream from MyGrammarLexer import MyGrammarLexer # Assumes MyGrammar.g4 was compiled from MyGrammarParser import MyGrammarParser # Assumes MyGrammar.g4 was compiled from MyGrammarListener import MyGrammarListener # For listener pattern
Quickstart
import os
from antlr4 import InputStream, CommonTokenStream, ParseTreeWalker
# --- BEGIN: Dummy generated classes for demonstration ---
# In a real scenario, these would be generated by the ANTLR tool:
# java -jar antlr-4.x.x-complete.jar -Dlanguage=Python3 MyGrammar.g4
class MyGrammarLexer:
def __init__(self, input_stream): pass
def getAllTokens(self): return []
class MyGrammarParser:
def __init__(self, token_stream): pass
def startRule(self): return None # Replace 'startRule' with your grammar's entry rule
class MyGrammarListener:
def enterEveryRule(self, ctx): pass
def exitEveryRule(self, ctx): pass
# ... other enter/exit methods for your grammar rules
# --- END: Dummy generated classes ---
# Assuming MyGrammar.g4 contains:
# grammar MyGrammar;
# startRule: 'hello' ID EOF;
# ID: [a-zA-Z]+;
# WS: [ \t\r\n]+ -> skip;
def parse_input(text):
input_stream = InputStream(text)
lexer = MyGrammarLexer(input_stream) # Use your generated Lexer class
stream = CommonTokenStream(lexer)
parser = MyGrammarParser(stream) # Use your generated Parser class
# Optionally, set up error handling
# parser.removeErrorListeners()
# parser.addErrorListener(MyCustomErrorListener())
tree = parser.startRule() # Call the entry rule of your grammar
# Optionally, walk the parse tree with a listener or visitor
# walker = ParseTreeWalker()
# listener = MyGrammarListener() # Use your generated Listener/Visitor class
# walker.walk(listener, tree)
print(f"Parse tree: {tree.toStringTree(recog=parser)}")
if __name__ == '__main__':
# Simulate user input or a file content
# For a real application, you might read from stdin or a file
test_input = os.environ.get('ANTLR_TEST_INPUT', 'hello world')
print(f"Parsing: '{test_input}'")
parse_input(test_input)
print("Note: In a real scenario, 'MyGrammarLexer' and 'MyGrammarParser' would be generated .py files from your .g4 grammar using the ANTLR Java tool.")