一个用 Swift 重写的 Haskell Parsec 库的框架。
它的重新实现遵循了 Daan Leijen 和 Erik Meijer 在他们的论文 Parsec: Direct Style Monadic Parser Combinators For The Real World 中的思想
此外,这个框架将 Haskell Parsec 的代码解释为 Swift 代码,并进行了一些更改以适应 Swift 的特性,例如惰性求值和泛型。
这个框架依赖于 PaversFRP 和 PaversSugar。
这是一个来自 Parsec 的示例。
sudo xcode-select --switch /Applications/Xcode10-beta.app/Contents/Developer
mkdir ParenParser
cd ParenParser
swift package init --type executable
vi Package.swift
// swift-tools-version:4.2
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "ParenParser",
dependencies: [
// Dependencies declare other packages that this package depends on.
.package(url: "https://github.com/KeithPiTsui/PaversFRP.git", from: "1.0.0"),
.package(url: "https://github.com/KeithPiTsui/PaversParsec.git", from: "1.0.1"),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages which this package depends on.
.target(
name: "ParenParser",
dependencies: ["PaversFRP", "PaversParsec"]),
]
)
vi Sources/ParenParser/main.swift
import PaversParsec
import PaversFRP
func parenSet () -> ParserS<()> {
let left: ParserS<()> = char("(").fmap(terminal) <?> "("
let right: ParserS<()> = char(")").fmap(terminal) <?> ")"
let mParen: LazyParserS<()> = fmap( many(parenSet), terminal)
return left >>- mParen >>- right
}
let parens: LazyParserS<()> = (many(parenSet) >>- eof()) <|> eof()
let parser = parens()
let input1 = ParserStateS("()(())")
let result1 = parser.unParser(input1)
print(result1)
/**
ParserResult: Consumed
Parse OK
Got: ():()
*/
print("------------------")
let input = ParserStateS("(")
let result = parser.unParser(input)
print(result)
/**
ParserResult: Consumed
Parse Failed
Message:
{file: init, line: 1, column: 2}:
msgUnexpected msgEndOfInput
msgExpecting )
*/
swift build
./.build/x86_64-apple-macosx10.10/debug/ParenParser
Parse OK
结果表示成功:括号匹配。Parse Failed
结果表示解析失败,并附带有详细的错误消息。
这个框架有两个应用。
一个是用于 JSON 的解析。 PaversJSON
另一个是用于 Kaleidoscope 编译器的开发。 SwiftParsecKaleidoscope
为这个库提供更多的用例。
使 API 文档更具描述性且用户友好。
使 PaversParsec 达到可用于生产的水平。