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 {
// ...
}
}