subtype

inline fun <T> subtype(): ParserNodeDeclaration<T>

When paired with sealed classes and self, allows defining abstract nodes that only exist via their subtypes.

Consider the following sealed class hierarchy:

sealed class Expression(...) {
    companion object : ParserNodeDeclaration<Expression> by subtype()
}

data class Operation(...) : Expression(...) {
    companion object : ParserNodeDeclaration<Operation> by reflective()
}

data class Value(...) : Expression(...) {
    companion object : ParserNodeDeclaration<Value> by reflective
}

You can define Expression like so:

niwenParser {
    Expression {
        either {
            expect(Operation) storeIn self()
        } or {
            expect(Value) storeIn self()
        }
    }

    Operation {
        // ...
    }

    Value {
        // ...
    }
}