v5.21.0 Update#
Grammar, Optimization & Regex#
Grammar.parse()now eagerly callsself.optimized()before parsing, producing a newGrammarinstance rather than mutating in place.Grammar.optimize()and theoptrulesproperty have been removed. Code generators (pythongen,parsermodel_gen) also callmodel.optimized()before emitting source.All model nodes support deep optimization:
Model.optimized()returnscopy(self);Option,Group,Choice,Box,NamedBox,Sequence,Rule, andRuleIncludeeach optimize their children recursively, unwrapping single-element containers;Call.optimized()collapsesCall -> Rule(exp=Call)chains;Closure/Joinoverrides removed (handled byBox);EmptyClosure.__post_init__setsself.ast = None. Lazy attributes (_lookahead,_firstset,_follow_set) usegetattr()for safety with copied nodes.Model._set_grammar()renamed tolink().The
Functype replacesCallable[..., Any]infind_rule()and related interfaces.to_parsermodel_sourcecodeandcompile_to_parserare now exported fromtatsu.toolandtatsu.tool.api.The bootstrap parser and rules were regenerated to eliminate skeletal
Group/Optionwrapping.For compatibility with sibling projects 修TieXiu (Rust), ⻰OGoPEGo (Go), and ꘩TS’emekwes (TypeScript), all
Pattern-based regex lookaheads in the meta-grammar have been replaced with grammar-level&/!lookaheads. Thecommentsand multiline string regexes were simplified (dropped(?:.|\n)and(?!""")/(?!''')guards). TheDEDENTrule’s(?=\S)became&/\S/,raw_stringwas split into a two-step check, andpath/wordpatterns now use explicit[_a-zA-Z]instead of(?!\d)\wlookarounds.
Left Recursion Analysis#
The left-recursion modules have been renamed:
leftrecmarker.py→depthf.py,pegen_leftrec.py→pegen.py,graphtools.py→tools.py. A newautumn.pyprovides an alternative depth-framed algorithm. The SCC entry point inpegen.pyis nowmark_left_recursion().
Error Reporting#
FailedParse.__str__()usesstr.splitlines()and prints the error marker unconditionally (not just when the error lands on the current line).
Tooling, Build & Documentation#
The
tatsu.tool.benchnow supports benchmarking the ⻰OGoPEGoGoport via--ogo, and a--bothmode restricts to TatSu parsers only.failed_filesappears at the top in verbose output.The
Justfilereceived formatting cleanups and now omits--no-summaryfrom pytest invocations.docs/accept.txtacceptsJustfileas a token.README.rstnow has a Sibling Projects section.CLI tests use a
uv_run()helper with diagnostic assertions. The bootstrap test setstrace=Falseand removes the redundantg9.optimized()call (optimization is now insideparse()).