fun <T: Any> Feed<T>.takeWhile(predicate: Predicate<T>): Sequence<T> = generateSequence {
peek.takeIf(predicate)?.let { runCatching(::consume).getOrNull() }
}
fun <T> Feed<T>.takeWhile(predicate: Predicate<T>): Sequence<T> = sequence {
while (true)
if (predicate(peek)) yield(runCatching(::consume).getOrNull() ?: break)
else break
} #Kotlin sequences 好棒棒呀,一个 or 的逻辑从三行简化到了一行。
Repeat 现在需要 override fun show(write: Consumer<T>, item: R?)
因为 Fold 只能完成 from,并不能完成 to。
至于现在的 Tuple+read/show 和之前的 Fold+then/contextual 孰优孰劣,还没有定数
但现在规范化了解析失败的时候有
其实 Seq, Or, Repeat 也完全可以在 read 的时候 try catch 一下,给异常添加更多信息传下去,不过我觉得镇静模式就很好。
因为 Fold 只能完成 from,并不能完成 to。
至于现在的 Tuple+read/show 和之前的 Fold+then/contextual 孰优孰劣,还没有定数
但现在规范化了解析失败的时候有
clamUntil,还是比较好的其实 Seq, Or, Repeat 也完全可以在 read 的时候 try catch 一下,给异常添加更多信息传下去,不过我觉得镇静模式就很好。
Literate Kotlin 可以教小白了解自己的实现,但写起来很冗长,emmm……
回看那篇
回看那篇
Share
看完这段 Kotlin 代码后我哭了
🐕 duangsuse’s shared files(e.g. productive software projects, documents)
/tmp/duangsuse.sock
Calc.kt
提问!如何编写一个十进制解析器?
我们先来看看上一个版本怎么做:
不知道,好像不得不引入 contextual 解析器…… 其实也不一定需要…… 但是最好要有……
我们先来看看上一个版本怎么做:
class DecimalRead(mzero: Int): Monoid<Int>(mzero, { i -> this*10 + i })
object HexRead: Monoid<Int>(0, { i -> this*16 + i })
private val oneNine = element('1'..'9') then { it-'0' }
private val zero = item('0') const 0
private val digit = or(oneNine, zero)
private fun digitsCtx(zero: Int, optional: Boolean): CParser<Int>
= repeat(DecimalRead(zero), digit, if (optional) MAYBE else SOME)
val digits = digitsCtx(0, optional = false)
val digitsNoLeadingZero: CParser<Int> = or(digit.single(), oneNine contextual { digitsCtx(it, optional = true) })
private val hexDigit: CParser<Int> = or(digit, element('A'..'F') then { it-'A'+10 }, element('a'..'f') then { it-'a'+10 })
那么, 如何不允许前置 '0'?不知道,好像不得不引入 contextual 解析器…… 其实也不一定需要…… 但是最好要有……
class DecimalRead(zero: Int): Monoid<Int>(zero, { this*10 + it })
object Digit: Convert<Char, Char, Int>(RangeElement('0'..'9'), {it-'0'}, {'0'+it})
object Decimal: Repeat<Char, Int, Int>(DecimalRead(0), Digit) {
override fun show(write: Consumer<Char>, item: Int?) { item?.toString()?.forEach(write) }
}>>> val s=CharInput("",InputStreamFeed(System.`in`))
>>> s.takeWhile { it in '0'..'9' || it == '\n' }.toList()
12313
432
res17: kotlin.collections.List<kotlin.Char> = [
, 1, 2, 3, 1, 3,
, 4, 3, 2,
]
修好了 InputStreamFeedParser.kt
17.7 KB
class DecimalRead(zero: Int): Monoid<Int>(zero, { this*10 + it })
object Digit: Convert<Char, Char, Int>(RangeElement('0'..'9'), {it-'0'}, {'0'+it})
object Decimal: Repeat<Char, Int, Int>(DecimalRead(0), Digit) {
override fun show(write: Consumer<Char>, item: Int?) { item?.toString()?.forEach(write) }
}
总之就是可以用,但怎么用呢…… 明天再看 #Kotlin #code