Skip to content

Experimental Swift package for composable parsing via Local Lexing.

License

Notifications You must be signed in to change notification settings

phlegmaticprogrammer/ParsingKit

Repository files navigation

Copyright (c) 2020 Steven Obua

License: MIT License


ParsingKit is a Swift package for composable parsing. Its foundation is Local Lexing. It is experimental in the sense that its goal is to explore how practical Local Lexing is, and how much it can actually facilitate composable parsing.

Its API is not documented yet, and it hasn't been extensively tested yet. A document describing the principles on which ParsingKit is based is in the making. For now, to get a feel for the framework, you can examine the existing tests. Here is an example grammar taken from them:

import FirstOrderDeepEmbedding
import ParsingKit

class Calculator : TextGrammar {
    
    typealias N = Nonterminal<UNIT, INT>
    
    @Sym var Expr : N
    @Sym var Sum : N
    @Sym var Product : N
    @Sym var Num : N
    @Sym var Digit : N
            
    override func build() {
        add {
            Expr.rule {
                Sum
                                
                Sum.out --> Expr
            }

            Sum.rule {
                Sum[1]
                literal("+")
                Product
                
                Sum[1]~ + Product~ --> Sum
            }

            Sum.rule {
                Product
                                
                Product~ --> Sum
            }

            Product.rule {
                Product[1]
                literal("*")
                Num
                
                Product[1]~ * Num~ --> Product
            }
            
            Product.rule {
                Num

                Num~ --> Product
            }
            
            Num.rule {
                Digit
                
                Digit~ --> Num
            }
            
            
            Num.rule {
                Num[1]
                Digit
                                    
                Num[1]~ * 10 + Digit~ --> Num
            }
            
            Digit.rule {
                Char
                
                %?(Char~ >= "0" && Char~ <= "9")
                                
                Char~.match("0" => 0, "1" => 1, "2" => 2, "3" => 3, "4" => 4, "5" => 5, "6" => 6, "7" => 7, "8" => 8, "9" => 9) --> Digit
            }
        }
    }
    
}

Parsing with this grammar is simple:

let calculator = Calculator()
let parser = calculator.parser()
let result = parser.parse(input: "32+4*7", start: calculator.Expr)
switch result {
case let .failed(position): print("parsing failed at position \(position)")
case let .success(length: length, results: results):
    print("parsing succeeded (\(length) characters consumed): output parameter = \(results.first!.key)")
}

About

Experimental Swift package for composable parsing via Local Lexing.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages