Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/turbolent/parsercombinators
A parser-combinator library for Swift
https://github.com/turbolent/parsercombinators
parser parser-combinators parsing swift
Last synced: 27 days ago
JSON representation
A parser-combinator library for Swift
- Host: GitHub
- URL: https://github.com/turbolent/parsercombinators
- Owner: turbolent
- License: mit
- Created: 2017-07-03T22:52:33.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2019-05-12T20:42:11.000Z (over 5 years ago)
- Last Synced: 2024-10-03T10:28:33.842Z (about 1 month ago)
- Topics: parser, parser-combinators, parsing, swift
- Language: Swift
- Homepage:
- Size: 150 KB
- Stars: 3
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
[![Build Status](https://travis-ci.org/turbolent/ParserCombinators.svg?branch=master)](https://travis-ci.org/turbolent/ParserCombinators)
# ParserCombinators
A *parser-combinator* library for Swift.
Parsers are simply functions that accept any kind of input, such as strings or custom data structures, and return an output.
Parser combinators are higher-order functions which allow the composition of parsers to create more expressive parsers.
## Examples
For example, a simple calculator with the grammar in BNF can be implemented as follows:
```
::= |
::= |
::= '(' ')' |
::= '0' | '1' | ...
::= |
::= '+' | '-'
::= '*' | '/'
``````swift
import ParserCombinators
import ParserCombinatorOperatorstypealias Op = (Int, Int) -> Int
typealias OpParser = Parserlet addOp: OpParser =
char("+") ^^^ (+) ||
char("-") ^^^ (-)let mulOp: OpParser =
char("*") ^^^ (*) ||
char("/") ^^^ (/)let digit = `in`(.decimalDigits, kind: "digit")
let num = digit.rep(min: 1) ^^ { Int(String($0))! }let expr: Parser =
Parser.recursive { expr in
let factor = (char("(") ~> expr) <~ char(")")
|| numlet term = factor.chainLeft(
separator: mulOp,
min: 1
).map { $0 ?? 0 }return term.chainLeft(
separator: addOp,
min: 1
).map { $0 ?? 0 }
}let r = CollectionReader(collection: "(23+42)*3")
guard case .success(let value, _) = expr.parse(r) else {
fatalError()
}assert(value == 195)
```