Grammar

public protocol Grammar

A language stores a set of grammar rules that can be used to parse Strings. Extensions provide additional methods (such as parsing) that operate on these rules.

  • The rules in the Language‘s grammar

    Declaration

    Swift

    var rules: [Rule] { get }
  • tokenize(_:) Extension method

    Creates an iterable stream of tokens using the supplied source and this Grammar

    It is very easy to create and iterate through a stream, for example:

    let source = "12+3+10"
    
    for token in try calculationGrammar.stream(source){
       // Do something cool...
    }
    

    Streams are the easiest way to use a Grammar, and consume less memory and are in general faster (they certainly will never be slower). However you cannot easily navigate and reason about the stream, and only top level rules and tokens will be created.

    Declaration

    Swift

    public func tokenize(_ source: String) -> TokenStream

    Parameters

    source

    The source to parse

    Return Value

    An iterable stream of tokens *

  • parse(_:) Extension method

    Creates a HomogenousTree using the supplied grammar.

    A HomogenousTree captures the result of parsing hierarchically making it easy to manipulate the resultant data-structure. It is also possible to get more information about any parsing errors. For example:

    let source = "12+3+10"
    
    do {
       // Build the HomogenousTree
       let ast = try calculationGrammar.parse(source)
    
       // Prints the parsing tree
       print(ast)
    } catch let error as ProcessingError {
       print(error.debugDescription)
    }
    

    Declaration

    Swift

    public func parse(_ source: String) throws -> HomogenousTree

    Parameters

    source

    The source to parse with the Grammar

    Return Value

    A HomogenousTree *

  • build(_:as:) Extension method

    Builds the supplied source into a Heterogeneous representation (any Swift Decodable type).

    This is the most powerful application of a Grammar and leverages Swift’s Decoable protocol. It is strongly recommended that you read a little about that first.

    Essentially each token in the grammar will be mapped to a CodingKey. You should first parse into a HomogenousTree to make sure your types and the hierarchy generated from your grammar align.

    If you want to automatically generate the Decodable types you can do this using STLR and stlrc which will automatically synthesize your grammar and data-structures in Swift.

    Declaration

    Swift

    public func build<T>(_ source: String, as type: T.Type) throws -> T where T : Decodable

    Parameters

    source

    The source to compile

    type

    The Decodable type that should be created

    Return Value

    The populated type *