/tmp/duangsuse.sock
23 subscribers
303 photos
3 videos
92 files
337 links
从 duangsuse::Echo (@dsuse) 跟进出来的分支,将在作者恢复原帐号访问的时候合并删除。
Download Telegram
在我看来,ParserKt 的 LayoutPattern 和 传统方法 最大的差别就是
- PKT 的是 scannerless parsing,lexer-parser 的话那不是最后一层操作(各有优缺)
- Lexer 用数据栈、PKT 用系统栈(个人 profile,用系统栈貌似块那么几ms)
- PKT 没有利用 state,而把 state 建立在递归用栈里(当然它其实也是完全支持 contextual parsing 的)
- PKT 依赖 Deep { Root, Nest, Term } 这种递归数据结构存储解析结果,要再次转化为 AST 必须使用 Deep.Visitor(缺点)
- PKT 的 LayoutPattern 支持 rebuild,对调试很方便
- PKT 的 decideLayerItem; item, tail, layout 都是抽象的,而且 onNestIndent、onTermIndent 也都可重写。代码复用性很高(优点)
Forwarded from Deleted Account
@CodeHz 大佬,冰封之前也写过 lexer 层面把布局解析为内部 END token 的做法,你觉得我们这两个实现有啥优缺点呢 ~ 请dalao分析……
/tmp/duangsuse.sock
https://github.com/daorys1/mulan/blob/master/ulang/runtime/env.py#L213
lg.add('LBRACE', '{\\r*\\n*', flags=(re.DOTALL))
lg.add('RBRACE', '\\r*\\n*}', flags=(re.DOTALL))

代码质量奇差、异想天开
空格语法结构分不清,也不知道是简单了还是困难了,还是本来很 low 却很难伺候。
ParserKt 坚守节操,不修改 Feed 的基本定义,LL(1) 的问题完全可以利用 contextual 解析器,去区分……
Forwarded from Deleted Account
开始想 LL(1) 了,ParserKt 的 Feed,不可能 lookhead 任何字符,处理 /// 的分词,进退两难……
不知道是不是应该把分词降低到更低的层次、不知道是不是该模拟 state machine、不知道可不可能专门做兼容……
/tmp/duangsuse.sock
ParserKt 坚守节操,不修改 Feed 的基本定义,LL(1) 的问题完全可以利用 contextual 解析器,去区分……
ParserKt 针对 greedy trie pattern 根本没办法修复,因为它的 Feed 模型相当严格,一旦出现 peek = sticky end 的问题,非常难以解决——要判断是不是,必须 consume,consume 完若不是则一定会导致此字符已被消耗无法再用。

也不是不能利用扩展 Pattern 解决,确实是可以添加一个上下文,要求顺序解析 p1 p2 其中之一不为 notParsed,可那毕竟不是个容易复用的办法……
这个计算器足够,$#%#@……
/tmp/duangsuse.sock
ParserKt 针对 greedy trie pattern 根本没办法修复,因为它的 Feed 模型相当严格,一旦出现 peek = sticky end 的问题,非常难以解决——要判断是不是,必须 consume,consume 完若不是则一定会导致此字符已被消耗无法再用。 也不是不能利用扩展 Pattern 解决,确实是可以添加一个上下文,要求顺序解析 p1 p2 其中之一不为 notParsed,可那毕竟不是个容易复用的办法……
在 ParserKt 里,读取字符串非常简单,只需要 lookahead-1

val digit = digitFor('0'..'9')
val hex = Decide(digit, digitFor('A'..'Z', 'A', 10), digitFor('a'..'z', 'a', 10)).mergeFirst { if (it in 0..9) 0 else 1 }

val escapes = mapOf('"' to '"', 't' to '\t', 'b' to '\b', 'n' to '\n', 'r' to '\r', '\\' to '\\')
val namedEscape = MapPattern(escapes) { error("unknown escape '$it'"); '?' }
val unicodeEscapePart = object: Repeat<Char, Int, Int>(asInt(16), hex) {
override val bounds = 4..4
override val greedy = false
override fun unfold(value: Int) = value.toString(16).padStart(4, '0').map { hex.read(SingleFeed(it))!! } }
}
val unicodeEscape = Convert(unicodeEscapePart, Int::toChar, Char::toInt).clamWhile(hex, '?') {"bad unicode escape"}

val escaped = Decide(namedEscape, unicodeEscape).mergeFirst { if (it in escapes.values) 0 else 1 } prefix item('\\')
/tmp/duangsuse.sock
https://github.com/duangsuse-valid-projects/Share/blob/master/Others/kt_misc/pkt_9/String.kt#L17 ParserKt 总算稳当了些…… 🥳
fun KeywordPattern<String>.greedy() = Piped(this) { it ?: //FIXME is not possible
try { takeWhile { it !in this@greedy.routes }.joinToString("").takeIf(String::isNotEmpty) }
catch (_: Feed.End) { notParsed }
}

我还是不能容忍一个无法实际实现,有 bug 的 pattern 存在于 ParserKt 里。
混乱不堪的计算器
Forwarded from tim
算错了 一百除一 结果为 一百分一,一百除以一才是一百
Forwarded from Deleted Account
我不喜欢除以的表示方法,就是一个名字,除号的简写。
一百除一是”一百去除一“ 1.div(100)、1 / 100
一百除以一是 100.divBy(1)
这我知道
Forwarded from tim
除和除以的数学意义不一样啊
Forwarded from Deleted Account
我和数学有仇,我记不住数字而且也讨厌什么”蕴含“”可知“”易证“”平凡“那一套数学专属的逻辑表达,代码在这里,你去加?
Forwarded from Deleted Account
其实同时增加这两个操作符用不了两行代码,但是我就是不想加,因为 Kotlin 里面没有 divBy,我也觉得没必要区分”除“和“除以”。对“除”运算,这个主语引入的没啥意义,反正数学家现在都不用。
Forwarded from Deleted Account
> 3除以1
= 3
> 3除1
= 0