Fixes#102. While on macOS the `libcompiler.a` and `libruntime.a`
files apparently get output directly into `out/Release/` by the build,
on Linux they seem to go into a subdirectory `out/Release/obj.target/`.
This causes someone who tries to follow the instructions to get an
error like
```
/usr/bin/ld: cannot find -lcompiler
clang: error: linker command failed with exit code 1 (use -v to see invocation)
```
That looks like the setup is broken somehow, and for someone who
hasn't spent much time fixing up Unix linker errors, it doesn't give a
lot of clues as to how to fix it.
Instead, have the recommended command find the actual library file
directly, and pass that to the linker. (Alternatively we could have
passed the containing directory to `-L`; this is a little shorter, and
of course neither version is what you'd want in an industrial-strength
build recipe.)
This isn't the world's most elegant solution, obviously -- it'd be
better (at least as far as this part is concerned) to have the layout
be the same on different platforms. But doing that sounds likely to
require significant messing around with build scripts, so this at
least makes the instructions work reliably.
Some linkers (among them, the GNU ld 2.28 on my laptop, which clang
relies on for linking) are picky about the order they get their
ingredients in on the command line. When they are, they want the
leaf nodes (like your `main` function) first, and the dependencies
(like `libcompiler.a`) after.
It's kind of counterintuitive (at least to me) that this is the
preferred order, though I can understand it from the perspective
of efficient resource use in the era when some linkers were first
written. Anyway, it's the way it is. There's a detailed
explanation here:
https://stackoverflow.com/a/409470/378130
So, adjust the examples in the README to an order that should
work everywhere.
This fixes part of #102.
The links to http://harmonia.cs.berkeley.edu got to a "forbidden, you' dont have permission to access..." error page. I have updated "Efficient and Flexible Incremental Parsing" to point to the ftp location on berkeley.edu. The only hosted reference to "Incremental Analysis of Real Programming Languages" is at ACM Digital Library, I pointed the link here.
* Deal with mergeability outside of error comparison function
* Make `better_version_exists` function pure (don't halt other versions
as a side effect).
* Tweak error comparison logic
Signed-off-by: Rick Winfrey <rewinfrey@github.com>
The previous approach to error recovery relied on special error-recovery
states in the parse table. For each token T, there was an error recovery
state in which the parser looked for *any* token that could follow T.
Unfortunately, sometimes the set of tokens that could follow T contained
conflicts. For example, in JS, the token '}' can be followed by the
open-ended 'template_chars' token, but also by ordinary tokens like
'identifier'. So with the old algorithm, when recovering from an
unexpected '}' token, the lexer had no way to distinguish identifiers
from template_chars.
This commit drops the error recovery states. Instead, when we encounter
an unexpected token T, we recover from the error by finding a previous
state S in the stack in which T would be valid, popping all of the nodes
after S, and wrapping them in an error.
This way, the lexer is always invoked in a normal parse state, in which
it is looking for a non-conflicting set of tokens. Eliminating the error
recovery states also shrinks the lex state machine significantly.
Signed-off-by: Rick Winfrey <rewinfrey@github.com>