/tmp/duangsuse.sock
23 subscribers
303 photos
3 videos
92 files
337 links
从 duangsuse::Echo (@dsuse) 跟进出来的分支,将在作者恢复原帐号访问的时候合并删除。
Download Telegram
abstract class Tuple<E>(override val size: Cnt): Sized {
protected abstract val items: Array<E>
operator fun get(index: Idx) = items[index]
operator fun set(index: Idx, value: E) { items[index] = value }
fun toArray(): Array<E> = items

protected class Index<T>(private val idx: Idx) {
operator fun getValue(self: Tuple<out T>, _p: KProperty<*>): T = self[idx]
operator fun setValue(self: Tuple<in T>, _p: KProperty<*>, value: T) { self[idx] = value }
}

override fun equals(other: Any?): Boolean {
if (this === other) return true
return if (other !is Tuple<*>) false
else (size == other.size) && items.contentEquals(other.items)
}
override fun hashCode(): Int = items.contentHashCode()
override fun toString(): String = "(${items.joinToString(", ")})"
}

data class Tuple2<A, B>(var first: A, var second: B)
typealias Producer<T> = () -> T
typealias Consumer<T> = (T) -> Unit
typealias Predicate<T> = (T) -> Boolean

typealias Fold<T, R> = FoldOp<T, *, R>
interface Reducer<in T, out R> {
fun accept(item: T)
fun finish(): R
}

abstract class FoldOp<in A, B, out C> {
protected abstract val initial: B
protected abstract fun join(base: B, item: A): B
protected abstract fun convert(base: B): C
fun reducer() = object: Reducer<A, C> {
private var base: B = initial
override fun accept(item: A) { base = join(base, item) }
override fun finish(): C = convert(base)
}
}
////////
abstract class Effect<A, B, C>: FoldOp<A, B, C>() {
protected abstract fun accept(base: B, item: A)
final override fun join(base: B, item: A): B = base.also { accept(base, item) }
}
abstract class Monoid<T>(mzero: T, private val mplus: T.(T) -> T): FoldOp<T, T, T>() {
override val initial: T = mzero
final override fun join(base: T, item: T): T = base.mplus(item)
final override fun convert(base: T): T = base
}

typealias AsList<T> = Effect<T, MutableList<T>, List<T>>
fun <T> asList() = object: AsList<T>() {
override val initial: MutableList<T> get() = mutableListOf()
override fun accept(base: MutableList<T>, item: T) { base.add(item) }
override fun convert(base: MutableList<T>): List<T> = base
}
fun buildStr() = object: FoldOp<Char, StringBuilder, String>() {
override val initial get() = StringBuilder()
override fun join(base: StringBuilder, item: Char) = base.append(item)
override fun convert(base: StringBuilder) = base.toString()
}
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
}
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)
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)
/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)
分成 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 #code
Parser.kt
10.1 KB
#Kotlin #code ParserKt,还差一点点就又写完了……
我严重简化了模型,相信这次,一定什么都能写! Until(asString(), item("\""), item())
Forwarded from Deleted Account
把 fun 换成 def;interface 换成 trait;泛型的 <> 换成 []、* 换成 _;函数类型的 (T)->R 换成 (T) => R 基本上就可以写 Scala 了
Scala 的闭包 {} 还有 { case A => R1; case B => R2 } 那种写法,相当复杂多样而且风格类似数学……
Scala 的 () => R 还可以直接省略 (),而且这语言不是惰性求值传参的,真是……
Forwarded from Deleted Account
最好还是不要为了理论写应用,那样容易忽视易用性
Forwarded from Deleted Account
但是作为一个新人,就要敢与恶鬼争高下
Forwarded from Deleted Account
不向霸王让寸分
Forwarded from Deleted Account
不要怂就是干
你觉得手写困难,那你就手写
Forwarded from Deleted Account
战胜困难的最好方法是面对它
Forwarded from Deleted Account
苟利技术生死以,岂因困难避趋之
Forwarded from Deleted Account
感觉这句话可以说三遍,如果觉得无聊了就换本书看,多买几本不同领域的书,比如算法/嵌入式/GUI应用/编译原理/语言实现换着看,是个不错的方法。
Forwarded from Deleted Account
以前有电脑的时候我根本不会看书,现在也是一样……

所以说一定不能让自己经常在电脑旁边…… 会死人的
思维也是不在实操编程的时候会灵活很多

许多不错的设计也都是在吃饭、散步什么的时候想出来的

所以这个下机时间很重要,学习期要多留

像我这样的码农,不太在乎(学习理论、实践理论)提升的,书基本不会看,编程比较多……