/tmp/duangsuse.sock
23 subscribers
303 photos
3 videos
92 files
337 links
从 duangsuse::Echo (@dsuse) 跟进出来的分支,将在作者恢复原帐号访问的时候合并删除。
Download Telegram
Forwarded from Deleted Account
建议有条件的人去看看那个 https://codon.com/hello-declarative-world
Forwarded from Deleted Account
Kotlin 和 Java 可以基本互译
而且不是有 Lombok
Forwarded from Deleted Account
duangsuse 是计算机科学爱好者,偏向程序表达与转化(包含编译原理什么的)
喜欢Kotlin和OOP,最近随便写点想写的东西,主要是复用库。
我打算先弄完我这 Hosts,然后再随便检查一下写个 JSON 解析器

然后我想写汉字数值的解析器和输出……

然后想写 LayoutPattern
汉字数值最特殊的地方在于有 十一七百亿 这种,哈哈
感觉现在的解析策略虽然容错了,但有点奇奇怪怪的问题……
就是那一点“微不足道”的奇奇怪怪的问题,终结了我一天的时间……
头疼医头、脚痛医脚……
还好,我用修复了的 never(); always(); isStickyEnd() 和提出的 clamWhile 能够解决一些问题
Check(never()) { if (!isStickyEnd()) clamWhile(!nlChar, Line.Unknown, "unknown line") else it }
/tmp/duangsuse.sock
汉字数值最特殊的地方在于有 十一 和 七百亿 这种,哈哈
我不打算写汉字数值的,但打算写普通 1min2s 这种的
汉字的有一个特点,它的前置单位要递归,才支持 七百亿 这种

普通的没什么困难,就是累加和 max cmpLT、div/mod 好了
ParserKt 的 EOF 问题实在是太气人了
以 ANTLR 的威力,其实 EOF 问题也只是不存在罢了
但 ParserKt 可以解析数值的序列、Token 的序列,ANTLR 不能
而且那样 EOF 字符便不能合法存在了
我知道仅仅不允许 EOF 字符的说法很可笑,但 ParserKt 是泛型框架
/tmp/duangsuse.sock
写不了,整 StickyEOF 和 EOF Char 的问题已经心力交瘁,晚安
StickyEnd(nlChar or item(EOF), notParsed) { clamWhile(!nlChar, Line.Unknown, "unknown line") }
总算是解决了,ParserKt 走向实践之重大隐患
Deleted Account
sealed class Sexp { data class Term(val name: String): Sexp(); data class Nest(val list: List<Sexp>): Sexp() } lateinit var sexp: Pattern<Char, Sexp> val str = Until(elementIn(' ', *parens.items()), asString(), anyChar) val atom = Convert(str) { Sexp.Term(it)…
sealed class Sexp { data class Term(val name: String): Sexp(); data class Nest(val list: List<Sexp>): Sexp() }
lateinit var sexp: Pattern<Char, Sexp>
val str = Until(elementIn(' ', '(', ')'), asString(), anyChar)
val atom = Convert(str) { Sexp.Term(it) }
val nestItems = SurroundBy(parens.map(String::first).toPat(), JoinBy(item(' '), Deferred{sexp}).mergeConstantJoin())
val nest = Convert(nestItems) { Sexp.Nest(it) }
sexp = Decide(nest, atom).mergeFirst { if (it is Sexp.Term) 0 else 1 }
Forwarded from Deleted Account
我也重复了一下

个人建议:下次
- iter.joinToString("") { "$it" } 这类可读性不高的还是用 iter.joinToString("", Char::toString) 代替好了,尤其是 dollar string 不能滥用。
- 切忌把 Kotlin IO 写回 Haskell 式 IO,一旦发现代码太“空”,要及时调整,let 什么的是用来提升可读性的,不要用它降低代码密集度。
- n, p 这样的名字可以说是 meaningless…… n 叫 accumulator 吧。尤其是那个 p,怎么能叫 p 呢……
好可爱
https://github.com/mattbierner/bennu

哈,这个人非常的大佬,可是尽管 bennu Parser Combinator 很 Haskell,但远不如 ParserKt 工程,而且 ParserKt 实现了它的绝大部分常用功能。
var op = oneOf '><+-.,';
var other = many <| noneOf "><+-.,[]"; // Brainfuck ignores any other characters
var block = (body) => between(character '[', character ']', body);

var program := rec\self -> // allows referencing `program` in parse definition.
next(other, // consume non BF chars at start,
eager <| sepEndBy(other, // and between instructions and ending program
either(op,
block(self) )));


这 Haskell 系编程就有一个特点,它偏向艺术,喜欢弄一些数学上优雅但又没啥实际作用的小技巧。
ParserKt 里这还容易写明白一些

sealed class BF {
data class Op(val id: Char): BF()
data class Blk(val body: List<BF>): BF()
}
val control = elementIn('>', '<', '+', '-', '.', ',', ']')
val controlBF = Convert(control, { BF.Op(it) }, { it.id })
lateinit var program: Pattern<Char, List<BF>>
val block = SurroundBy(item('[') to item(']').clam("] !!!"), Deferred {program})
val blockBF = Convert(block, { BF.Blk(it) }, { it.body })

val ws = Repeat(asString(), !control).Many()
program = Convert(Seq(::AnyTuple, ws,
JoinBy(ws, Decide(blockBF, controlBF).mergeFirst { if (it is BF.Op) 0 else 1 }).mergeConstantJoin(""),
ws)) { it.getAs<List<BF>>(1) }