interface Pattern<T, R> {
fun read(s: Input<T>): R?
fun show(write: Consumer<T>, item: R?)
}
interface PositivePattern<T, R>: Pattern<T, R> {
override fun read(s: Input<T>): R
}
inline val notParsed: Nothing? get() = null
fun <T, R> Pattern<T, R>.toDefault(defaultValue: R) = object: PositivePattern<T, R> {
override fun read(s: Input<T>): R = this@toDefault.read(s) ?: defaultValue
override fun show(write: Consumer<T>, item: R?) { this@toDefault.show(write, item!!) }
}
fun <T, R> Pattern<T, R>.tryRead(s: Input<T>): R? {
fun read(): R? = try { this.read(s) }
catch (_: Feed.End) { notParsed }
val parsed: R?
s.mark(); parsed = read()
s.run { if (parsed == notParsed) reset() else unmark() }
return parsed
}
/tmp/duangsuse.sock
Parser.kt 现在有最大的问题就是 Input,不支持我之前说的镇静解析策略的 ErrorHandler,反而去兼容了 MarkReset —— 其实 MarkReset 完全不应该首要兼容的,它只会解决一些非常不容易出现的问题,还影响性能 Input 和 Feed 的层次也容易让人糊涂,Input 的魔法一点都不好玩,只是让人开心那么一会而已,很快实践时就会造成大问题,过度设计。 最重要的是 object: Pat 和 val name = Pat() 这种区别不应该再支持了,再支持势必要出大问题…
rt 此外是 SOR 模式不规范,不容易让人记住,我给起了个简化名 "SURD",Seq, Until, Repeat, Decide
然后对 atom patterns 进行规范,只有 deferred, satisfy, item, elem
扩展 pattern 有 TriePattern, InfixPattern, SurroundBy, JoinBy
InfixPattern 对 join operator 的抽象也有很严重的问题,之前是 enum class 都容易声明的,现在变成什么 from/to 啥鬼样子,不男不女的还造成了很严重的相等性判断问题,简直不是人写的
open class Deferred<T, R>(private val pat: Producer<Pattern<T, R>>): Pattern<T, R>
abstract class SatisfyTest<T>: Pattern<T, T> {
abstract fun test(item: T): Boolean
}
open class Satisfy<T>(val predicate: Predicate<T>): SatisfyTest<T>()
class AnyItem<T>: Satisfy<T>({ true })
open class Item<T>(val x: T): SatisfyTest<T>()
open class Element<T>(vararg val xs: T): AbstractSatisfy<T>() {
override fun test(item: T) = item in xs
override fun toString() = "(${xs.joinToString("|", transform = ::showRawString)})"
}
open class RangeElement(val xs: CharRange): AbstractSatisfy<Char>() {
override fun test(item: Char) = item in xs
override fun toString() = "$xs"
}
open class Seq<IN, T, TUP: Tuple<T>>(val allocator: Producer<TUP>, vararg val items: Pattern<IN, T>): Pattern<IN, TUP> {
override fun toString() = items.joinToString(" ").surround("(", ")")
}
abstract class Repeat<IN, T, R>(val fold: Fold<T, R>, val item: Pattern<IN, T>): Pattern<IN, R> {
open val countBound: Predicate<Cnt> = {true}
override fun toString() = "{$item}"
}
abstract class Decide<T, R>(vararg val cases: Pattern<T, R>): Pattern<T, R> {
override fun toString() = cases.joinToString("|").surround("(", ")")
}
open class Convert<T, R, R1>(val item: Pattern<T, R>, val from: (R) -> R1, val to: (R1) -> R): Pattern<T, R1>
override fun toString() = item.toString()
}
open class SurroundBy<T, R>(val lr: Pair<T, T>, val item: Pattern<T, R>): Pattern<T, R>
class TriePattern<K, V>: Trie<K, V>(), Pattern<K, V>
abstract class InfixPattern<IN, ATOM>(val atom: Pattern<IN, ATOM>, val op: Pattern<IN, Join<ATOM>>): Pattern<IN, ATOM> {
abstract fun onError(base: ATOM, op1: Join<ATOM>): Nothing
}
然后对 atom patterns 进行规范,只有 deferred, satisfy, item, elem
扩展 pattern 有 TriePattern, InfixPattern, SurroundBy, JoinBy
InfixPattern 对 join operator 的抽象也有很严重的问题,之前是 enum class 都容易声明的,现在变成什么 from/to 啥鬼样子,不男不女的还造成了很严重的相等性判断问题,简直不是人写的
open class Deferred<T, R>(private val pat: Producer<Pattern<T, R>>): Pattern<T, R>
abstract class SatisfyTest<T>: Pattern<T, T> {
abstract fun test(item: T): Boolean
}
open class Satisfy<T>(val predicate: Predicate<T>): SatisfyTest<T>()
class AnyItem<T>: Satisfy<T>({ true })
open class Item<T>(val x: T): SatisfyTest<T>()
open class Element<T>(vararg val xs: T): AbstractSatisfy<T>() {
override fun test(item: T) = item in xs
override fun toString() = "(${xs.joinToString("|", transform = ::showRawString)})"
}
open class RangeElement(val xs: CharRange): AbstractSatisfy<Char>() {
override fun test(item: Char) = item in xs
override fun toString() = "$xs"
}
open class Seq<IN, T, TUP: Tuple<T>>(val allocator: Producer<TUP>, vararg val items: Pattern<IN, T>): Pattern<IN, TUP> {
override fun toString() = items.joinToString(" ").surround("(", ")")
}
abstract class Repeat<IN, T, R>(val fold: Fold<T, R>, val item: Pattern<IN, T>): Pattern<IN, R> {
open val countBound: Predicate<Cnt> = {true}
override fun toString() = "{$item}"
}
abstract class Decide<T, R>(vararg val cases: Pattern<T, R>): Pattern<T, R> {
override fun toString() = cases.joinToString("|").surround("(", ")")
}
open class Convert<T, R, R1>(val item: Pattern<T, R>, val from: (R) -> R1, val to: (R1) -> R): Pattern<T, R1>
override fun toString() = item.toString()
}
open class SurroundBy<T, R>(val lr: Pair<T, T>, val item: Pattern<T, R>): Pattern<T, R>
class TriePattern<K, V>: Trie<K, V>(), Pattern<K, V>
abstract class InfixPattern<IN, ATOM>(val atom: Pattern<IN, ATOM>, val op: Pattern<IN, Join<ATOM>>): Pattern<IN, ATOM> {
abstract fun onError(base: ATOM, op1: Join<ATOM>): Nothing
}
deferred(pat)
SatisyTest
satisfy
anyItem, item(value)
element(vararg xs)
range(CharRange)
Seq(data, items)
Until(fold, item)
Repeat(fold, item)
Decide(cases)
Convert(item, from, to)
Contextual(head, body)
SurroundBy(lr, item)
JoinBy(seprator, item)
TriePattern()
InfixPattern(atom, op)
SatisyTest
satisfy
anyItem, item(value)
element(vararg xs)
range(CharRange)
Seq(data, items)
Until(fold, item)
Repeat(fold, item)
Decide(cases)
Convert(item, from, to)
Contextual(head, body)
SurroundBy(lr, item)
JoinBy(seprator, item)
TriePattern()
InfixPattern(atom, op)
satisfy(predicate)
anyItem item(value)
elementIn(vararg xs)
elementIn(CharRange)
Seq(data, items)
Until(fold, item, terminate)
Repeat(fold, item) { open val countBound: Preciate<Cnt> }
Decide(cases)
SatisfyTest { abstract fun test(value: IN): Boolean }
SurroundBy(lr, item)
JoinBy(seprator, item)
Deferred(item)
Convert(item, from, to)
Contextual(head, body)
TriePattern()
InfixPattern(seprator, item)
anyItem item(value)
elementIn(vararg xs)
elementIn(CharRange)
Seq(data, items)
Until(fold, item, terminate)
Repeat(fold, item) { open val countBound: Preciate<Cnt> }
Decide(cases)
SatisfyTest { abstract fun test(value: IN): Boolean }
SurroundBy(lr, item)
JoinBy(seprator, item)
Deferred(item)
Convert(item, from, to)
Contextual(head, body)
TriePattern()
InfixPattern(seprator, item)
/tmp/duangsuse.sock
satisfy(predicate) anyItem item(value) elementIn(vararg xs) elementIn(CharRange) Seq(data, items) Until(fold, item, terminate) Repeat(fold, item) { open val countBound: Preciate<Cnt> } Decide(cases) SatisfyTest { abstract fun test(value: IN): Boolean }…
SURD — Seq, Until, Repeat, Decide
IES — Item, ElementIn, Satisfy
合起来重写的版本不叫 Parser.kt 了,叫 Surdies 吧(迫真)
Seq(data, items)
Until(fold, terminate, item)
Repeat(fold, item) { open val countBound: Preciate<Cnt> }
Decide(cases)
item() item(value)
elementIn(vararg xs) elementIn(CharRange)
satisfy(predicate)
Deferred(item)
JoinBy(seprator, item)
SurroundBy(surround, item)
Convert(item, from, to)
Contextual(head, body)
TriePattern()
InfixPattern(seprator, item)
SatisfyTest 还要加一个逆命题 not() operator。
这样我们就可以 Until(ignore(), !elementIn(whiteSpaces), char)
Pattern<IN, T> 要有 toDefault(defaultValue: T): PositivePattern<IN, T>
需要用到的辅助模型:
Seq — Tuple
Repeat — Fold
TriePattern — Trie, Iterable.toMap, reverseMap, EnumMap
InfixPattern — InfixOp
typealias Producer<T> = () -> T
typealias Consumer<T> = (T) -> Unit
typealias Predicate<T> = (T) -> Boolean
Tuple 要 get/set, Index, toArray, equals, ext:toList
Tuple2
typealias AsList<T> = EffectFold<T, MutableList<T>, List<T>>
typealias BuildStr = ConvertFold<Char, StringBuilder, String>
class JoinFold<T>(initial: T, private val append: T.(T) -> T): Fold<T, T>
输入模型:
interface Feed<out T> {
val peek: T; fun consume(): T
class End: NoSuchElementException("no more")
}
interface Input<T>: Feed<T>, ErrorHandler<T>
abstract class SliceFeed
abstract class StreamFeed
open class CharInput: Input<Char>, SourceLocated
class CharInputCRLF
辅助:
fun <IN> Feed<IN>.consumeIf(predicate: Predicate<IN>): IN
fun <IN> Feed<IN>.takeWhile(predicate: Predicate<IN>): Sequence<IN>
fun <IN> Feed<IN>.take(n: Cnt): Sequence<IN>
fun impossible(): Nothing = error("impossible")
fun <T> MutableList<T>.removeLast() = removeAt(lastIndex)
IES — Item, ElementIn, Satisfy
合起来重写的版本不叫 Parser.kt 了,叫 Surdies 吧(迫真)
Seq(data, items)
Until(fold, terminate, item)
Repeat(fold, item) { open val countBound: Preciate<Cnt> }
Decide(cases)
item() item(value)
elementIn(vararg xs) elementIn(CharRange)
satisfy(predicate)
Deferred(item)
JoinBy(seprator, item)
SurroundBy(surround, item)
Convert(item, from, to)
Contextual(head, body)
TriePattern()
InfixPattern(seprator, item)
SatisfyTest 还要加一个逆命题 not() operator。
这样我们就可以 Until(ignore(), !elementIn(whiteSpaces), char)
Pattern<IN, T> 要有 toDefault(defaultValue: T): PositivePattern<IN, T>
需要用到的辅助模型:
Seq — Tuple
Repeat — Fold
TriePattern — Trie, Iterable.toMap, reverseMap, EnumMap
InfixPattern — InfixOp
typealias Producer<T> = () -> T
typealias Consumer<T> = (T) -> Unit
typealias Predicate<T> = (T) -> Boolean
Tuple 要 get/set, Index, toArray, equals, ext:toList
Tuple2
typealias AsList<T> = EffectFold<T, MutableList<T>, List<T>>
typealias BuildStr = ConvertFold<Char, StringBuilder, String>
class JoinFold<T>(initial: T, private val append: T.(T) -> T): Fold<T, T>
输入模型:
interface Feed<out T> {
val peek: T; fun consume(): T
class End: NoSuchElementException("no more")
}
interface Input<T>: Feed<T>, ErrorHandler<T>
abstract class SliceFeed
abstract class StreamFeed
open class CharInput: Input<Char>, SourceLocated
class CharInputCRLF
辅助:
fun <IN> Feed<IN>.consumeIf(predicate: Predicate<IN>): IN
fun <IN> Feed<IN>.takeWhile(predicate: Predicate<IN>): Sequence<IN>
fun <IN> Feed<IN>.take(n: Cnt): Sequence<IN>
fun impossible(): Nothing = error("impossible")
fun <T> MutableList<T>.removeLast() = removeAt(lastIndex)
分成 Extensions Slice Tuple Fold Input SURD IES MiscPattern TriePattern 这些部分实现?
class SliceFeed<T>(private val slice: Slice<T>): Feed<T> {
private var position = 0
private var tailConsumed = false
override val peek get() = slice[position] // v check for getPeek() v
override fun consume() = try { val got = peek; slice[++position]; got }
catch (_: IndexOutOfBoundsException) {
--position
if (!tailConsumed) peek.also { tailConsumed = true }
else throw Feed.End()
}
override fun toString() = "Slice(${peek}...${slice})"
}
不好看,只是可以加一个 noexcept,弃了弃了。 #Kotlin #codeForwarded from Deleted Account
把 fun 换成 def;interface 换成 trait;泛型的 <> 换成 []、* 换成 _;函数类型的 (T)->R 换成 (T) => R 基本上就可以写 Scala 了
Scala 的闭包 {} 还有 { case A => R1; case B => R2 } 那种写法,相当复杂多样而且风格类似数学……
Scala 的 () => R 还可以直接省略 (),而且这语言不是惰性求值传参的,真是……
Scala 的闭包 {} 还有 { case A => R1; case B => R2 } 那种写法,相当复杂多样而且风格类似数学……
Scala 的 () => R 还可以直接省略 (),而且这语言不是惰性求值传参的,真是……
Forwarded from Deleted Account
感觉这句话可以说三遍,如果觉得无聊了就换本书看,多买几本不同领域的书,比如算法/嵌入式/GUI应用/编译原理/语言实现换着看,是个不错的方法。
Forwarded from Deleted Account
以前有电脑的时候我根本不会看书,现在也是一样……
所以说一定不能让自己经常在电脑旁边…… 会死人的
思维也是不在实操编程的时候会灵活很多
许多不错的设计也都是在吃饭、散步什么的时候想出来的
所以这个下机时间很重要,学习期要多留
像我这样的码农,不太在乎(学习理论、实践理论)提升的,书基本不会看,编程比较多……
所以说一定不能让自己经常在电脑旁边…… 会死人的
思维也是不在实操编程的时候会灵活很多
许多不错的设计也都是在吃饭、散步什么的时候想出来的
所以这个下机时间很重要,学习期要多留
像我这样的码农,不太在乎(学习理论、实践理论)提升的,书基本不会看,编程比较多……
Forwarded from Deleted Account
成天水裙是没前途的 (无恶意,只是说,如果那样的话)
大概帮助,太冷漠太热情都不合适,还是点到为止。
大概帮助,太冷漠太热情都不合适,还是点到为止。