Rules dependent on each other
Closed this issue · 2 comments
ksqsf commented
Is it possible to define the following grammar?
val singleton by lbrace cmd rbrace; // singleton -> cmd
val expr by number or funccall or ... or singleton; // expr -> singleton
val cmd by expr semicol; // cmd -> expr
// the dependency is a cycle: cmd -> expr -> singleton -> cmd
so that this grammar accepts
{ 1; }
as an expression. I can't write the grammar in the naive way, because Kotlin rejects this code complaining "Variable cmd must be initialized". I tried lazy
but the properties seem to be NULL, not properly initialized.
edit: I added lazy to every parser but it ended up infinite recursion.
ksqsf commented
object NestedGrammar : Grammar<Int>() {
val ws by regexToken("\\w+", ignore = true)
val num by regexToken("[0-9]+")
val lbrace by literalToken("{")
val rbrace by literalToken("}")
val semicol by literalToken(";")
val number: Parser<Int> by num map { it.text.toInt() }
val singleton: Parser<Int> by -lbrace * cmd * -rbrace
val expr: Parser<Int> by number or singleton
val cmd: Parser<Int> by expr * semicol map { it.t1 }
override val rootParser by cmd
}
fun main() {
val text = "{ 1; };"
NestedGrammar.parseToEnd(text)
}
This is a minimal reproducible example.
ksqsf commented
Solved by using parser