içinde Free Monad'lar ile keyfi ağaçlar kullanma Dilbilgisi için iki farklı yorumu olan bir kitaplık oluşturuyorum: 1) dilbilgisi tarafından tanımlanan dilde dizeler oluşturma dilbilgisi 2) dizeleri ayrıştırma.Scala + Cats
Kütüphane, gramerin AST'sini serbest bir monad olarak oluşturmak için kediler kullanır. Ancak, bu mükemmel uyumsuz gibi görünmeyebilir çünkü serbest monadlar AST'nin deyim listeleri için güzel bir liste benzeri temsilini oluşturur, ancak bir dilbilgisi bir açıklama listesinden çok uzaktır ve keyfi bir ağaç yapısına daha yakındır.
Ağaçlarımı, birleştirilen 2 dilbilgiyi belirtmek için ~
işlecini kullanarak gerçekleştirmeyi başardım. AST, o zaman kendilerinin keyfi AST'leri olan bir gramer listesidir.
Sorum şu: Bir AST'nin alttiplerini ücretsiz bir monada tekrarlamak için iyi bir yol nedir?
Benim şu anki uygulama is here:
def parserInterpreter: GrammarA ~> ParserInterpreterState =
new (GrammarA ~> ParserInterpreterState) {
def apply[A](fa: GrammarA[A]): ParserInterpreterState[A] =
fa match {
case Regx(regexp) => parseRegex(regexp)
case Optional(b) => parseOptional(b.foldMap(this))
case m @ Multi(g) =>
def x: State[String, A] =
State.apply(state => {
g.foldMap(this)
.run(state)
.map {
case (s, ParseSuccess(_)) => x.run(s).value
case r @ (s, ParseFailure()) => (s, ParseSuccess(s).asInstanceOf[A])
}
.value
})
x
case Choice(a, b) =>
State.apply(state => {
val runA = a.foldMap(this).run(state).value
if (runA._2.asInstanceOf[ParseResult[_]].isSuccess)
runA
else {
b.foldMap(this).run(state).value
}
})
}
}
Not özellikle Multi
vaka yinelemeli alt ağacı yorumlamak amacıyla güvensiz özyinelemeye (yani kuyruk değil özyinelemeli) kullandığını. Bunu yapmanın daha iyi bir yolu var mı?
Please click here for the source code.