A compiled (C) parser for the MoonScript language.
This repo uses pgen to compile
moonscript_parser/grammar.lua into a native C Lua module that can parse
MoonScript code. This is the experimental new parser that is fully compatible
and will replace the LPeg version in in the
MoonScript repository.
luarocks install moonscript-parserBuilding requires a C compiler and the Lua headers; the module has no other dependencies (no lpeg).
Recent versions of the moonscript rock can use this module in place of the
LPeg parser. It is opt-in: set MOONSCRIPT_PARSER=pgen in the
environment:
MOONSCRIPT_PARSER=pgen moonc ...If the variable is set but this module isn't installed, parsing fails with a require error rather than silently using the LPeg parser.
local parse = require "moonscript_parser"
local tree, err = parse.string(moonscript_code)
if not tree then
print(err) -- line/column message with a source excerpt
endBenchmarked against the LPeg parser from moonscript 0.6.0 by parsing every
.moon file from the lapis,
lapis-community, and
moonscript repositories: 405 files,
1.43 MiB, 58,296 lines. Times are the best of 5 passes over the full corpus,
parse time only (source pre-loaded into memory, no compilation).
| Interpreter | LPeg parser | This parser | Speedup |
|---|---|---|---|
| Lua 5.1.5 | 0.947s | 0.180s | 5.3x |
| LuaJIT 2.1 | 0.817s | 0.141s | 5.8x |
Measured on an AMD Ryzen 8840U with LPeg 1.1.0.
moonscript_parser.slow is the same grammar generated as a pure Lua output
module by pgen for environments where the C module can't be built. It's
substantially slower but requires no C modules.
The rock vendors the generated C module (moonscript_parser.c). To rebuild the
parser, you will need pgen installed.
(luarocks install pgen)
# regenerate moonscript_parser.c (and the vendored errors.lua) from the grammar
make generate
# run the test suite
make testThe test suite compares the parsed AST to a set of pre-built expected outputs.
make test runs it twice: against the native module, then with TEST_SLOW=1
to cover the pure Lua parser. If you are changing the AST then you will need
to regenerate the outputs
make build_test_outputsThe initial outputs were generated while the parser had full differential parity with the reference LPeg parser, so they encode its exact tree shapes.