PaversParsec

一个用 Swift 重写的 Haskell Parsec 库的框架。

它的重新实现遵循了 Daan Leijen 和 Erik Meijer 在他们的论文 Parsec: Direct Style Monadic Parser Combinators For The Real World 中的思想

此外,这个框架将 Haskell Parsec 的代码解释为 Swift 代码,并进行了一些更改以适应 Swift 的特性,例如惰性求值和泛型。

依赖

这个框架依赖于 PaversFRPPaversSugar

示例

这是一个来自 Parsec 的示例。

  1. 以下示例使用 Xcode 10 作为构建环境。假设您已安装 xcode 10
sudo xcode-select --switch /Applications/Xcode10-beta.app/Contents/Developer
  1. 使用 Swift 包管理器安装 PaversParsec。
mkdir ParenParser
cd ParenParser
swift package init --type executable
vi Package.swift
  1. 编辑 Package.swift 文件,为我们的 ParenParser 添加依赖项。
// 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"]),
    ]
)
  1. 我们通过编辑 Sources/ParenParser/main.swift 文件来构建一个用于解析括号匹配的解析器,如下所示。
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 )
*/
  1. 构建并执行。
swift build
./.build/x86_64-apple-macosx10.10/debug/ParenParser

Parse OK 结果表示成功:括号匹配。Parse Failed 结果表示解析失败,并附带有详细的错误消息。

用例

这个框架有两个应用。

一个是用于 JSON 的解析。 PaversJSON

另一个是用于 Kaleidoscope 编译器的开发。 SwiftParsecKaleidoscope

待办事项

  1. 为这个库提供更多的用例。

  2. 使 API 文档更具描述性且用户友好。

  3. 使 PaversParsec 达到可用于生产的水平。