55 lines
1.3 KiB
Python
55 lines
1.3 KiB
Python
"""Expression utilities — all functions return grammar.py AST nodes."""
|
|
|
|
from .grammar import Symbol, Concat, Alt, Plus, Optional, Star, Epsilon, Empty
|
|
|
|
|
|
def sym(s):
|
|
"""Create a symbol node."""
|
|
return Symbol(s)
|
|
|
|
|
|
def concat(*parts):
|
|
"""Create concatenation AST node."""
|
|
parts = [p for p in parts if p and not isinstance(p, Epsilon)]
|
|
if not parts:
|
|
return Epsilon()
|
|
if len(parts) == 1:
|
|
return parts[0]
|
|
return Concat(parts)
|
|
|
|
|
|
def disj(*parts):
|
|
"""Create disjunction AST node."""
|
|
parts = [p for p in parts if p and not isinstance(p, Empty)]
|
|
if not parts:
|
|
return Empty()
|
|
if len(parts) == 1:
|
|
return parts[0]
|
|
return Alt(parts)
|
|
|
|
|
|
def star(expr):
|
|
"""Create one-or-more repetition AST node (r+)."""
|
|
if not expr or isinstance(expr, Empty):
|
|
return expr or Empty()
|
|
if isinstance(expr, Epsilon):
|
|
return Epsilon()
|
|
return Plus(expr)
|
|
|
|
|
|
def optional(expr):
|
|
"""Create optional AST node (r?)."""
|
|
if not expr or isinstance(expr, Empty):
|
|
return Epsilon()
|
|
if isinstance(expr, Epsilon):
|
|
return Epsilon()
|
|
return Optional(expr)
|
|
|
|
|
|
def alphabet(node):
|
|
"""Return set of alphabet symbols in AST node."""
|
|
from .grammar import alphabet as _grammar_alphabet
|
|
return _grammar_alphabet(node)
|
|
|
|
|
|
|