Parser generator · Python 3.13+
Write the grammar.
Get the parser.
A small Python parser generator with no dependencies. Give it a grammar, and it builds LR0, SLR or LR1 parsing tables, and parsers that compute values on every reduction, with your callbacks or the grammar's primitives.
syntactes is a parser generator written in Python. The name comes from the
Greek συντάκτης (/sin'daktis/), meaning editor or composer.
- Grammars as text or as objects. Write one
lhs -> symbolsrule per line, or build theTokens andRules yourself. See Grammars. - Three kinds of tables. LR0, SLR and LR1 generators, with a readable printout and a list of conflicts. See Parsing tables.
- Callbacks on every reduction. Each rule's callback gets one token per right-hand side symbol, and its return value becomes the value of the left-hand side. See Parsing.
- Primitives in the grammar. Tag a rule with a primitive, like
add(1,3) % expr -> expr PLUS exprorint % term -> NUMBER, and the parser computes its value without a callback. See Primitives. - No dependencies. It uses only the standard library.
Here's a calculator in a few lines:
from syntactes import Grammar, Token
from syntactes.parser import LR1Parser
grammar = Grammar.from_text("""
expr -> expr PLUS term
expr -> term
term -> term TIMES NUMBER
term -> NUMBER
""")
start, add, pass_term, multiply, number = grammar.rules
parser = LR1Parser.from_grammar(grammar)
@parser.execute_on(start)
def result(expr):
return expr.value
@parser.execute_on(add)
def on_add(expr, plus, term):
return expr.value + term.value
@parser.execute_on(pass_term)
def on_term(term):
return term.value
@parser.execute_on(multiply)
def on_multiply(term, times, number):
return term.value * number.value
@parser.execute_on(number)
def on_number(number):
return number.value
def lex(text):
for word in text.split():
if word == "+":
yield Token("PLUS", True)
elif word == "*":
yield Token("TIMES", True)
else:
yield Token("NUMBER", True, int(word))
yield Token.eof()
print(parser.parse(lex("2 * 3 + 4"))) # 10
Need a scanner to produce the tokens? The sibling project
lectes scans text with named regexes,
and its tokens map onto syntactes Tokens.