Swift Parser Combinator library inspired by NimbleParsec for Elixir.

Related tags

Utility SimpleParsec
Overview

SimpleParsec

Simple parser combinator library for Swift inspired by NimbleParsec for Elixir.

Each function in the library creates a Parser which can be used to create an AST from text.

For example the string(_: String) -> Parser function returns a Parser which matches the exact string passed to the string() function:

import SimpleParsec

let parser: Parser = string("def")

The above example constructs a parser which matches the exact string "def".

Parser is just a typealias for a function which we can call to perform the parsing. The Parser typealias is defined as:

public typealias Parser = (Substring) -> ParserResult

Therefore we need to invoke the parser with a substring (the text to be parsed) and we get a ParserResult.

let result = parser("def functionName")

The above will successfully parse the text as it begins with "def".

Note that the Parser parameter type is actually Substring and not String. This allows for efficient processing throughout the parsers as substrings don't copy the string instead represent index locations within the string. Swift automatically converts the string literal into a Substring however if we have an already defined string we will need to convert it to a substring first:

let text = "def name"
let result = parser(Substring(text))

A parser returns a ParserResult which is an enum with two cases, either .ok or .error.

public enum ParserResult {
    case ok(Substring, AST?)
    case error(Substring, String)
}

Both include the remaining text that still needs to be parsed (the Substring) and .ok also includes the AST constructed up to this point whereas .error includes an error message. We can desconstruct the enum using an if case let:

if case let .ok(remain, astOpt) = result,
    let ast = astOpt {
    print(ast)
}

Note that astOpt is an optional, i.e. it can be nil even if the result is .ok. The AST can be nil for parsers such as ignore and optional where no match is okay or the result is not intended to be added to the AST. Here is a more complex example:

func functionHeader() -> Parser {
    tag(label: "function", concat([
       ignore(string("def")),
       ignore(iws()),
       tag(label: "functionName", alphaString()),
       ignore(string("(")),
       tag(label: "params", optional(params())),
       ignore(string(")"))
    ]))
}

func params() -> Parser {
    choose([
       concat([
         times(min: 1, concat([
            param(),
            ignore(string(",")),
            ignore(optional(iws()))
         ])),
         param()
       ]),
       param()
   ])
}

func param() -> Parser {
    tag(label: "param", alphaString())
}

let parser = functionHeader()

let result = parser("def myFunction(paramOne, paramTwo, paramThree)")

if case let .ok(_, ast) = result {
    print(ast!)
}

Outputs:

tag("function", SimpleParsec.AST.list([
    SimpleParsec.AST.tag("functionName", SimpleParsec.AST.value("myFunction")), 
    SimpleParsec.AST.tag("params", SimpleParsec.AST.list([
        SimpleParsec.AST.tag("param", SimpleParsec.AST.value("paramOne")), 
        SimpleParsec.AST.tag("param", SimpleParsec.AST.value("paramTwo")), 
        SimpleParsec.AST.tag("param", SimpleParsec.AST.value("paramThree"))
    ]))
]))
  • tag() adds a label to a nested parser result which can be used for processing the AST later.
  • ignore() will match its parser but not add the results to the AST.
  • concat() takes an array of parsers and ensures they all occur one after the other.
  • times() expects the parser to occur a multiple number of times, with a specified minimum.
  • iws() is short for in-line whitespace, i.e. whitespace that doesn't include new lines, or simply spaces and tabs. It matches one or more. To match a single character use iwsChar(). See also ws() which also matches new lines, and the single character version wsChar().
You might also like...
Swift's Sugar. Heavily inspired on Objc Sugar

Swift's Sugar. Heavily inspired on Objc Sugar

Cross-Platform, Protocol-Oriented Programming base library to complement the Swift Standard Library. (Pure Swift, Supports Linux)

SwiftFoundation Cross-Platform, Protocol-Oriented Programming base library to complement the Swift Standard Library. Goals Provide a cross-platform in

swift-highlight a pure-Swift data structure library designed for server applications that need to store a lot of styled text

swift-highlight is a pure-Swift data structure library designed for server applications that need to store a lot of styled text. The Highlight module is memory-efficient and uses slab allocations and small-string optimizations to pack large amounts of styled text into a small amount of memory, while still supporting efficient traversal through the Sequence protocol.

macOS system library in Swift

SystemKit A macOS system library in Swift based off of libtop, from Apple's top implementation. For an example usage of this library, see dshb, a macO

Swift library to develop custom Alexa Skills
Swift library to develop custom Alexa Skills

AlexaSkillsKit AlexaSkillsKit is a Swift library that allows you to develop custom skills for Amazon Alexa, the voice service that powers Echo. It tak

🏹 Bow is a cross-platform library for Typed Functional Programming in Swift
🏹 Bow is a cross-platform library for Typed Functional Programming in Swift

Bow is a cross-platform library for Typed Functional Programming in Swift. Documentation All documentation and API reference is published in our websi

Focus is an Optics library for Swift (where Optics includes Lens, Prisms, and Isos)

Focus Focus is an Optics library for Swift (where Optics includes Lens, Prisms, and Isos) that is inspired by Haskell's Lens library. Introduction Foc

A Swift micro library for generating Sunrise and Sunset times.

Solar A Swift helper for generating Sunrise and Sunset times. Solar performs its calculations locally using an algorithm from the United States Naval

Plugin and runtime library for using protobuf with Swift

Swift Protobuf Welcome to Swift Protobuf! Apple's Swift programming language is a perfect complement to Google's Protocol Buffer ("protobuf") serializ

Owner
null
A result builder that build HTML parser and transform HTML elements to strongly-typed result, inspired by RegexBuilder.

HTMLParserBuilder A result builder that build HTML parser and transform HTML elements to strongly-typed result, inspired by RegexBuilder. Note: Captur

null 4 Aug 25, 2022
An SSH config parser library with a fancy API

The SshConfig makes it quick and easy to load, parse, and decode/encode the SSH configs. It also helps to resolve the properties by hostname and use them safely in your apps (thanks for Optional and static types in Swift).

Artem Labazin 8 Nov 25, 2022
A Powerful , Extensible CSS Parser written in pure Swift.

A Powerful , Extensible CSS Parser written in pure Swift.

null 273 Sep 9, 2022
A simple, but efficient CSV Parser, written in Swift.

CSV CSV.swift is a powerful swift library for parsing CSV files that supports reading as [String], [String: String] and Decodable, without sacrificing

Ben Koska 4 Nov 28, 2022
.DS_Store file parser/viewer.

.DS_Store file parser/viewer.

JD Gadina 51 Dec 1, 2022
ParserCombinators - String Parser Construction Kit

ParserCombinators provides a set of elementary building blocks for deriving stru

Marcel Tesch 0 Jan 7, 2022
HxSTLParser is a basic STL parser capable of loading STL files into an SCNNode

HxSTLParser HxSTLParser is a basic STL parser capable of loading STL files into an SCNNode. Installing Via Carthage Just add it to your Cartfile githu

Victor 23 Dec 16, 2022
iOS Logs, Events, And Plist Parser

iLEAPP iOS Logs, Events, And Plists Parser Details in blog post here: https://abrignoni.blogspot.com/2019/12/ileapp-ios-logs-events-and-properties.htm

Brigs 421 Jan 5, 2023
A μframework of extensions for SequenceType in Swift 2.0, inspired by Python's itertools, Haskell's standard library, and other things.

SwiftSequence Full reference here. (If you're looking for data structures in Swift, those have been moved to here) SwiftSequence is a lightweight fram

Donnacha Oisín Kidney 376 Oct 12, 2022
Swiftbot on slack. Inspired by kishikawakatsumi/swift-compiler-discord-bot

Swiftbot Swiftbot on slack. Inspired by kishikawakatsumi/swift-compiler-discord-bot Usage $ swiftbot --token xoxb-xxxxxxxxxxxx-xxxxxxxxxxxx-xxxxxxxxxx

noppefoxwolf 55 Jan 8, 2022