SwiftParse 是一个解析器组合子库。这个项目仍在快速迭代中,尚未稳定。
让我们为 brainfuck 语言构建一个解析器。 这是一种糟糕的语言,但可以作为如何使用 SwiftParse 的一个很好的例子。
import SwiftParse
enum Instruction {
case incPointer, decPointer, incByte, decByte, writeByte, readByte
case loop([Instruction])
}
typealias LoopParser = StandardParser<String, Instruction>
struct BrainfuckParser {
static let incPointer = match(">") ^^ { _ in Instruction.incPointer }
static let decPointer = match("<") ^^ { _ in Instruction.decPointer }
static let incByte = match("+") ^^ { _ in Instruction.incByte }
static let decByte = match("-") ^^ { _ in Instruction.decByte }
static let writeByte = match(".") ^^ { _ in Instruction.writeByte }
static let readByte = match(",") ^^ { _ in Instruction.readByte }
static let pointerOps = incPointer | decPointer
static let byteOps = incByte | decByte
static let ioOps = writeByte | readByte
static let operation = pointerOps | byteOps | ioOps | loop()
// loop must defined as a static function because it references
// operation which in turn references loop.
static let loop: () -> LoopParser = {
loopStart ~ operation* ~ loopEnd ^^ { Instruction.loop($0.0.1) }
}
static let loopStart = match("[")
static let loopEnd = match("]")
static let program = operation+
}
现在让我们执行它,看看它解析了什么
let result = BrainfuckParser.program(AnyCollection("+[>,]"))
let parseTree = try! result.get().value
这将生成一个解析树,如下所示:
[
SwiftParse.Brainfuck.incByte,
SwiftParse.Brainfuck.loop([
SwiftParse.Brainfuck.incPointer,
SwiftParse.Brainfuck.readByte
])
]
并且没有剩余的未解析字符。 真棒!
有关更完整的示例,请查看 https://github.com/mgadda/swift-parse-examples