swift-parser-generator

这段代码尝试在 Swift 中实现类似 Scala 解析器组合子的功能。 在某种程度上它是成功的,因为它可以用来创建简单的解析器。 中间解析结果被缓存用于复杂的规则,因此复杂表达式的解析仍然应该是线性时间的(参见 Packrat)。

工作原理

通过运算符重载,创建了一个嵌套的函数集,构成了解析器。 这些函数接受一个解析器实例和一个读取器对象,该读取器对象为函数提供要解析的字符。

目前支持以下解析操作

// "a" followed by "b"
let rule = "a" ~ "b"

// "a" followed by "b", with possible whitespace in between
// to change what is considered whitespace, change the parser.whitespace rule
let rule = "a" ~~ "b"

// at least one "a", but possibly more
let rule = "a"++

// "a" or "b"
let rule = "a" | "b"

// "a" followed by something other than "b"
let rule = "a" ~ !"b"

// "a" followed by one or more "b"
let rule = "a" ~ "b"+

// "a" followed by zero or more "b"
let rule = "a" ~ "b"*

// "a" followed by a numeric digit
let rule = "a" ~ ("0"-"9")

// "a" followed by the rule named "blah"
let rule = "a" ~ ^"blah"

// "a" optionally followed by "b"
let rule = "a" ~ "b"/~

// "a" followed by the end of input
let rule = "a"*!*

// a single "," 
let rule = %","

// regular expression: consecutive word or space characters
let rule = %!"[\\w\\s]+"

要让解析器在规则匹配时调用您的代码,请使用 => 运算符。 例如

import SwiftParser
class Adder : Parser {
var stack: Int[] = []

func push(_ text: String) {
    stack.append(text.toInt()!)
}

func add() {
    let left = stack.removeLast()
    let right = stack.removeLast()

    stack.append(left + right)
}

	override init() {
		super.init()

		self.grammar = Grammar { [unowned self] g in
			g["number"] = ("0"-"9")+ => { [unowned self] parser in self.push(parser.text) }
			return (^"number" ~ "+" ~ ^"number") => add
		}
	}
}

此示例展示了如何使用解析器的几个细节。 解析器在名为 grammar 的对象中定义,该对象定义了命名的规则以及开始规则,以告诉解析器从哪里开始。

以下代码片段取自其中一个单元测试。 它展示了如何实现包含相互递归规则的解析器

self.grammar = Grammar { [unowned self] g in
	g["number"] = ("0"-"9")+ => { [unowned self] parser in self.push(parser.text) }

	g["primary"] = ^"secondary" ~ (("+" ~ ^"secondary" => add) | ("-" ~ ^"secondary" => sub))*
	g["secondary"] = ^"tertiary" ~ (("*" ~ ^"tertiary" => mul) | ("/" ~ ^"tertiary" => div))*
	g["tertiary"] = ("(" ~ ^"primary" ~ ")") | ^"number"

	return (^"primary")*!*
}

安装

Swift Package Manager (SPM)

您可以使用 Swift Package Manager 安装该驱动程序,方法是将以下行作为依赖项添加到您的 Package.swift

.Package(url: "https://github.com/dparnell/swift-parser-generator.git", majorVersion: 1)

要在 Xcode 项目中使用该驱动程序,请使用 SPM 生成一个 Xcode 项目文件

swift package generate-xcodeproj

手动

将 SwiftParser.xcodeproj 拖到您自己的项目中,然后将 SwiftParser 添加为依赖项(构建目标)并链接到它。 然后您应该能够简单地从 Swift 代码中 'import SwiftParser'。