Live data from Hacker News

Glush: A robust parser compiler built using non-deterministic automatons

sanity.io

11–20 of 34 posts

Re: Glush: A robust parser compiler built using non-deterministic automatons

#11

Intrigued .. keep posting. I tried a bison/flex parser and was stuck in shift/reduce hell.

In my experience, shift/reduce conflicts typically reflect real ambiguities, at least in your initial draft of a grammar. Reporting them at that stage is a good thing; you should be addressing them instead of glossing over them.

There are legitimate reasons to need more power than LALR(1) provides, but careless thinking is more common.

Re: Glush: A robust parser compiler built using non-deterministic automatons

#12
Sounds promising! And a great exposition of the background and development.

About the Glushkov construction for regular expressions, here's some Python code that may perhaps help to explain it, since the Wikipedia page is hard to follow (at least for me) and the Mastodon thread linked in the post admitted to some confusion about the "Play on Regular Expressions" paper (which I haven't read): https://github.com/darius/sketchbook/blob/master/regex/nfa_p...

Sorry it's not pedagogically great either; I was rederiving the method for myself rather than implementing from textbooks. What I called 'follows' in the comment should correspond to 'pair set' in the post; the other fields have the same names.

Incidentally I think the post a bit overstates the problems with PEGs (you shouldn't need left recursion anywhere a hand-written recursive-descent parser would also work; PEGs were meant to streamline and formalize recursive descent, and this failure to model the practice can be fixed without big changes) -- but CFGs are great too and I'm looking forward to studying Glush. I wish I'd thought of exploring the generalization to context-free grammars.

Re: Glush: A robust parser compiler built using non-deterministic automatons

#13
Skipping to "Glush, the algorithm" can be helpful if you already know the history of parsing.

TL;DR: Glush grammars consist of "rules" that are regexes + recursion of rule calls. Compiles to NFAs.

I'm not sure I see the point in declaring precedence levels inside rules -- maybe it's just a preference thing, but I like having operator precedences in a separate section of the grammar. Yacc does this. Megaparsec for Haskell does this.

This reminds me of two things:

1. How syntax highlighting is implemented in Vim and GEdit (which is to say GtkSourceView). See for example how "contexts" can be nested here: https://github.com/rubencaro/gedit_hacks/blob/master/.local/...

2. Kleenex: https://kleenexlang.org - https://github.com/diku-kmc/kleenexlang - a silly example: https://github.com/athas/EggsML/blob/master/concieggs/compil...

I am tempted to classify this as "regex extended with recursion" rather than "an alternative to CFGs", since I cannot decipher from the article the exact expressive power.

Re: Glush: A robust parser compiler built using non-deterministic automatons

#14
post #5

Earlier quoted context omitted.

Have you considered jq? https://stedolan.github.io/jq/ https://github.com/stedolan/jq

Worth noting jq is not quite like what GP has tried, in that it seems to be designed as a command-line utility first with only incidental concessions to allow itself to be linked as a library. Its C API is poorly documented and essentially defined by the single implementation. The language itself is immensely powerful and not really sandboxable. It's a nice language to work in but definitely not one I'd want to expos…

I'm actually working on a separate implementation with the intent of making jq work as a library.

By "not really sandboxable", what powerful features of jq do you mean?

I'm not sure what's meant by "expose as a user interface". It's a pretty abstract DSL, so I would certainly only expose it to programmers.

Re: Glush: A robust parser compiler built using non-deterministic automatons

#16

I would have really preferred a table of contents, either at the top or in a sidebar. It would have made it easier to skip over all the background materials that essentially rehashes an undergrad complier course.

There is one, which appears as a sidebar once you're below the fold. Bizarre placement imo, but it's there.

Huh, you're right. I guess I shouldn't be reading this on mobile.

Re: Glush: A robust parser compiler built using non-deterministic automatons

#17
post #14

Earlier quoted context omitted.

Worth noting jq is not quite like what GP has tried, in that it seems to be designed as a command-line utility first with only incidental concessions to allow itself to be linked as a library. Its C API is poorly documented and essentially defined by the single implementation. The language itself is immensely powerful and not really sandboxable. It's a nice language to work in but definitely not one I'd want to expos…

I'm actually working on a separate implementation with the intent of making jq work as a library. By "not really sandboxable", what powerful features of jq do you mean? I'm not sure what's meant by "expose as a user interface". It's a pretty abstract DSL, so I would certainly only expose it to programmers.

> By "not really sandboxable", what powerful features of jq do you mean?

On close inspection I can't find things as bad as I imagined, but there are still some unexpected barely-documented features like reading files from anywhere on disk[1] as long as they have the right extension, with much wider implications than one might expect at a glance. (Note the while the module path is relative and checked for path traversal, you can just set the search path. Undocumented is that the text needn't even parse as JSON because you can just set the raw flag.) In general, many language features are implemented by exposing a more powerful primitive than necessary to the language and documenting a less powerful wrapper but not the primitive itself; the security implications go more or less unexamined.

There seems to be no particular provision for executing any less than enough to generate the next output, so if you want to set limits on execution you'll have to do that at the process level. This is something you can probably do better in a separate implementation, though.

> I'm not sure what's meant by "expose as a user interface". It's a pretty abstract DSL, so I would certainly only expose it to programmers.

Only trusted users should have access to jq. I would assume that anyone who has access to executing jq code can execute arbitrary code in the interpreter's context. I'm less sure that it's true right now than I was when I made the post above, but it still seems pretty likely.

[1]: https://stedolan.github.io/jq/manual/#importRelativePathStri...;

Re: Glush: A robust parser compiler built using non-deterministic automatons

#18
> However, in practice it turns out that LALR(1) isn’t always the answer. For instance, both GCC, Rust and Go have chosen to use handwritten parsers that are not based on a declarative grammar file. I find this disappointing: We have decades of experience with specifying languages in a declarative format, and apparently it’s still easier to manually write parsers. Obviously there’s something lacking with the algorithms we have today.

Many production compilers have hand-written parsers because of error reporting, not because of issues with parser-generator algorithms.

Consider the example of missing parenthesis. I can specify a grammar with the following:

  EXPR =
       ...
       | '(' EXPR ')'
The generated parser will not gracefully report a mismatched number of parentheses! Instead, it will report that the user's input is not formatted as expected, which makes it hard for the user to understand what went wrong.

It is possible to modify the grammar to look for this case specifically:

  EXPR =
       ...
       | '(' EXPR ')'
       | '(' EXPR      // report this explicitly
But now I've just polluted my once-pristine grammar file. And adding all of the necessary error checks throughout the grammar will really make things complicated.

So, many production compilers end-up with custom parsers to report unexpected input in a sane way. It is not that the algorithms are lacking; there is simply no mechanism for a generator to know what a mismatched parenthesis should be reported as.

Re: Glush: A robust parser compiler built using non-deterministic automatons

#19

> However, in practice it turns out that LALR(1) isn’t always the answer. For instance, both GCC, Rust and Go have chosen to use handwritten parsers that are not based on a declarative grammar file. I find this disappointing: We have decades of experience with specifying languages in a declarative format, and apparently it’s still easier to manually write parsers. Obviously there’s something lacking with the algorith…

Error recovery and reporting are for sure the biggest challenge of a production parser. If you work out of band, you can play a lot of tricks in your parser to make it much more effective in handling errors. For example, braces can be matched in many languages without parsing any other constructs in the language, meaning these errors can all be reported and recovered from independent of the rest of the language. Then again, the overloading of as operators and braces in many languages defeats that a bit :)

Hand coding a parser is usually worth it for a moderately popular production language. Parser generators really shine for smaller language efforts that can’t afford the overhead and don’t really care about the niceties of decent error reporting.

Re: Glush: A robust parser compiler built using non-deterministic automatons

#20
post #2

Thanks for sharing. Currently I'm looking for an elegant language for querying Json structures. In addition to JsonPath, JMESPath, Glush & GROQ is definitely worth a try

I can recommend jtc as something nice to use for extracting stuff from deep json structures. It should be quite feasible to integrate as a library if one so desires.

https://github.com/ldn-softdev/jtc/blob/master/User%20Guide....

Post reply on HN