GithubHelp home page GithubHelp logo

Comments (6)

mbrandonw avatar mbrandonw commented on August 22, 2024 3

Whoa, also I just realized that computed properties can be recursive, and so you don't even listParser to be a function:

let eol = Parser<Void> { str in str == "" ? () : nil }

var listParser: Parser<List> {
  oneOf([
    eol.map { .empty },
    zip(int, oneOf([literal(","), eol]))
      .flatMap { head, _ in
        listParser
          .map { tail in .cons(head, tail) }
    }
  ])
}

Only strange thing is that Swift has this warning even though the recursion is safe :/

image

from episode-code-samples.

mbrandonw avatar mbrandonw commented on August 22, 2024

Hey @tapcast-kevin, good question!

We really hope to get back to parsers soon, there's still so much left to talk about, including this recursion problem. I'll sketch out a simplified example of how to do recursive parsing and maybe you can extrapolate it to your use case.

Say you had this recursive enum:

indirect enum List {
  case empty
  case cons(Int, List)
}

And you wanted to parse strings like "1,2,3,4" into it. You can actually construct a parser that calls itself, you just have to express the parser as a function and make sure to call itself lazily:

let eol = Parser<Void> { str in str == "" ? () : nil }

func listParser() -> Parser<List> {
  oneOf([
    // If there is nothing left to parse then we can end with the `.empty` List
    eol.map { .empty },

    // If there's stuff left to parse then we can parse off a single int and 
    // an (optional) delimiter, and then `flatMap` onto that so that we 
    // can lazily run the parser again
    zip(int, oneOf([literal(","), eol]))
      .flatMap { head, _ in
        listParser().map { tail in .cons(head, tail) }
    }
  ])
}

And then to use it:

let p = listParser()
print(p.run("1,2,3").match!)

Hope that helps!

(NB: these code samples are based off where we left off in episode 64)

from episode-code-samples.

 avatar commented on August 22, 2024

Thanks @mbrandonw! I'm getting closer, but I need to study this a bit more to fully grok it. Thanks for the pointer

from episode-code-samples.

 avatar commented on August 22, 2024

I ended up writing a similar "parsing" system for reading binary data from a mutable instance of Data (NSData). There wasn't any recursion to deal with, so that kept things simple. That exercise greatly increased my understanding of zip, map, flatMap, and even contraMap (pullbacks that I used for going in the other direction; writing binary). After that exercise, I came back to this problem and your solution now makes sense to me AND it works too! ;) I have a simple JSON parser in not much code, which is amazing to me. I have wanted to dive into this (combinator) style of parsing for a while, but it has been so foreign to my OOP/imperative/LALR mindset. Thanks again for the help and all of the videos!

from episode-code-samples.

mbrandonw avatar mbrandonw commented on August 22, 2024

@tapcast-kevin this is really awesome to hear, I'm glad stuff is clicking!

(pullbacks that I used for going in the other direction; writing binary)

Interesting! When we get back into parsing episodes (hopefully a few months from now) we will be discussing the idea of "invertible parsing", which is the ability to simultaneously parse and print. Sounds like you are experimenting with something similar, which is cool!

from episode-code-samples.

 avatar commented on August 22, 2024

I'm not there yet, but I'm working my way in that direction. That is indeed a fascinating topic.

from episode-code-samples.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.