From 1565dd69e81bf0871978e30e17ecb928a9177596 Mon Sep 17 00:00:00 2001 From: hikerpig Date: Mon, 2 May 2022 14:40:53 +0800 Subject: [PATCH] feat: add `--include-paths` support in nearleyc --- bin/nearley-test.js | 1 - bin/nearleyc.js | 1 + lib/compile.js | 24 +++++++++++++++---- .../grammars/include-paths/include-example.ne | 1 + test/nearleyc.test.js | 8 ++++++- 5 files changed, 28 insertions(+), 7 deletions(-) create mode 100644 test/grammars/include-paths/include-example.ne diff --git a/bin/nearley-test.js b/bin/nearley-test.js index c91696ee..732a2bf5 100755 --- a/bin/nearley-test.js +++ b/bin/nearley-test.js @@ -61,4 +61,3 @@ if (typeof(opts.input) === "undefined") { if (!opts.quiet) writeTable(output, parser); writeResults(output, parser); } - diff --git a/bin/nearleyc.js b/bin/nearleyc.js index 11aa8cf2..bf1ad3a4 100755 --- a/bin/nearleyc.js +++ b/bin/nearleyc.js @@ -12,6 +12,7 @@ opts.version(version, '-v, --version') .arguments('') .option('-o, --out [filename.js]', 'File to output to (defaults to stdout)', false) .option('-e, --export [name]', 'Variable to set parser to', 'grammar') + .option('--include-paths [includePaths]', 'Paths to lookup include files') .option('-q, --quiet', 'Suppress linter') .option('--nojs', 'Do not compile postprocessors') .parse(process.argv); diff --git a/lib/compile.js b/lib/compile.js index c0ae8a16..53335b85 100644 --- a/lib/compile.js +++ b/lib/compile.js @@ -12,6 +12,17 @@ opts.alreadycompiled = []; } + var nodePath = require('path'); + var nodeFs = require('fs'); + var includePaths = []; + if (opts.includePaths && opts.includePaths.split) { + includePaths = opts.includePaths.split(',').map(function(p) { + return nodePath.resolve(process.cwd(), p); + }); + } + var firstIncludePath = (opts.args && opts.args[0]) ? nodePath.dirname(opts.args[0]) : process.cwd(); + includePaths.push(firstIncludePath); + var result = { rules: [], body: [], // @directives list @@ -33,12 +44,15 @@ // Include file var path; if (!productionRule.builtin) { - path = require('path').resolve( - opts.args[0] ? require('path').dirname(opts.args[0]) : process.cwd(), - productionRule.include - ); + for (let i = 0; i < includePaths.length; i++) { + var pathToLookup = nodePath.resolve(includePaths[i], productionRule.include); + if (nodeFs.existsSync(pathToLookup)) { + path = pathToLookup; + break; + } + } } else { - path = require('path').resolve( + path = nodePath.resolve( __dirname, '../builtin/', productionRule.include diff --git a/test/grammars/include-paths/include-example.ne b/test/grammars/include-paths/include-example.ne new file mode 100644 index 00000000..7613f274 --- /dev/null +++ b/test/grammars/include-paths/include-example.ne @@ -0,0 +1 @@ +@include "multi-include/a.ne" \ No newline at end of file diff --git a/test/nearleyc.test.js b/test/nearleyc.test.js index 2c304380..c582240a 100644 --- a/test/nearleyc.test.js +++ b/test/nearleyc.test.js @@ -1,6 +1,7 @@ const fs = require('fs'); const expect = require('expect'); +const path = require('path'); const nearley = require('../lib/nearley'); const {compile, evalGrammar, parse, nearleyc} = require('./_shared'); @@ -110,7 +111,11 @@ describe("bin/nearleyc", function() { expect(stderr).toBe(""); }); - + it("accepets --include-paths", function () { + const includePath = path.join(__dirname, 'grammars'); + const {stdout, stderr} = externalNearleyc("grammars/include-paths/include-example.ne", '.js', ['--include-paths', includePath]); + expect(stderr).toBe(""); + }); }) describe('nearleyc: example grammars', function() { @@ -219,6 +224,7 @@ describe('nearleyc: builtins', () => { const g = evalGrammar(source) expect(parse(g, " ")).toEqual([null]) }) + }) describe('nearleyc: macros', () => {