TatSu takes a grammar in a variation of EBNF as input, and outputs a memoizing PEG/Packrat parser in Python.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
The primary interface for compiling EBNF grammars and parsing input text using TatSu. These functions provide both one-step parsing for simple use cases and separate compilation for parser reuse and performance optimization.
Compile EBNF grammar definitions into reusable parser models with memoization and optimization support.
def compile(grammar, name=None, semantics=None, asmodel=False, config=None, **settings):
"""
Compile an EBNF grammar into a parser model.
Parameters:
- grammar (str): EBNF grammar definition string
- name (str, optional): Name for the parser (defaults to grammar filename base)
- semantics (object, optional): Semantic actions object with rule methods
- asmodel (bool): If True, use ModelBuilderSemantics automatically
- config (ParserConfig, optional): Parser configuration object
- **settings: Additional parser settings (trace, colorize, left_recursion, etc.)
Returns:
Model: Compiled parser model that can parse input text
Raises:
GrammarError: If grammar contains syntax or semantic errors
"""Usage example:
import tatsu
grammar = '''
start = expr;
expr = term ("+" term)*;
term = factor ("*" factor)*;
factor = "(" expr ")" | number;
number = /\d+/;
'''
# Basic compilation
model = tatsu.compile(grammar)
# Compilation with options
model = tatsu.compile(
grammar,
name="Calculator",
trace=True,
left_recursion=True
)
# Use the compiled model multiple times
result1 = model.parse("2 + 3")
result2 = model.parse("4 * 5")Parse input text using a grammar in a single function call, combining compilation and parsing for convenience.
def parse(grammar, input, start=None, name=None, semantics=None, asmodel=False, config=None, **settings):
"""
Parse input text using the provided grammar.
Parameters:
- grammar (str): EBNF grammar definition string
- input (str): Text to parse
- start (str, optional): Start rule name (defaults to first rule in grammar)
- name (str, optional): Parser name for error reporting
- semantics (object, optional): Semantic actions object
- asmodel (bool): If True, use ModelBuilderSemantics automatically
- config (ParserConfig, optional): Parser configuration object
- **settings: Additional parser settings
Returns:
Any: Parsed AST or result of semantic actions
Raises:
ParseException: If input cannot be parsed according to grammar
FailedParse: Specific parse failure with position information
"""Usage example:
import tatsu
grammar = '''
expr = number ("+" number)*;
number = /\d+/;
'''
# Direct parsing
result = tatsu.parse(grammar, "1 + 2 + 3")
print(result) # ['1', ['+', '2'], ['+', '3']]
# Parsing with semantic actions
class CalcSemantics:
def number(self, ast):
return int(ast)
def expr(self, ast):
result = ast[0]
for op, num in ast[1]:
result += num
return result
result = tatsu.parse(grammar, "1 + 2 + 3", semantics=CalcSemantics())
print(result) # 6The compiled Model object provides methods for parsing input and accessing grammar information.
class Model:
"""Compiled grammar model that can parse input text."""
def parse(self, input, start=None, semantics=None, config=None, **settings):
"""
Parse input text using this compiled grammar.
Parameters:
- input (str): Text to parse
- start (str, optional): Start rule name
- semantics (object, optional): Semantic actions object
- config (ParserConfig, optional): Parser configuration
- **settings: Additional parsing settings
Returns:
Any: Parsed AST or semantic action result
"""
def pretty(self):
"""
Return a pretty-printed version of the grammar.
Returns:
str: Formatted grammar text
"""
def pretty_lean(self):
"""
Return a lean pretty-printed version without annotations.
Returns:
str: Formatted grammar text without name: or ::Parameter annotations
"""
@property
def rules(self):
"""Get the grammar rules dictionary."""
def nodecount(self):
"""
Count the total number of nodes in the grammar AST.
Returns:
int: Total node count
"""Usage example:
model = tatsu.compile(grammar)
# Parse with the model
ast = model.parse("1 + 2 * 3")
# Get grammar information
print(f"Grammar has {len(model.rules)} rules")
print(f"Total nodes: {model.nodecount()}")
# Pretty print the grammar
print(model.pretty())Common parser settings that can be passed to compile() and parse() functions:
# Parser behavior settings
trace: bool = False # Enable verbose parsing trace output
colorize: bool = False # Use colored output in traces (requires colorama)
left_recursion: bool = True # Enable left-recursion support
nameguard: bool = None # Prevent tokens that are prefixes of others
whitespace: str = None # Characters to skip during parsing
# Grammar processing settings
filename: str = None # Source filename for error reporting
ignorecase: bool = False # Case-insensitive parsingCore parsing functions raise specific exceptions for different types of failures:
# Grammar compilation errors
GrammarError # Invalid grammar syntax or semantics
SemanticError # Semantic action processing errors
# Parse failures
ParseException # Base parsing exception
FailedParse # Parse failure with position info
FailedToken # Expected token not found
FailedPattern # Regex pattern didn't match
FailedChoice # No choice alternative matched
FailedKeyword # Keyword match failedExample error handling:
import tatsu
from tatsu.exceptions import ParseException, GrammarError
try:
# This will raise GrammarError - invalid grammar
model = tatsu.compile("invalid grammar syntax")
except GrammarError as e:
print(f"Grammar error: {e}")
try:
# This will raise FailedParse - parse failure
result = tatsu.parse("expr = 'hello';", "goodbye")
except ParseException as e:
print(f"Parse failed: {e}")
print(f"Position: line {e.line}, column {e.col}")Install with Tessl CLI
npx tessl i tessl/pypi-tatsu