mirror of
https://github.com/duhanbalci/dexpr.git
synced 2026-07-02 00:29:15 +00:00
initial commit
This commit is contained in:
21
editor/node_modules/@lezer/generator/LICENSE
generated
vendored
Normal file
21
editor/node_modules/@lezer/generator/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (C) 2018 by Marijn Haverbeke <marijn@haverbeke.berlin> and others
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
27
editor/node_modules/@lezer/generator/README.md
generated
vendored
Normal file
27
editor/node_modules/@lezer/generator/README.md
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
# @lezer/generator
|
||||
|
||||
[ [**WEBSITE**](http://lezer.codemirror.net) | [**ISSUES**](https://github.com/lezer-parser/lezer/issues) | [**FORUM**](https://discuss.codemirror.net/c/lezer) | [**CHANGELOG**](https://github.com/lezer-parser/generator/blob/master/CHANGELOG.md) ]
|
||||
|
||||
This is an [LR(1)](https://en.wikipedia.org/wiki/LR_parser) (more precisely pseudo-[LALR](https://en.wikipedia.org/wiki/LALR_parser),with opt-in [GLR](https://en.wikipedia.org/wiki/GLR_parser)) parser generator which outputs grammars that can be used by the [Lezer](https://github.com/lezer-parser/lezer/) parser.
|
||||
|
||||
This package exports both a command-line parser generator tool called [`lezer-generator`](https://lezer.codemirror.net/docs/guide/#building-a-grammar) and a [programming interface](https://lezer.codemirror.net/docs/ref/#generator).
|
||||
|
||||
The grammar format that the tool accepts is documented in the [system guide](https://lezer.codemirror.net/docs/guide/#writing-a-grammar).
|
||||
|
||||
See `test/cases/` for some simple example grammars, or [lezer-javascript](https://github.com/lezer-parser/javascript) for a real grammar.
|
||||
|
||||
You can import `"@lezer/generator/rollup"` to get a [Rollup](https://rollupjs.org/guide/en/) plugin that will transform files ending in `.grammar` or `.grammar.terms` (a pseudo-source referring to the terms produced by the `.grammar` file) as part of the rollup build process.
|
||||
|
||||
```javascript
|
||||
import {lezer} from "@lezer/generator/rollup"
|
||||
|
||||
export default {
|
||||
input: "./in.js",
|
||||
output: {file: "out.js", format: "cjs"},
|
||||
plugins: [lezer()]
|
||||
}
|
||||
```
|
||||
|
||||
The plugin can be passed `lezer({exportName})` option to configure the name of the parser export.
|
||||
|
||||
The code is licensed under an MIT license.
|
||||
4313
editor/node_modules/@lezer/generator/dist/index.cjs
generated
vendored
Normal file
4313
editor/node_modules/@lezer/generator/dist/index.cjs
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
95
editor/node_modules/@lezer/generator/dist/index.d.cts
generated
vendored
Normal file
95
editor/node_modules/@lezer/generator/dist/index.d.cts
generated
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
import { NodePropSource, NodeProp } from '@lezer/common';
|
||||
import { ExternalTokenizer, Stack, ContextTracker, LRParser } from '@lezer/lr';
|
||||
|
||||
type BuildOptions = {
|
||||
/**
|
||||
The name of the grammar file
|
||||
*/
|
||||
fileName?: string;
|
||||
/**
|
||||
A function that should be called with warnings. The default is
|
||||
to call `console.warn`.
|
||||
*/
|
||||
warn?: (message: string) => void;
|
||||
/**
|
||||
Whether to include term names in the output file. Defaults to
|
||||
false.
|
||||
*/
|
||||
includeNames?: boolean;
|
||||
/**
|
||||
Determines the module system used by the output file. Can be
|
||||
either `"cjs"` (CommonJS) or `"es"` (ES2015 module), defaults to
|
||||
`"es"`.
|
||||
*/
|
||||
moduleStyle?: string;
|
||||
/**
|
||||
Set this to true to output TypeScript code instead of plain
|
||||
JavaScript.
|
||||
*/
|
||||
typeScript?: boolean;
|
||||
/**
|
||||
The name of the export that holds the parser in the output file.
|
||||
Defaults to `"parser"`.
|
||||
*/
|
||||
exportName?: string;
|
||||
/**
|
||||
When calling `buildParser`, this can be used to provide
|
||||
placeholders for external tokenizers.
|
||||
*/
|
||||
externalTokenizer?: (name: string, terms: {
|
||||
[name: string]: number;
|
||||
}) => ExternalTokenizer;
|
||||
/**
|
||||
Used by `buildParser` to resolve external prop sources.
|
||||
*/
|
||||
externalPropSource?: (name: string) => NodePropSource;
|
||||
/**
|
||||
Provide placeholders for external specializers when using
|
||||
`buildParser`.
|
||||
*/
|
||||
externalSpecializer?: (name: string, terms: {
|
||||
[name: string]: number;
|
||||
}) => (value: string, stack: Stack) => number;
|
||||
/**
|
||||
If given, will be used to initialize external props in the parser
|
||||
returned by `buildParser`.
|
||||
*/
|
||||
externalProp?: (name: string) => NodeProp<any>;
|
||||
/**
|
||||
If given, will be used as context tracker in a parser built with
|
||||
`buildParser`.
|
||||
*/
|
||||
contextTracker?: ContextTracker<any> | ((terms: {
|
||||
[name: string]: number;
|
||||
}) => ContextTracker<any>);
|
||||
};
|
||||
/**
|
||||
Build an in-memory parser instance for a given grammar. This is
|
||||
mostly useful for testing. If your grammar uses external
|
||||
tokenizers, you'll have to provide the `externalTokenizer` option
|
||||
for the returned parser to be able to parse anything.
|
||||
*/
|
||||
declare function buildParser(text: string, options?: BuildOptions): LRParser;
|
||||
/**
|
||||
Build the code that represents the parser tables for a given
|
||||
grammar description. The `parser` property in the return value
|
||||
holds the main file that exports the `Parser` instance. The
|
||||
`terms` property holds a declaration file that defines constants
|
||||
for all of the named terms in grammar, holding their ids as value.
|
||||
This is useful when external code, such as a tokenizer, needs to
|
||||
be able to use these ids. It is recommended to run a tree-shaking
|
||||
bundler when importing this file, since you usually only need a
|
||||
handful of the many terms in your code.
|
||||
*/
|
||||
declare function buildParserFile(text: string, options?: BuildOptions): {
|
||||
parser: string;
|
||||
terms: string;
|
||||
};
|
||||
|
||||
/**
|
||||
The type of error raised when the parser generator finds an issue.
|
||||
*/
|
||||
declare class GenError extends Error {
|
||||
}
|
||||
|
||||
export { type BuildOptions, GenError, buildParser, buildParserFile };
|
||||
95
editor/node_modules/@lezer/generator/dist/index.d.ts
generated
vendored
Normal file
95
editor/node_modules/@lezer/generator/dist/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
import { NodePropSource, NodeProp } from '@lezer/common';
|
||||
import { ExternalTokenizer, Stack, ContextTracker, LRParser } from '@lezer/lr';
|
||||
|
||||
type BuildOptions = {
|
||||
/**
|
||||
The name of the grammar file
|
||||
*/
|
||||
fileName?: string;
|
||||
/**
|
||||
A function that should be called with warnings. The default is
|
||||
to call `console.warn`.
|
||||
*/
|
||||
warn?: (message: string) => void;
|
||||
/**
|
||||
Whether to include term names in the output file. Defaults to
|
||||
false.
|
||||
*/
|
||||
includeNames?: boolean;
|
||||
/**
|
||||
Determines the module system used by the output file. Can be
|
||||
either `"cjs"` (CommonJS) or `"es"` (ES2015 module), defaults to
|
||||
`"es"`.
|
||||
*/
|
||||
moduleStyle?: string;
|
||||
/**
|
||||
Set this to true to output TypeScript code instead of plain
|
||||
JavaScript.
|
||||
*/
|
||||
typeScript?: boolean;
|
||||
/**
|
||||
The name of the export that holds the parser in the output file.
|
||||
Defaults to `"parser"`.
|
||||
*/
|
||||
exportName?: string;
|
||||
/**
|
||||
When calling `buildParser`, this can be used to provide
|
||||
placeholders for external tokenizers.
|
||||
*/
|
||||
externalTokenizer?: (name: string, terms: {
|
||||
[name: string]: number;
|
||||
}) => ExternalTokenizer;
|
||||
/**
|
||||
Used by `buildParser` to resolve external prop sources.
|
||||
*/
|
||||
externalPropSource?: (name: string) => NodePropSource;
|
||||
/**
|
||||
Provide placeholders for external specializers when using
|
||||
`buildParser`.
|
||||
*/
|
||||
externalSpecializer?: (name: string, terms: {
|
||||
[name: string]: number;
|
||||
}) => (value: string, stack: Stack) => number;
|
||||
/**
|
||||
If given, will be used to initialize external props in the parser
|
||||
returned by `buildParser`.
|
||||
*/
|
||||
externalProp?: (name: string) => NodeProp<any>;
|
||||
/**
|
||||
If given, will be used as context tracker in a parser built with
|
||||
`buildParser`.
|
||||
*/
|
||||
contextTracker?: ContextTracker<any> | ((terms: {
|
||||
[name: string]: number;
|
||||
}) => ContextTracker<any>);
|
||||
};
|
||||
/**
|
||||
Build an in-memory parser instance for a given grammar. This is
|
||||
mostly useful for testing. If your grammar uses external
|
||||
tokenizers, you'll have to provide the `externalTokenizer` option
|
||||
for the returned parser to be able to parse anything.
|
||||
*/
|
||||
declare function buildParser(text: string, options?: BuildOptions): LRParser;
|
||||
/**
|
||||
Build the code that represents the parser tables for a given
|
||||
grammar description. The `parser` property in the return value
|
||||
holds the main file that exports the `Parser` instance. The
|
||||
`terms` property holds a declaration file that defines constants
|
||||
for all of the named terms in grammar, holding their ids as value.
|
||||
This is useful when external code, such as a tokenizer, needs to
|
||||
be able to use these ids. It is recommended to run a tree-shaking
|
||||
bundler when importing this file, since you usually only need a
|
||||
handful of the many terms in your code.
|
||||
*/
|
||||
declare function buildParserFile(text: string, options?: BuildOptions): {
|
||||
parser: string;
|
||||
terms: string;
|
||||
};
|
||||
|
||||
/**
|
||||
The type of error raised when the parser generator finds an issue.
|
||||
*/
|
||||
declare class GenError extends Error {
|
||||
}
|
||||
|
||||
export { type BuildOptions, GenError, buildParser, buildParserFile };
|
||||
4309
editor/node_modules/@lezer/generator/dist/index.js
generated
vendored
Normal file
4309
editor/node_modules/@lezer/generator/dist/index.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
45
editor/node_modules/@lezer/generator/dist/rollup-plugin-lezer.cjs
generated
vendored
Normal file
45
editor/node_modules/@lezer/generator/dist/rollup-plugin-lezer.cjs
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var index_js = require('./index.cjs');
|
||||
|
||||
function lezer(config = {}) {
|
||||
let built = Object.create(null);
|
||||
|
||||
return {
|
||||
name: "rollup-plugin-lezer",
|
||||
|
||||
resolveId(source, importer) {
|
||||
let m = /^([^\0].*\.grammar)(\.terms)?$/.exec(source);
|
||||
if (!m) return null
|
||||
let id = path.resolve(importer ? path.dirname(importer) : process.cwd(), m[1]);
|
||||
return m[2] ? `\0${id}.terms` : id
|
||||
},
|
||||
|
||||
load(id) {
|
||||
let m = /^\0?(.*\.grammar)(\.terms)?$/.exec(id);
|
||||
if (!m) return null
|
||||
if (!m[2]) this.addWatchFile(id);
|
||||
let base = m[1];
|
||||
let build = built[base] || (built[base] = fs.promises.readFile(base, "utf8").then(code => index_js.buildParserFile(code, {
|
||||
fileName: base,
|
||||
moduleStyle: "es",
|
||||
exportName: config.exportName,
|
||||
warn: message => this.warn(message)
|
||||
})));
|
||||
return build.then(result => m[2] ? result.terms : result.parser)
|
||||
},
|
||||
|
||||
watchChange(id) {
|
||||
if (built[id]) built[id] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const rollup = lezer;
|
||||
|
||||
exports.lezer = lezer;
|
||||
exports.rollup = rollup;
|
||||
3
editor/node_modules/@lezer/generator/dist/rollup-plugin-lezer.d.cts
generated
vendored
Normal file
3
editor/node_modules/@lezer/generator/dist/rollup-plugin-lezer.d.cts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import {Plugin} from "rollup"
|
||||
|
||||
export function lezer(config?: {exportName?: string}): Plugin
|
||||
3
editor/node_modules/@lezer/generator/dist/rollup-plugin-lezer.d.ts
generated
vendored
Normal file
3
editor/node_modules/@lezer/generator/dist/rollup-plugin-lezer.d.ts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import {Plugin} from "rollup"
|
||||
|
||||
export function lezer(config?: {exportName?: string}): Plugin
|
||||
38
editor/node_modules/@lezer/generator/dist/rollup-plugin-lezer.js
generated
vendored
Normal file
38
editor/node_modules/@lezer/generator/dist/rollup-plugin-lezer.js
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
import {resolve, dirname} from "path"
|
||||
import {promises as fs} from "fs"
|
||||
import {buildParserFile} from "./index.js"
|
||||
|
||||
export function lezer(config = {}) {
|
||||
let built = Object.create(null)
|
||||
|
||||
return {
|
||||
name: "rollup-plugin-lezer",
|
||||
|
||||
resolveId(source, importer) {
|
||||
let m = /^([^\0].*\.grammar)(\.terms)?$/.exec(source)
|
||||
if (!m) return null
|
||||
let id = resolve(importer ? dirname(importer) : process.cwd(), m[1])
|
||||
return m[2] ? `\0${id}.terms` : id
|
||||
},
|
||||
|
||||
load(id) {
|
||||
let m = /^\0?(.*\.grammar)(\.terms)?$/.exec(id)
|
||||
if (!m) return null
|
||||
if (!m[2]) this.addWatchFile(id)
|
||||
let base = m[1]
|
||||
let build = built[base] || (built[base] = fs.readFile(base, "utf8").then(code => buildParserFile(code, {
|
||||
fileName: base,
|
||||
moduleStyle: "es",
|
||||
exportName: config.exportName,
|
||||
warn: message => this.warn(message)
|
||||
})))
|
||||
return build.then(result => m[2] ? result.terms : result.parser)
|
||||
},
|
||||
|
||||
watchChange(id) {
|
||||
if (built[id]) built[id] = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const rollup = lezer
|
||||
187
editor/node_modules/@lezer/generator/dist/test.cjs
generated
vendored
Normal file
187
editor/node_modules/@lezer/generator/dist/test.cjs
generated
vendored
Normal file
@@ -0,0 +1,187 @@
|
||||
'use strict';
|
||||
|
||||
var common = require('@lezer/common');
|
||||
|
||||
const none = [];
|
||||
class TestSpec {
|
||||
constructor(name, props, children = none, wildcard = false) {
|
||||
this.name = name;
|
||||
this.props = props;
|
||||
this.children = children;
|
||||
this.wildcard = wildcard;
|
||||
}
|
||||
static parse(spec) {
|
||||
let pos = 0, tok = "sof", value = "";
|
||||
function err() {
|
||||
throw new SyntaxError("Invalid test spec: " + spec);
|
||||
}
|
||||
function next() {
|
||||
while (pos < spec.length && /\s/.test(spec.charAt(pos)))
|
||||
pos++;
|
||||
if (pos == spec.length)
|
||||
return tok = "eof";
|
||||
let next = spec.charAt(pos++);
|
||||
if (next == "(" && spec.slice(pos, pos + 4) == "...)") {
|
||||
pos += 4;
|
||||
return tok = "...";
|
||||
}
|
||||
if (/[\[\](),=]/.test(next))
|
||||
return tok = next;
|
||||
if (/[^()\[\],="\s]/.test(next)) {
|
||||
let name = /[^()\[\],="\s]*/.exec(spec.slice(pos - 1));
|
||||
value = name[0];
|
||||
pos += name[0].length - 1;
|
||||
return tok = "name";
|
||||
}
|
||||
if (next == '"') {
|
||||
let content = /^"((?:[^\\"]|\\.)*)"/.exec(spec.slice(pos - 1)) || err();
|
||||
value = JSON.parse(content[0]);
|
||||
pos += content[0].length - 1;
|
||||
return tok = "name";
|
||||
}
|
||||
return err();
|
||||
}
|
||||
next();
|
||||
function parseSeq() {
|
||||
let seq = [];
|
||||
while (tok != "eof" && tok != ")") {
|
||||
seq.push(parse());
|
||||
if (tok == ",")
|
||||
next();
|
||||
}
|
||||
return seq;
|
||||
}
|
||||
function parse() {
|
||||
let name = value, children = none, props = [], wildcard = false;
|
||||
if (tok != "name")
|
||||
err();
|
||||
next();
|
||||
if (tok == "[") {
|
||||
next();
|
||||
while (tok != "]") {
|
||||
if (tok != "name")
|
||||
err();
|
||||
let prop = common.NodeProp[value], val = "";
|
||||
if (!(prop instanceof common.NodeProp))
|
||||
err();
|
||||
next();
|
||||
if (tok == "=") {
|
||||
next();
|
||||
if (tok != "name")
|
||||
err();
|
||||
val = value;
|
||||
next();
|
||||
}
|
||||
props.push({ prop, value: prop.deserialize(val) });
|
||||
}
|
||||
next();
|
||||
}
|
||||
if (tok == "(") {
|
||||
next();
|
||||
children = parseSeq();
|
||||
// @ts-ignore TypeScript doesn't understand that `next` may have mutated `tok` (#9998)
|
||||
if (tok != ")")
|
||||
err();
|
||||
next();
|
||||
}
|
||||
else if (tok == "...") {
|
||||
wildcard = true;
|
||||
next();
|
||||
}
|
||||
return new TestSpec(name, props, children, wildcard);
|
||||
}
|
||||
let result = parseSeq();
|
||||
if (tok != "eof")
|
||||
err();
|
||||
return result;
|
||||
}
|
||||
matches(type) {
|
||||
if (type.name != this.name)
|
||||
return false;
|
||||
for (let { prop, value } of this.props)
|
||||
if ((value || type.prop(prop)) && JSON.stringify(type.prop(prop)) != JSON.stringify(value))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
function defaultIgnore(type) { return /\W/.test(type.name); }
|
||||
function testTree(tree, expect, mayIgnore = defaultIgnore) {
|
||||
let specs = TestSpec.parse(expect);
|
||||
let stack = [specs], pos = [0];
|
||||
tree.iterate({
|
||||
enter(n) {
|
||||
if (!n.name)
|
||||
return;
|
||||
let last = stack.length - 1, index = pos[last], seq = stack[last];
|
||||
let next = index < seq.length ? seq[index] : null;
|
||||
if (next && next.matches(n.type)) {
|
||||
if (next.wildcard) {
|
||||
pos[last]++;
|
||||
return false;
|
||||
}
|
||||
pos.push(0);
|
||||
stack.push(next.children);
|
||||
return undefined;
|
||||
}
|
||||
else if (mayIgnore(n.type)) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
let parent = last > 0 ? stack[last - 1][pos[last - 1]].name : "tree";
|
||||
let after = next ? next.name + (parent == "tree" ? "" : " in " + parent) : `end of ${parent}`;
|
||||
throw new Error(`Expected ${after}, got ${n.name} at ${n.to} \n${tree}`);
|
||||
}
|
||||
},
|
||||
leave(n) {
|
||||
if (!n.name)
|
||||
return;
|
||||
let last = stack.length - 1, index = pos[last], seq = stack[last];
|
||||
if (index < seq.length)
|
||||
throw new Error(`Unexpected end of ${n.name}. Expected ${seq.slice(index).map(s => s.name).join(", ")} at ${n.from}\n${tree}`);
|
||||
pos.pop();
|
||||
stack.pop();
|
||||
pos[last - 1]++;
|
||||
}
|
||||
});
|
||||
if (pos[0] != specs.length)
|
||||
throw new Error(`Unexpected end of tree. Expected ${stack[0].slice(pos[0]).map(s => s.name).join(", ")} at ${tree.length}\n${tree}`);
|
||||
}
|
||||
function toLineContext(file, index) {
|
||||
const endEol = file.indexOf('\n', index + 80);
|
||||
const endIndex = endEol === -1 ? file.length : endEol;
|
||||
return file.substring(index, endIndex).split(/\n/).map(str => ' | ' + str).join('\n');
|
||||
}
|
||||
function fileTests(file, fileName, mayIgnore = defaultIgnore) {
|
||||
let caseExpr = /\s*#[ \t]*(.*)(?:\r\n|\r|\n)([^]*?)==+>([^]*?)(?:$|(?:\r\n|\r|\n)+(?=#))/gy;
|
||||
let tests = [];
|
||||
let lastIndex = 0;
|
||||
for (;;) {
|
||||
let m = caseExpr.exec(file);
|
||||
if (!m)
|
||||
throw new Error(`Unexpected file format in ${fileName} around\n\n${toLineContext(file, lastIndex)}`);
|
||||
let text = m[2].trim(), expected = m[3].trim();
|
||||
let [, name, configStr] = /(.*?)(\{.*?\})?$/.exec(m[1]);
|
||||
let config = configStr ? JSON.parse(configStr) : null;
|
||||
let strict = !/⚠|\.\.\./.test(expected);
|
||||
tests.push({
|
||||
name,
|
||||
text,
|
||||
expected,
|
||||
configStr,
|
||||
config,
|
||||
strict,
|
||||
run(parser) {
|
||||
if (parser.configure && (strict || config))
|
||||
parser = parser.configure(Object.assign({ strict }, config));
|
||||
testTree(parser.parse(text), expected, mayIgnore);
|
||||
}
|
||||
});
|
||||
lastIndex = m.index + m[0].length;
|
||||
if (lastIndex == file.length)
|
||||
break;
|
||||
}
|
||||
return tests;
|
||||
}
|
||||
|
||||
exports.fileTests = fileTests;
|
||||
exports.testTree = testTree;
|
||||
15
editor/node_modules/@lezer/generator/dist/test.d.cts
generated
vendored
Normal file
15
editor/node_modules/@lezer/generator/dist/test.d.cts
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
import { Tree, Parser, NodeType } from '@lezer/common';
|
||||
|
||||
declare function defaultIgnore(type: NodeType): boolean;
|
||||
declare function testTree(tree: Tree, expect: string, mayIgnore?: typeof defaultIgnore): void;
|
||||
declare function fileTests(file: string, fileName: string, mayIgnore?: typeof defaultIgnore): {
|
||||
name: string;
|
||||
text: string;
|
||||
expected: string;
|
||||
configStr: string;
|
||||
config: object;
|
||||
strict: boolean;
|
||||
run(parser: Parser): void;
|
||||
}[];
|
||||
|
||||
export { fileTests, testTree };
|
||||
15
editor/node_modules/@lezer/generator/dist/test.d.ts
generated
vendored
Normal file
15
editor/node_modules/@lezer/generator/dist/test.d.ts
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
import { Tree, Parser, NodeType } from '@lezer/common';
|
||||
|
||||
declare function defaultIgnore(type: NodeType): boolean;
|
||||
declare function testTree(tree: Tree, expect: string, mayIgnore?: typeof defaultIgnore): void;
|
||||
declare function fileTests(file: string, fileName: string, mayIgnore?: typeof defaultIgnore): {
|
||||
name: string;
|
||||
text: string;
|
||||
expected: string;
|
||||
configStr: string;
|
||||
config: object;
|
||||
strict: boolean;
|
||||
run(parser: Parser): void;
|
||||
}[];
|
||||
|
||||
export { fileTests, testTree };
|
||||
184
editor/node_modules/@lezer/generator/dist/test.js
generated
vendored
Normal file
184
editor/node_modules/@lezer/generator/dist/test.js
generated
vendored
Normal file
@@ -0,0 +1,184 @@
|
||||
import { NodeProp } from '@lezer/common';
|
||||
|
||||
const none = [];
|
||||
class TestSpec {
|
||||
constructor(name, props, children = none, wildcard = false) {
|
||||
this.name = name;
|
||||
this.props = props;
|
||||
this.children = children;
|
||||
this.wildcard = wildcard;
|
||||
}
|
||||
static parse(spec) {
|
||||
let pos = 0, tok = "sof", value = "";
|
||||
function err() {
|
||||
throw new SyntaxError("Invalid test spec: " + spec);
|
||||
}
|
||||
function next() {
|
||||
while (pos < spec.length && /\s/.test(spec.charAt(pos)))
|
||||
pos++;
|
||||
if (pos == spec.length)
|
||||
return tok = "eof";
|
||||
let next = spec.charAt(pos++);
|
||||
if (next == "(" && spec.slice(pos, pos + 4) == "...)") {
|
||||
pos += 4;
|
||||
return tok = "...";
|
||||
}
|
||||
if (/[\[\](),=]/.test(next))
|
||||
return tok = next;
|
||||
if (/[^()\[\],="\s]/.test(next)) {
|
||||
let name = /[^()\[\],="\s]*/.exec(spec.slice(pos - 1));
|
||||
value = name[0];
|
||||
pos += name[0].length - 1;
|
||||
return tok = "name";
|
||||
}
|
||||
if (next == '"') {
|
||||
let content = /^"((?:[^\\"]|\\.)*)"/.exec(spec.slice(pos - 1)) || err();
|
||||
value = JSON.parse(content[0]);
|
||||
pos += content[0].length - 1;
|
||||
return tok = "name";
|
||||
}
|
||||
return err();
|
||||
}
|
||||
next();
|
||||
function parseSeq() {
|
||||
let seq = [];
|
||||
while (tok != "eof" && tok != ")") {
|
||||
seq.push(parse());
|
||||
if (tok == ",")
|
||||
next();
|
||||
}
|
||||
return seq;
|
||||
}
|
||||
function parse() {
|
||||
let name = value, children = none, props = [], wildcard = false;
|
||||
if (tok != "name")
|
||||
err();
|
||||
next();
|
||||
if (tok == "[") {
|
||||
next();
|
||||
while (tok != "]") {
|
||||
if (tok != "name")
|
||||
err();
|
||||
let prop = NodeProp[value], val = "";
|
||||
if (!(prop instanceof NodeProp))
|
||||
err();
|
||||
next();
|
||||
if (tok == "=") {
|
||||
next();
|
||||
if (tok != "name")
|
||||
err();
|
||||
val = value;
|
||||
next();
|
||||
}
|
||||
props.push({ prop, value: prop.deserialize(val) });
|
||||
}
|
||||
next();
|
||||
}
|
||||
if (tok == "(") {
|
||||
next();
|
||||
children = parseSeq();
|
||||
// @ts-ignore TypeScript doesn't understand that `next` may have mutated `tok` (#9998)
|
||||
if (tok != ")")
|
||||
err();
|
||||
next();
|
||||
}
|
||||
else if (tok == "...") {
|
||||
wildcard = true;
|
||||
next();
|
||||
}
|
||||
return new TestSpec(name, props, children, wildcard);
|
||||
}
|
||||
let result = parseSeq();
|
||||
if (tok != "eof")
|
||||
err();
|
||||
return result;
|
||||
}
|
||||
matches(type) {
|
||||
if (type.name != this.name)
|
||||
return false;
|
||||
for (let { prop, value } of this.props)
|
||||
if ((value || type.prop(prop)) && JSON.stringify(type.prop(prop)) != JSON.stringify(value))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
function defaultIgnore(type) { return /\W/.test(type.name); }
|
||||
function testTree(tree, expect, mayIgnore = defaultIgnore) {
|
||||
let specs = TestSpec.parse(expect);
|
||||
let stack = [specs], pos = [0];
|
||||
tree.iterate({
|
||||
enter(n) {
|
||||
if (!n.name)
|
||||
return;
|
||||
let last = stack.length - 1, index = pos[last], seq = stack[last];
|
||||
let next = index < seq.length ? seq[index] : null;
|
||||
if (next && next.matches(n.type)) {
|
||||
if (next.wildcard) {
|
||||
pos[last]++;
|
||||
return false;
|
||||
}
|
||||
pos.push(0);
|
||||
stack.push(next.children);
|
||||
return undefined;
|
||||
}
|
||||
else if (mayIgnore(n.type)) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
let parent = last > 0 ? stack[last - 1][pos[last - 1]].name : "tree";
|
||||
let after = next ? next.name + (parent == "tree" ? "" : " in " + parent) : `end of ${parent}`;
|
||||
throw new Error(`Expected ${after}, got ${n.name} at ${n.to} \n${tree}`);
|
||||
}
|
||||
},
|
||||
leave(n) {
|
||||
if (!n.name)
|
||||
return;
|
||||
let last = stack.length - 1, index = pos[last], seq = stack[last];
|
||||
if (index < seq.length)
|
||||
throw new Error(`Unexpected end of ${n.name}. Expected ${seq.slice(index).map(s => s.name).join(", ")} at ${n.from}\n${tree}`);
|
||||
pos.pop();
|
||||
stack.pop();
|
||||
pos[last - 1]++;
|
||||
}
|
||||
});
|
||||
if (pos[0] != specs.length)
|
||||
throw new Error(`Unexpected end of tree. Expected ${stack[0].slice(pos[0]).map(s => s.name).join(", ")} at ${tree.length}\n${tree}`);
|
||||
}
|
||||
function toLineContext(file, index) {
|
||||
const endEol = file.indexOf('\n', index + 80);
|
||||
const endIndex = endEol === -1 ? file.length : endEol;
|
||||
return file.substring(index, endIndex).split(/\n/).map(str => ' | ' + str).join('\n');
|
||||
}
|
||||
function fileTests(file, fileName, mayIgnore = defaultIgnore) {
|
||||
let caseExpr = /\s*#[ \t]*(.*)(?:\r\n|\r|\n)([^]*?)==+>([^]*?)(?:$|(?:\r\n|\r|\n)+(?=#))/gy;
|
||||
let tests = [];
|
||||
let lastIndex = 0;
|
||||
for (;;) {
|
||||
let m = caseExpr.exec(file);
|
||||
if (!m)
|
||||
throw new Error(`Unexpected file format in ${fileName} around\n\n${toLineContext(file, lastIndex)}`);
|
||||
let text = m[2].trim(), expected = m[3].trim();
|
||||
let [, name, configStr] = /(.*?)(\{.*?\})?$/.exec(m[1]);
|
||||
let config = configStr ? JSON.parse(configStr) : null;
|
||||
let strict = !/⚠|\.\.\./.test(expected);
|
||||
tests.push({
|
||||
name,
|
||||
text,
|
||||
expected,
|
||||
configStr,
|
||||
config,
|
||||
strict,
|
||||
run(parser) {
|
||||
if (parser.configure && (strict || config))
|
||||
parser = parser.configure(Object.assign({ strict }, config));
|
||||
testTree(parser.parse(text), expected, mayIgnore);
|
||||
}
|
||||
});
|
||||
lastIndex = m.index + m[0].length;
|
||||
if (lastIndex == file.length)
|
||||
break;
|
||||
}
|
||||
return tests;
|
||||
}
|
||||
|
||||
export { fileTests, testTree };
|
||||
56
editor/node_modules/@lezer/generator/package.json
generated
vendored
Normal file
56
editor/node_modules/@lezer/generator/package.json
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"name": "@lezer/generator",
|
||||
"version": "1.8.0",
|
||||
"description": "Parser generator for the incremental lezer parser",
|
||||
"main": "dist/index.cjs",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./dist/index.js",
|
||||
"require": "./dist/index.cjs"
|
||||
},
|
||||
"./test": {
|
||||
"import": "./dist/test.js",
|
||||
"require": "./dist/test.cjs"
|
||||
},
|
||||
"./dist/test": {
|
||||
"import": "./dist/test.js",
|
||||
"require": "./dist/test.cjs"
|
||||
},
|
||||
"./rollup": {
|
||||
"import": "./dist/rollup-plugin-lezer.js",
|
||||
"require": "./dist/rollup-plugin-lezer.cjs"
|
||||
}
|
||||
},
|
||||
"module": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"author": "Marijn Haverbeke <marijn@haverbeke.berlin>",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@marijn/buildtool": "^0.1.6",
|
||||
"@types/mocha": "^5.2.6",
|
||||
"@types/node": "^20.5.0",
|
||||
"ist": "^1.1.1",
|
||||
"mocha": "^10.2.0",
|
||||
"ts-node": "^10.9.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@lezer/common": "^1.1.0",
|
||||
"@lezer/lr": "^1.3.0"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/lezer-parser/generator.git"
|
||||
},
|
||||
"scripts": {
|
||||
"watch": "node build.js --watch",
|
||||
"prepare": "node build.js",
|
||||
"test": "mocha"
|
||||
},
|
||||
"bin": {
|
||||
"lezer-generator": "./src/lezer-generator.cjs"
|
||||
}
|
||||
}
|
||||
63
editor/node_modules/@lezer/generator/src/lezer-generator.cjs
generated
vendored
Executable file
63
editor/node_modules/@lezer/generator/src/lezer-generator.cjs
generated
vendored
Executable file
@@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env node
|
||||
const {buildParserFile, GenError} = require("..")
|
||||
|
||||
let file = undefined, out = undefined, moduleStyle = "es", includeNames = false, exportName = undefined, noTerms = false, typeScript = false
|
||||
|
||||
const {writeFileSync, readFileSync} = require("fs")
|
||||
|
||||
const usage = "Usage: lezer-generator [--cjs] [--names] [--noTerms] [--typeScript] [--output outfile] [--export name] file"
|
||||
|
||||
for (let i = 2; i < process.argv.length;) {
|
||||
let arg = process.argv[i++]
|
||||
if (!/^-/.test(arg)) {
|
||||
if (file) error("Multiple input files given")
|
||||
file = arg
|
||||
} else if (arg == "--help") {
|
||||
console.log(usage)
|
||||
process.exit(0)
|
||||
} else if (arg == "--cjs") {
|
||||
moduleStyle = "cjs"
|
||||
} else if (arg == "-o" || arg == "--output") {
|
||||
if (out) error("Multiple output files given")
|
||||
out = process.argv[i++]
|
||||
} else if (arg == "--names") {
|
||||
includeNames = true
|
||||
} else if (arg == "--export") {
|
||||
exportName = process.argv[i++]
|
||||
} else if (arg == "--noTerms") {
|
||||
noTerms = true
|
||||
} else if (arg == "--typeScript") {
|
||||
typeScript = true
|
||||
} else {
|
||||
error("Unrecognized option " + arg)
|
||||
}
|
||||
}
|
||||
|
||||
if (!file) error("No input file given")
|
||||
|
||||
function error(msg) {
|
||||
console.error(msg)
|
||||
console.log(usage)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
let parser, terms
|
||||
try {
|
||||
;({parser, terms} = buildParserFile(readFileSync(file, "utf8"), {
|
||||
fileName: file, moduleStyle, includeNames, exportName, typeScript
|
||||
}))
|
||||
} catch (e) {
|
||||
console.error(e instanceof GenError ? e.message : e.stack)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
if (out) {
|
||||
let ext = /^(.*)\.(c?js|mjs|ts|esm?)$/.exec(out)
|
||||
let outExt = typeScript ? "ts" : "js"
|
||||
let [parserFile, termFile] = ext ? [out, ext[1] + ".terms." + ext[2]] : [out + "." + outExt, out + ".terms." + outExt]
|
||||
writeFileSync(parserFile, parser)
|
||||
if (!noTerms) writeFileSync(termFile, terms)
|
||||
console.log(`Wrote ${parserFile}${noTerms ? "" : ` and ${termFile}`}`)
|
||||
} else {
|
||||
console.log(parser)
|
||||
}
|
||||
Reference in New Issue
Block a user