/tmp/duangsuse.sock
23 subscribers
303 photos
3 videos
92 files
337 links
从 duangsuse::Echo (@dsuse) 跟进出来的分支,将在作者恢复原帐号访问的时候合并删除。
Download Telegram
Forwarded from Deleted Account
现在 ParserKt 可以在 100 行左右完成 JSON 的 read / show 了 🤔
Forwarded from Deleted Account
虽然我一直有在优化项目的接口易用性,但感觉还是有些“小乌云”……
顺序、直到、重复、选择 (SURD) 这些大结构没有变
单项、含于、符合 (IES) 的最后一个字母我给它加上了 StickyEnd,也算是解决了 Feed 模型的一个不被重视的问题
模式、正模式、可选模式、修饰模式 (PPOP) 我最后削掉了那个 PositivePattern
现在又变成了 POPCorn (都是助记的) 算是把 ConstantPattern 给合并到了基本模型里,方便 skip whitespaces 的 Pattern 的 rebuild。
Forwarded from Deleted Account
突然觉得我可以“汉化”一下,然后投稿给汉语编程,哈哈哈 😂
https://sap.github.io/chevrotain/docs/tutorial/step1_lexing.html#introduction
SELECT column1 FROM table2
SELECT name, age FROM persons WHERE age > 100

val letter = elementIn('a'..'z', 'A'..'Z') or item('_')
// [a-zA-Z]\w*
val name = Seq(::StringTuple, letter.toStringPat(), stringFor(letter or digit))
// 0|[1-9]\d*
val int = Contextual

sealed class SQL {
// SELECT {Name} FROM Name (WHERE Expr)?
class Select(val columns: List<String>, val table: String, val filter: Where?): SQL()
class Where(val expr: Expr)
}

val keyword = KeywordPattern<Pattern<Char, >


草写不出来了
https://tomassetti.me/parsing-in-javascript/#chevrotain

sealed class Token {
data class NamedConst(val name: String): Token()
}

fun KeywordPattern<Token>.mergeConsts(vararg names: String) = names.forEach { this[it] = Token.NamedConst(it) }
val namedConsts = KeywordPattern<Token>().apply {
mergeConsts("true", "false", "null")
}
val namedEscape = mapOf('b' to '\b', 't' to '\t', 'n' to '\n', 'r' to '\r', 'f' to '\u000C', 'v' to '\u000B')
val stringChar = Decide(!elementIn('"', '\n', '\\'), MapPattern(namedEscape) prefix item('\\')).mergeFirst {
if (it in namedEscape.values) 1 else 0 }
val string = SurroundBy(item('"') to item('"').clam {"unterminated string"}, stringFor(stringChar))
/tmp/duangsuse.sock
https://tomassetti.me/parsing-in-javascript/#chevrotain sealed class Token { data class NamedConst(val name: String): Token() } fun KeywordPattern<Token>.mergeConsts(vararg names: String) = names.forEach { this[it] = Token.NamedConst(it) } val namedConsts…
ParserKt 是 scannerless parsing 框架,目前对这样传统的 lexer-parser 结构 支持还不完善……

其实也可以用 iterator input,但着实是没好的 Pattern 去支持即时更新的 iterator
This media is not supported in your browser
VIEW IN TELEGRAM
我去专门独立于 Repeat pattern,写一个这种输入吧。
我把这个“封建余孽”加回来了…… 难道就是为了显示 ParserKt 很有灵活性么
class BoolScanner(feed: Feed<Char>): LexerFeed<Int>(feed) {
override fun tokenizer() = KeywordPattern<Int>().apply { mergeStrings("true" to 1, "false" to 0) }
override val eof = -1
}
这么说来,其实在这无聊的时候试着让 ParserKt 能在简洁性上吊打其他的框架,才是最有意思的事情吧……
This media is not supported in your browser
VIEW IN TELEGRAM
真的已经分不清框架的核心和外设了…… 都写在一个文件里 没有规矩
说实在话,其实 ParserKt 现在的 Pattern 架构处理 leftrec 文法也没问题,我早想过了,只需要弄个 LrDecide 和 leftrec {},靠异常系统就可以工作
http://canopy.jcoglan.com/
grammar Maps
map <- "{" string ":" value "}" %make_map
string <- "'" [^']* "'" %make_string
value <- list / number
list <- "[" value ("," value)* "]" %make_list
number <- [0-9]+ %make_number

lateinit var list: Pattern<Char, List<Any>>
val comma = item(',').tokenize()
val number = Repeat(asInt(), digitFor('0'..'9'))
val string = SurroundBy(quotes.clamly(), stringFor(!item('\'')))
val value = Decide(number, Deferred{list}).mergeFirst { if (it is List<*>) 1 else 0 }.also {
list = SurroundBy(squares.clamly(), JoinBy(comma, it) )
}
val kvPart = Seq(::AnyTuple, string, item(':'), value)
val kv = Convert(kvPart, { it[0] to it[1] }, { anyTupleOf(first, ':', second) })
val map = SurroundBy(braces.clamly(), JoinBy(comma, kv))

直接从输入到 Any 值、直接从 Any 值弄回输入,类型全贴上。
Forwarded from 憨憨的碎碎念 | #春节限定跑路 (wuhang2003)
一本英语书的神预测
/tmp/duangsuse.sock
真的已经分不清框架的核心和外设了…… 都写在一个文件里 没有规矩
现在 ParserKt 也的确是越来越乱了…… 一些基本模型的实现,也被我质疑是 不够简洁 也能被查出 bug 了么……

看来 严格的工程规范 是必须了
可是我没有硬件条件,用不起 Gradle,而且自动化测试困难