Forwarded from Deleted Account
虽然我一直有在优化项目的接口易用性,但感觉还是有些“小乌云”……
顺序、直到、重复、选择 (SURD) 这些大结构没有变
单项、含于、符合 (IES) 的最后一个字母我给它加上了 StickyEnd,也算是解决了 Feed 模型的一个不被重视的问题
模式、正模式、可选模式、修饰模式 (PPOP) 我最后削掉了那个 PositivePattern
现在又变成了
顺序、直到、重复、选择 (SURD) 这些大结构没有变
单项、含于、符合 (IES) 的最后一个字母我给它加上了 StickyEnd,也算是解决了 Feed 模型的一个不被重视的问题
模式、正模式、可选模式、修饰模式 (PPOP) 我最后削掉了那个 PositivePattern
现在又变成了
POPCorn (都是助记的) 算是把 ConstantPattern 给合并到了基本模型里,方便 skip whitespaces 的 Pattern 的 rebuild。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, > 草写不出来了
sap.github.io
Tutorial - Lexer | Chevrotain
Parser Building Toolkit for JavaScript
/tmp/duangsuse.sock
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, le…
其实我们 ParserKt 是不兴包含 lexer 的架构的
ParserKt 实在是太 general-purpose 了,以至于都不好专门为 [a-z]\w 那种情况添加函数
ParserKt 实在是太 general-purpose 了,以至于都不好专门为 [a-z]\w 那种情况添加函数
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))Strumenta
Parsing in JavaScript: all the tools and libraries you can use
We present and compare all possible alternatives you can use to parse languages in JavaScript. From libraries to parser generators, we present all options
/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
其实也可以用 iterator input,但着实是没好的 Pattern 去支持即时更新的 iterator
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 现在的 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>>直接从输入到 Any 值、直接从 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))
/tmp/duangsuse.sock
真的已经分不清框架的核心和外设了…… 都写在一个文件里 没有规矩
现在 ParserKt 也的确是越来越乱了…… 一些基本模型的实现,也被我质疑是 不够简洁 也能被查出 bug 了么……
看来 严格的工程规范 是必须了
可是我没有硬件条件,用不起 Gradle,而且自动化测试困难
看来 严格的工程规范 是必须了
可是我没有硬件条件,用不起 Gradle,而且自动化测试困难