"""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)



