News for hackers. Stuff that matters.
Re:Participle: A parser library for Go by weberc2 on Tuesday July 17, 2018 @08:45AM (#17549275)
This looks really cool. I spent a few weeks last year trying to build my first programming language, but I kept getting bogged down by parsing and eventually gave up.
Re:Participle: A parser library for Go by cweagans on Tuesday July 17, 2018 @11:17AM (#17550254)
You should check out Thorsten Ball's interpreterbook.com and compilerbook.com. I went through the former - it's amazing. I'm eagerly awaiting the release of the latter.

It walks through the creation of an entire interpreter from scratch using just core Go packages, including test coverage.

Re:Participle: A parser library for Go by weberc2 on Tuesday July 17, 2018 @06:09PM (#17553917)
I'll do that, thanks for the tip! I heard about the interpreter book from the GoTime podcast, but didn't know about the compiler book. :)
Re:Participle: A parser library for Go by cweagans on Wednesday July 18, 2018 @10:12AM (#17558523)
It was announced relatively recently. If it's even half as good as the interpreter book, it'll be worth the price :)
Re:Participle: A parser library for Go by laumars on Tuesday July 17, 2018 @09:25AM (#17549553)
Parsing isn't actually that hard once you wrap your hard around the problem. There are lots of good guides for writing parsers online which really helped me out when I was feeling the same bourdon as you are.

So what I'm trying to say is stick with it and I'm sure you'll crack it. :)

Re:Participle: A parser library for Go by azhenley on Tuesday July 17, 2018 @09:50AM (#17549703)
Definitely. I used to always get stuck on the parsing part, and it definitely is time consuming to get right, but once you get past it once it is much easier to tackle in the future.

Then you realize that parsing is only a small piece of making your own language!

Re:Participle: A parser library for Go by laumars on Tuesday July 17, 2018 @09:56AM (#17549746)
The Eureka moment for me was learning that a parser isn't a single entity. It's reading tokens, making an abstract syntax tree, etc. One I learned how to break the problems down I found writing parsers very easy.

As for it only being a small part of making your own language, that is so true too. However I do think it's a rewarding project to tackle.

Re:Participle: A parser library for Go by jerf on Tuesday July 17, 2018 @10:09AM (#17549816)
The ability to parse is one of the things that differentiates "power programmers" from people just hooking things together. If you wish to be one of the former, it is on the Must Study list.

It is true that many, perhaps even most programmers can go their entire career without having to face the problem of writing their own code to take a text file and view it as a tree of tokens. This is even more true than ever with so many off-the-shelf serialization options, meaning that creating your own new one had better have a really, really darned good justification to it. But if you conceptualize a parser as "a thing that receives a stream of low level, primitive inputs and needs to extract sensible state information and know when constraints have been violated"... ah, now that sounds pretty useful, right? And very modern as we continue our inevitable marches towards viewing the world in terms of event streams rather than blobs of completed input that we can take in all at once. The generalized parsing problem of taking a stream of primitives and extracting higher level meaning from them is as relevant as ever, if not more relevant.

Re:Participle: A parser library for Go by weberc2 on Tuesday July 17, 2018 @10:36AM (#17549987)
How do you write a parser in a language like Go? I stumbled upon parser combinatory and tried to shoehorn them into Go, but the lack of generics mostly prohibited this. I also tried imperatively writing the parser, but this was tedious and error prone. I also explored parser generators, but these seemed to have huge learning curves and still produced awful code. Beyond that, it’s hard to tell what kind of parser I need because of all of the academic jargon. :/

I would love to be pointed in the right direction!

Re:Participle: A parser library for Go by laumars on Tuesday July 17, 2018 @10:53AM (#17550082)
The lack of generics wasn't an issue for me.

A 30 second overview:

The first thing you need to do is scan your file for tokens (eg "{", "}", "[", "]", ",", "\"", etc in the case of JSON).

Then you traverse your tokens and turn them into an AST (Abstract Syntax Tree) which is essentially just a "struct" version of the code (in the dumbest description imaginable). The point of this is you start adding definitions to your tokens. Eg what does a "[" mean?

From there you can start writing your real business logic since you now have a Go struct version of your code which you can traverse.

However I would really would recommend doing a google for how to write your own compiler. There are dozens of good resources out there (I can't recall the one that I used off hand) and they'll explain this process a thousand times better than I have above.

One last thing to note, the theory of writing a parser is pretty language agnostic so don't get put off that one guide is in C or another in Java or Python or LISP or whatever. As long as you get the theory nailed you can write the Go code equivalent without too much headache.

Re:Participle: A parser library for Go by zzzcpan on Tuesday July 17, 2018 @01:22PM (#17551361)
Parser combinators don't need generics, as they are merely higher-order recursive descent parsers. I.e. recursive parsers where functions are created via other functions to generalize and compose them. Go is expressive enough to do that.

For example, let's say we start with a function that parses a character '['.

  buf, pos := []byte("[123]"), 0
  
  LBRACK := func()bool {
     if buf[pos] != '[' {
        return false
     }
     pos ++  // consume character
     return true
  }
It would suck to write such function for every single character we have to parse. We can generate it instead:

  CHAR := func(c byte)func()bool {
     return func()bool {
        if buf[pos] != c {
           return false
        }
        pos ++
        return true
     }
  }
  
  LBRACK := CHAR('[')
Now let's do the same for parsing a sequence. We combine outputs of other functions and return one that parses them one by one.

  SEQ := func (args... func()bool) func()bool {
     return func()bool {
        for i := 0; i < len(args); i++ {
           f := args[i]
           if f() == false {
              return false
           }
        }
        return true
     }
  }
  
  parser := SEQ(
     CHAR('['),
     SEQ(
        CHAR('1'),
        CHAR('2'),
        CHAR('3'),
     ),
     CHAR(']'),
  )
This is the idea.

This is not a real world example though. You'll need to have more primitives, a wrapper that handles various things, like restoring buffer index on failure, captures, that save starting index, move buf/pos into context structure, virtual stack to store captures/errors, etc.

  func SEQ (args... func(ctx *Ctx)bool) func(ctx *Ctx)bool {
     return wrap (func(ctx *Ctx)bool {
        ...
     })
  }
But it's important to get there on your own. And it's pretty much as fast and as flexible as completely hand-written recursive descent parsers and as powerful as parser generators.
Re:Participle: A parser library for Go by weberc2 on Tuesday July 17, 2018 @04:07PM (#17552826)
Is that a parser? That looks like a matcher. I actually built something that looks almost exactly like this, but it doesn't get you an AST, right? What am I missing?
Re:Participle: A parser library for Go by zzzcpan on Tuesday July 17, 2018 @04:55PM (#17553296)
To get to AST you have to create AST nodes. Make a function that captures the output and put it into places where you want to create AST nodes. Sort of like this:

  SEQ(
     ...
     CAPTURE(
        // parser to capture
        SEQ(...),
        // extra arguments: 
        // a name, a function to call,
        // that creates an AST node, etc.
     ),
  )
Re:Participle: A parser library for Go by laumars on Tuesday July 17, 2018 @04:12PM (#17552861)
Is the code online? What was the output of your routine?
Re:Participle: A parser library for Go by slentprog on Tuesday July 17, 2018 @11:19AM (#17550278)
I can recommend the book writing an interpreter in Go. It requires some basic knowledge of the Go programming language to get started.