Generate "pure" parsers from yacc, and do not require having a yacc to build the shell #223
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
TL;DR, this PR:
%define api.pure fullto parse.y. This makes the generated parsers "pure", which means they don't depend on any shared variables and multiple can run at once.This should be a complete no-op for an es user, and a minor improvement in convenience to an es builder.
Why this change? The ultimate goal is to be able to run es code while the parser is running. Doing so would unlock more or less the entire category of "interactive features" that are either difficult or impossible to have in es today. See #178 for what one version of that might look like, and some discussion.
The major technical hurdle to this "programmable input" was fixed with #205, which made it possible to fetch shell input without disabling the GC. This PR does half the work[*] of resolving the second technical hurdle: parsing while parsing.
The problem is that running es code requires, at unpredictable times, parsing es code. For example, if you overrode
%write-historyin your .esrc, and you want to call%write-historyfor each line of input, then that means that your interactive es shell parses%write-historyfrom the environment on the first line of input entered, which is likely to be in the middle of parsing the line of input itself.POSIX does not specify anything about a yacc parser supporting this, and by default, yaccs don't. However, bison and byacc can both be configured to, by using the non-standard
%define api.pure fulldirective to generate a "pure" parser. So we do that. But that makes ourparse.ynon-standard (and therefore considered non-portable, though I've struggled to even find alternative yaccs in reasonably common use these days). So to work around that, we just package up the generated parsers with the source code and, unless you mess around withparse.y, don't bother re-generating y.tab.c and token.h at all.This means that folks just trying to build es on their machines don't need a yacc installed at all. This makes es even more portable than it has been :) (assuming the outputted C code is nicely standards-compliant, which all evidence thus far suggests it is).
This follows how rc is packaged up these days, so arguably this is also helping make #1 happen. :)
[*] After this, the remaining work is making any globally scoped parsing-related data per-Input.