Compare commits
10 Commits
Author | SHA1 | Date |
---|---|---|
Sven Slootweg | 1d3a57d256 | 4 years ago |
Sven Slootweg | 1431320019 | 4 years ago |
Sven Slootweg | f11ef306c8 | 4 years ago |
Sven Slootweg | 51d6414151 | 4 years ago |
Sven Slootweg | 233f92f285 | 4 years ago |
Sven Slootweg | 937e1d4698 | 4 years ago |
Sven Slootweg | baf846b53f | 4 years ago |
Sven Slootweg | 8f737014fe | 4 years ago |
Sven Slootweg | 30400240e3 | 4 years ago |
Sven Slootweg | 69dbe3a4e4 | 4 years ago |
@ -0,0 +1,3 @@
|
|||||||
|
lib/parser.js
|
||||||
|
test/vendor/**/*
|
||||||
|
benchmark/vendor/**/*
|
@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"extends": "dmajda"
|
"extends": "@joepie91/eslint-config"
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
browser/*
|
browser
|
||||||
examples/*.js
|
examples/*.js
|
||||||
node_modules/*
|
node_modules
|
||||||
|
@ -1,42 +1,42 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
let benchmarks = [
|
let benchmarks = [
|
||||||
{
|
{
|
||||||
id: "json",
|
id: "json",
|
||||||
title: "JSON",
|
title: "JSON",
|
||||||
tests: [
|
tests: [
|
||||||
{ file: "example1.json", title: "Example 1" },
|
{ file: "example1.json", title: "Example 1" },
|
||||||
{ file: "example2.json", title: "Example 2" },
|
{ file: "example2.json", title: "Example 2" },
|
||||||
{ file: "example3.json", title: "Example 3" },
|
{ file: "example3.json", title: "Example 3" },
|
||||||
{ file: "example4.json", title: "Example 4" },
|
{ file: "example4.json", title: "Example 4" },
|
||||||
{ file: "example5.json", title: "Example 5" }
|
{ file: "example5.json", title: "Example 5" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "css",
|
id: "css",
|
||||||
title: "CSS",
|
title: "CSS",
|
||||||
tests: [
|
tests: [
|
||||||
{ file: "blueprint/src/reset.css", title: "Blueprint - reset.css (source)" },
|
{ file: "blueprint/src/reset.css", title: "Blueprint - reset.css (source)" },
|
||||||
{ file: "blueprint/src/typography.css", title: "Blueprint - typography.css (source)" },
|
{ file: "blueprint/src/typography.css", title: "Blueprint - typography.css (source)" },
|
||||||
{ file: "blueprint/src/forms.css", title: "Blueprint - forms.css (source)" },
|
{ file: "blueprint/src/forms.css", title: "Blueprint - forms.css (source)" },
|
||||||
{ file: "blueprint/src/grid.css", title: "Blueprint - grid.css (source)" },
|
{ file: "blueprint/src/grid.css", title: "Blueprint - grid.css (source)" },
|
||||||
{ file: "blueprint/src/print.css", title: "Blueprint - print.css (source)" },
|
{ file: "blueprint/src/print.css", title: "Blueprint - print.css (source)" },
|
||||||
// Contains syntax errors.
|
// Contains syntax errors.
|
||||||
// { file: "blueprint/src/ie.css", title: "Blueprint - ie.css (source)" },
|
// { file: "blueprint/src/ie.css", title: "Blueprint - ie.css (source)" },
|
||||||
{ file: "blueprint/min/screen.css", title: "Blueprint - screen.css (minified)" },
|
{ file: "blueprint/min/screen.css", title: "Blueprint - screen.css (minified)" },
|
||||||
{ file: "blueprint/min/print.css", title: "Blueprint - print.css (minified)" },
|
{ file: "blueprint/min/print.css", title: "Blueprint - print.css (minified)" },
|
||||||
// Contains syntax errors.
|
// Contains syntax errors.
|
||||||
// { file: "blueprint/min/ie.css", title: "Blueprint - ie.css (minified)" },
|
// { file: "blueprint/min/ie.css", title: "Blueprint - ie.css (minified)" },
|
||||||
{ file: "960.gs/src/reset.css", title: "960.gs - reset.css (source)" },
|
{ file: "960.gs/src/reset.css", title: "960.gs - reset.css (source)" },
|
||||||
{ file: "960.gs/src/text.css", title: "960.gs - text.css (source)" },
|
{ file: "960.gs/src/text.css", title: "960.gs - text.css (source)" },
|
||||||
{ file: "960.gs/src/960.css", title: "960.gs - 960.css (source)" },
|
{ file: "960.gs/src/960.css", title: "960.gs - 960.css (source)" },
|
||||||
{ file: "960.gs/src/960_24_col.css", title: "960.gs - 960_24_col.css (source)" },
|
{ file: "960.gs/src/960_24_col.css", title: "960.gs - 960_24_col.css (source)" },
|
||||||
{ file: "960.gs/min/reset.css", title: "960.gs - reset.css (minified)" },
|
{ file: "960.gs/min/reset.css", title: "960.gs - reset.css (minified)" },
|
||||||
{ file: "960.gs/min/text.css", title: "960.gs - text.css (minified)" },
|
{ file: "960.gs/min/text.css", title: "960.gs - text.css (minified)" },
|
||||||
{ file: "960.gs/min/960.css", title: "960.gs - 960.css (minified)" },
|
{ file: "960.gs/min/960.css", title: "960.gs - 960.css (minified)" },
|
||||||
{ file: "960.gs/min/960_24_col.css", title: "960.gs - 960_24_col.css (minified)" }
|
{ file: "960.gs/min/960_24_col.css", title: "960.gs - 960_24_col.css (minified)" }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
module.exports = benchmarks;
|
module.exports = benchmarks;
|
||||||
|
@ -1,118 +1,116 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
/* global setTimeout */
|
|
||||||
|
|
||||||
let peg = require("../lib/peg");
|
let peg = require("../lib/peg");
|
||||||
|
|
||||||
let Runner = {
|
let Runner = {
|
||||||
run(benchmarks, runCount, options, callbacks) {
|
run(benchmarks, runCount, options, callbacks) {
|
||||||
// Queue
|
// Queue
|
||||||
|
|
||||||
let Q = {
|
let Q = {
|
||||||
functions: [],
|
functions: [],
|
||||||
|
|
||||||
add(f) {
|
add(f) {
|
||||||
this.functions.push(f);
|
this.functions.push(f);
|
||||||
},
|
},
|
||||||
|
|
||||||
run() {
|
run() {
|
||||||
if (this.functions.length > 0) {
|
if (this.functions.length > 0) {
|
||||||
this.functions.shift()();
|
this.functions.shift()();
|
||||||
|
|
||||||
// We can't use |arguments.callee| here because |this| would get
|
// We can't use |arguments.callee| here because |this| would get
|
||||||
// messed-up in that case.
|
// messed-up in that case.
|
||||||
setTimeout(() => { Q.run(); }, 0);
|
setTimeout(() => { Q.run(); }, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// The benchmark itself is factored out into several functions (some of them
|
// The benchmark itself is factored out into several functions (some of them
|
||||||
// generated), which are enqueued and run one by one using |setTimeout|. We
|
// generated), which are enqueued and run one by one using |setTimeout|. We
|
||||||
// do this for two reasons:
|
// do this for two reasons:
|
||||||
//
|
//
|
||||||
// 1. To avoid bowser mechanism for interrupting long-running scripts to
|
// 1. To avoid bowser mechanism for interrupting long-running scripts to
|
||||||
// kick-in (or at least to not kick-in that often).
|
// kick-in (or at least to not kick-in that often).
|
||||||
//
|
//
|
||||||
// 2. To ensure progressive rendering of results in the browser (some
|
// 2. To ensure progressive rendering of results in the browser (some
|
||||||
// browsers do not render at all when running JavaScript code).
|
// browsers do not render at all when running JavaScript code).
|
||||||
//
|
//
|
||||||
// The enqueued functions share state, which is all stored in the properties
|
// The enqueued functions share state, which is all stored in the properties
|
||||||
// of the |state| object.
|
// of the |state| object.
|
||||||
|
|
||||||
let state = {};
|
let state = {};
|
||||||
|
|
||||||
function initialize() {
|
function initialize() {
|
||||||
callbacks.start();
|
callbacks.start();
|
||||||
|
|
||||||
state.totalInputSize = 0;
|
state.totalInputSize = 0;
|
||||||
state.totalParseTime = 0;
|
state.totalParseTime = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function benchmarkInitializer(benchmark) {
|
function benchmarkInitializer(benchmark) {
|
||||||
return function() {
|
return function() {
|
||||||
callbacks.benchmarkStart(benchmark);
|
callbacks.benchmarkStart(benchmark);
|
||||||
|
|
||||||
state.parser = peg.generate(
|
state.parser = peg.generate(
|
||||||
callbacks.readFile("../examples/" + benchmark.id + ".pegjs"),
|
callbacks.readFile("../examples/" + benchmark.id + ".pegjs"),
|
||||||
options
|
options
|
||||||
);
|
);
|
||||||
state.benchmarkInputSize = 0;
|
state.benchmarkInputSize = 0;
|
||||||
state.benchmarkParseTime = 0;
|
state.benchmarkParseTime = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function testRunner(benchmark, test) {
|
function testRunner(benchmark, test) {
|
||||||
return function() {
|
return function() {
|
||||||
callbacks.testStart(benchmark, test);
|
callbacks.testStart(benchmark, test);
|
||||||
|
|
||||||
let input = callbacks.readFile(benchmark.id + "/" + test.file);
|
let input = callbacks.readFile(benchmark.id + "/" + test.file);
|
||||||
|
|
||||||
let parseTime = 0;
|
let parseTime = 0;
|
||||||
for (let i = 0; i < runCount; i++) {
|
for (let i = 0; i < runCount; i++) {
|
||||||
let t = (new Date()).getTime();
|
let t = (new Date()).getTime();
|
||||||
state.parser.parse(input);
|
state.parser.parse(input);
|
||||||
parseTime += (new Date()).getTime() - t;
|
parseTime += (new Date()).getTime() - t;
|
||||||
}
|
}
|
||||||
let averageParseTime = parseTime / runCount;
|
let averageParseTime = parseTime / runCount;
|
||||||
|
|
||||||
callbacks.testFinish(benchmark, test, input.length, averageParseTime);
|
callbacks.testFinish(benchmark, test, input.length, averageParseTime);
|
||||||
|
|
||||||
state.benchmarkInputSize += input.length;
|
state.benchmarkInputSize += input.length;
|
||||||
state.benchmarkParseTime += averageParseTime;
|
state.benchmarkParseTime += averageParseTime;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function benchmarkFinalizer(benchmark) {
|
function benchmarkFinalizer(benchmark) {
|
||||||
return function() {
|
return function() {
|
||||||
callbacks.benchmarkFinish(
|
callbacks.benchmarkFinish(
|
||||||
benchmark,
|
benchmark,
|
||||||
state.benchmarkInputSize,
|
state.benchmarkInputSize,
|
||||||
state.benchmarkParseTime
|
state.benchmarkParseTime
|
||||||
);
|
);
|
||||||
|
|
||||||
state.totalInputSize += state.benchmarkInputSize;
|
state.totalInputSize += state.benchmarkInputSize;
|
||||||
state.totalParseTime += state.benchmarkParseTime;
|
state.totalParseTime += state.benchmarkParseTime;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function finalize() {
|
function finalize() {
|
||||||
callbacks.finish(state.totalInputSize, state.totalParseTime);
|
callbacks.finish(state.totalInputSize, state.totalParseTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main
|
// Main
|
||||||
|
|
||||||
Q.add(initialize);
|
Q.add(initialize);
|
||||||
benchmarks.forEach(benchmark => {
|
benchmarks.forEach(benchmark => {
|
||||||
Q.add(benchmarkInitializer(benchmark));
|
Q.add(benchmarkInitializer(benchmark));
|
||||||
benchmark.tests.forEach(test => {
|
benchmark.tests.forEach(test => {
|
||||||
Q.add(testRunner(benchmark, test));
|
Q.add(testRunner(benchmark, test));
|
||||||
});
|
});
|
||||||
Q.add(benchmarkFinalizer(benchmark));
|
Q.add(benchmarkFinalizer(benchmark));
|
||||||
});
|
});
|
||||||
Q.add(finalize);
|
Q.add(finalize);
|
||||||
|
|
||||||
Q.run();
|
Q.run();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = Runner;
|
module.exports = Runner;
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
const util = require("util");
|
||||||
|
|
||||||
|
const generate = require("../").generate;
|
||||||
|
const parser = require("../lib/parser");
|
||||||
|
|
||||||
|
let grammar = fs.readFileSync(path.join(__dirname, "test.pegjs"), { encoding: "utf-8" });
|
||||||
|
// let parseResult = parser.parse(grammar);
|
||||||
|
let parseResult = generate(grammar);
|
||||||
|
|
||||||
|
console.log(util.inspect(parseResult, { depth: null, colors: true }));
|
@ -0,0 +1,5 @@
|
|||||||
|
import Foo from "./util.pegjs"
|
||||||
|
import { CommaDelimited as DelimitedNumber } from "./delimited-number"
|
||||||
|
|
||||||
|
TopLevelRule
|
||||||
|
= "hello"
|
@ -1,108 +1,21 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
/* eslint-env node */
|
|
||||||
|
|
||||||
let babelify = require("babelify");
|
|
||||||
let browserify = require("browserify");
|
|
||||||
let buffer = require("vinyl-buffer");
|
|
||||||
let del = require("del");
|
|
||||||
let eslint = require("gulp-eslint");
|
|
||||||
let gulp = require("gulp");
|
let gulp = require("gulp");
|
||||||
let header = require("gulp-header");
|
|
||||||
let mocha = require("gulp-mocha");
|
|
||||||
let package_ = require("./package");
|
|
||||||
let peg = require("./lib/peg");
|
let peg = require("./lib/peg");
|
||||||
let rename = require("gulp-rename");
|
let rename = require("gulp-rename");
|
||||||
let runSequence = require("run-sequence");
|
|
||||||
let source = require("vinyl-source-stream");
|
|
||||||
let spawn = require("child_process").spawn;
|
|
||||||
let transform = require("gulp-transform");
|
let transform = require("gulp-transform");
|
||||||
let uglify = require("gulp-uglify");
|
|
||||||
|
|
||||||
const HEADER = [
|
|
||||||
"// PEG.js " + package_.version,
|
|
||||||
"//",
|
|
||||||
"// https://pegjs.org/",
|
|
||||||
"//",
|
|
||||||
"// Copyright (c) 2010-2016 David Majda",
|
|
||||||
"// Licensed under the MIT License.",
|
|
||||||
""
|
|
||||||
].map(line => `${line}\n`).join("");
|
|
||||||
|
|
||||||
const JS_FILES = [
|
|
||||||
"lib/**/*.js",
|
|
||||||
"!lib/parser.js",
|
|
||||||
"test/**/*.js",
|
|
||||||
"test/server",
|
|
||||||
"!test/vendor/**/*",
|
|
||||||
"benchmark/**/*.js",
|
|
||||||
"benchmark/run",
|
|
||||||
"benchmark/server",
|
|
||||||
"!benchmark/vendor/**/*",
|
|
||||||
"bin/pegjs",
|
|
||||||
"gulpfile.js"
|
|
||||||
];
|
|
||||||
|
|
||||||
const TEST_FILES = [
|
|
||||||
"test/**/*.js",
|
|
||||||
"!test/vendor/**/*"
|
|
||||||
];
|
|
||||||
|
|
||||||
function generate(contents) {
|
function generate(contents) {
|
||||||
return peg.generate(contents.toString(), {
|
return peg.generate(contents.toString(), {
|
||||||
output: "source",
|
output: "source",
|
||||||
format: "commonjs"
|
format: "commonjs"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run ESLint on all JavaScript files.
|
|
||||||
gulp.task("lint", () =>
|
|
||||||
gulp.src(JS_FILES)
|
|
||||||
.pipe(eslint())
|
|
||||||
.pipe(eslint.format())
|
|
||||||
.pipe(eslint.failAfterError())
|
|
||||||
);
|
|
||||||
|
|
||||||
// Run tests.
|
|
||||||
gulp.task("test", () =>
|
|
||||||
gulp.src(TEST_FILES, { read: false })
|
|
||||||
.pipe(mocha())
|
|
||||||
);
|
|
||||||
|
|
||||||
// Run benchmarks.
|
|
||||||
gulp.task("benchmark", () =>
|
|
||||||
spawn("benchmark/run", { stdio: "inherit" })
|
|
||||||
);
|
|
||||||
|
|
||||||
// Create the browser build.
|
|
||||||
gulp.task("browser:build", () =>
|
|
||||||
browserify("lib/peg.js", { standalone: "peg" })
|
|
||||||
.transform(babelify, { presets: "es2015", compact: false })
|
|
||||||
.bundle()
|
|
||||||
.pipe(source("peg.js"))
|
|
||||||
.pipe(header(HEADER))
|
|
||||||
.pipe(gulp.dest("browser"))
|
|
||||||
.pipe(rename({ suffix: ".min" }))
|
|
||||||
.pipe(buffer())
|
|
||||||
.pipe(uglify())
|
|
||||||
.pipe(header(HEADER))
|
|
||||||
.pipe(gulp.dest("browser"))
|
|
||||||
);
|
|
||||||
|
|
||||||
// Delete the browser build.
|
|
||||||
gulp.task("browser:clean", () =>
|
|
||||||
del("browser")
|
|
||||||
);
|
|
||||||
|
|
||||||
// Generate the grammar parser.
|
// Generate the grammar parser.
|
||||||
gulp.task("parser", () =>
|
gulp.task("parser", () =>
|
||||||
gulp.src("src/parser.pegjs")
|
gulp.src("src/parser.pegjs")
|
||||||
.pipe(transform(generate))
|
.pipe(transform("utf8", generate))
|
||||||
.pipe(rename({ extname: ".js" }))
|
.pipe(rename({ extname: ".js" }))
|
||||||
.pipe(gulp.dest("lib"))
|
.pipe(gulp.dest("lib"))
|
||||||
);
|
|
||||||
|
|
||||||
// Default task.
|
|
||||||
gulp.task("default", cb =>
|
|
||||||
runSequence("lint", "test", cb)
|
|
||||||
);
|
);
|
||||||
|
@ -1,54 +1,59 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
function hex(ch) { return ch.charCodeAt(0).toString(16).toUpperCase(); }
|
function hex(character) {
|
||||||
|
return character
|
||||||
|
.charCodeAt(0)
|
||||||
|
.toString(16)
|
||||||
|
.toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
// JavaScript code generation helpers.
|
// JavaScript code generation helpers.
|
||||||
let js = {
|
let js = {
|
||||||
stringEscape(s) {
|
stringEscape(s) {
|
||||||
// ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a string
|
// ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a string
|
||||||
// literal except for the closing quote character, backslash, carriage
|
// literal except for the closing quote character, backslash, carriage
|
||||||
// return, line separator, paragraph separator, and line feed. Any character
|
// return, line separator, paragraph separator, and line feed. Any character
|
||||||
// may appear in the form of an escape sequence.
|
// may appear in the form of an escape sequence.
|
||||||
//
|
//
|
||||||
// For portability, we also escape all control and non-ASCII characters.
|
// For portability, we also escape all control and non-ASCII characters.
|
||||||
return s
|
return s
|
||||||
.replace(/\\/g, "\\\\") // backslash
|
.replace(/\\/g, "\\\\") // backslash
|
||||||
.replace(/"/g, "\\\"") // closing double quote
|
.replace(/"/g, "\\\"") // closing double quote
|
||||||
.replace(/\0/g, "\\0") // null
|
.replace(/\0/g, "\\0") // null
|
||||||
.replace(/\x08/g, "\\b") // backspace
|
.replace(/\x08/g, "\\b") // backspace
|
||||||
.replace(/\t/g, "\\t") // horizontal tab
|
.replace(/\t/g, "\\t") // horizontal tab
|
||||||
.replace(/\n/g, "\\n") // line feed
|
.replace(/\n/g, "\\n") // line feed
|
||||||
.replace(/\v/g, "\\v") // vertical tab
|
.replace(/\v/g, "\\v") // vertical tab
|
||||||
.replace(/\f/g, "\\f") // form feed
|
.replace(/\f/g, "\\f") // form feed
|
||||||
.replace(/\r/g, "\\r") // carriage return
|
.replace(/\r/g, "\\r") // carriage return
|
||||||
.replace(/[\x00-\x0F]/g, ch => "\\x0" + hex(ch))
|
.replace(/[\x00-\x0F]/g, ch => "\\x0" + hex(ch))
|
||||||
.replace(/[\x10-\x1F\x7F-\xFF]/g, ch => "\\x" + hex(ch))
|
.replace(/[\x10-\x1F\x7F-\xFF]/g, ch => "\\x" + hex(ch))
|
||||||
.replace(/[\u0100-\u0FFF]/g, ch => "\\u0" + hex(ch))
|
.replace(/[\u0100-\u0FFF]/g, ch => "\\u0" + hex(ch))
|
||||||
.replace(/[\u1000-\uFFFF]/g, ch => "\\u" + hex(ch));
|
.replace(/[\u1000-\uFFFF]/g, ch => "\\u" + hex(ch));
|
||||||
},
|
},
|
||||||
|
|
||||||
regexpClassEscape(s) {
|
regexpClassEscape(s) {
|
||||||
// Based on ECMA-262, 5th ed., 7.8.5 & 15.10.1.
|
// Based on ECMA-262, 5th ed., 7.8.5 & 15.10.1.
|
||||||
//
|
//
|
||||||
// For portability, we also escape all control and non-ASCII characters.
|
// For portability, we also escape all control and non-ASCII characters.
|
||||||
return s
|
return s
|
||||||
.replace(/\\/g, "\\\\") // backslash
|
.replace(/\\/g, "\\\\") // backslash
|
||||||
.replace(/\//g, "\\/") // closing slash
|
.replace(/\//g, "\\/") // closing slash
|
||||||
.replace(/]/g, "\\]") // closing bracket
|
.replace(/]/g, "\\]") // closing bracket
|
||||||
.replace(/\^/g, "\\^") // caret
|
.replace(/\^/g, "\\^") // caret
|
||||||
.replace(/-/g, "\\-") // dash
|
.replace(/-/g, "\\-") // dash
|
||||||
.replace(/\0/g, "\\0") // null
|
.replace(/\0/g, "\\0") // null
|
||||||
.replace(/\x08/g, "\\b") // backspace
|
.replace(/\x08/g, "\\b") // backspace
|
||||||
.replace(/\t/g, "\\t") // horizontal tab
|
.replace(/\t/g, "\\t") // horizontal tab
|
||||||
.replace(/\n/g, "\\n") // line feed
|
.replace(/\n/g, "\\n") // line feed
|
||||||
.replace(/\v/g, "\\v") // vertical tab
|
.replace(/\v/g, "\\v") // vertical tab
|
||||||
.replace(/\f/g, "\\f") // form feed
|
.replace(/\f/g, "\\f") // form feed
|
||||||
.replace(/\r/g, "\\r") // carriage return
|
.replace(/\r/g, "\\r") // carriage return
|
||||||
.replace(/[\x00-\x0F]/g, ch => "\\x0" + hex(ch))
|
.replace(/[\x00-\x0F]/g, ch => "\\x0" + hex(ch))
|
||||||
.replace(/[\x10-\x1F\x7F-\xFF]/g, ch => "\\x" + hex(ch))
|
.replace(/[\x10-\x1F\x7F-\xFF]/g, ch => "\\x" + hex(ch))
|
||||||
.replace(/[\u0100-\u0FFF]/g, ch => "\\u0" + hex(ch))
|
.replace(/[\u0100-\u0FFF]/g, ch => "\\u0" + hex(ch))
|
||||||
.replace(/[\u1000-\uFFFF]/g, ch => "\\u" + hex(ch));
|
.replace(/[\u1000-\uFFFF]/g, ch => "\\u" + hex(ch));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = js;
|
module.exports = js;
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -0,0 +1,52 @@
|
|||||||
|
Import syntax
|
||||||
|
|
||||||
|
import Foo from packagename
|
||||||
|
import { Foo, Bar } from ./util
|
||||||
|
import { Foo as Bar, Baz, Qux } from ../quz
|
||||||
|
|
||||||
|
|
||||||
|
need to mangle identifiers declared in the initializer!
|
||||||
|
|
||||||
|
===========
|
||||||
|
|
||||||
|
Benchmark before internals changes (best of 3):
|
||||||
|
|
||||||
|
$ yarn benchmark
|
||||||
|
yarn run v1.21.1
|
||||||
|
$ node benchmark/run
|
||||||
|
┌─────────────────────────────────────┬───────────┬────────────┬──────────────┐
|
||||||
|
│ Test │ Inp. size │ Avg. time │ Avg. speed │
|
||||||
|
├─────────────────────────────────────┴───────────┴────────────┴──────────────┤
|
||||||
|
│ JSON │
|
||||||
|
├─────────────────────────────────────┬───────────┬────────────┬──────────────┤
|
||||||
|
│ Example 1 │ 0.69 kB │ 0.40 ms │ 1723.63 kB/s │
|
||||||
|
│ Example 2 │ 0.24 kB │ 0.10 ms │ 2363.28 kB/s │
|
||||||
|
│ Example 3 │ 0.59 kB │ 0.40 ms │ 1474.61 kB/s │
|
||||||
|
│ Example 4 │ 3.39 kB │ 0.90 ms │ 3763.02 kB/s │
|
||||||
|
│ Example 5 │ 0.85 kB │ 0.20 ms │ 4262.70 kB/s │
|
||||||
|
├─────────────────────────────────────┼───────────┼────────────┼──────────────┤
|
||||||
|
│ JSON total │ 5.75 kB │ 2.00 ms │ 2877.44 kB/s │
|
||||||
|
├─────────────────────────────────────┴───────────┴────────────┴──────────────┤
|
||||||
|
│ CSS │
|
||||||
|
├─────────────────────────────────────┬───────────┬────────────┬──────────────┤
|
||||||
|
│ Blueprint - reset.css (source) │ 1.20 kB │ 3.00 ms │ 401.04 kB/s │
|
||||||
|
│ Blueprint - typography.css (source) │ 3.11 kB │ 5.00 ms │ 621.48 kB/s │
|
||||||
|
│ Blueprint - forms.css (source) │ 1.79 kB │ 2.00 ms │ 896.00 kB/s │
|
||||||
|
│ Blueprint - grid.css (source) │ 9.54 kB │ 6.50 ms │ 1467.25 kB/s │
|
||||||
|
│ Blueprint - print.css (source) │ 1.78 kB │ 1.10 ms │ 1621.09 kB/s │
|
||||||
|
│ Blueprint - screen.css (minified) │ 11.83 kB │ 8.00 ms │ 1478.64 kB/s │
|
||||||
|
│ Blueprint - print.css (minified) │ 1.25 kB │ 0.60 ms │ 2089.84 kB/s │
|
||||||
|
│ 960.gs - reset.css (source) │ 0.99 kB │ 0.50 ms │ 1980.47 kB/s │
|
||||||
|
│ 960.gs - text.css (source) │ 0.97 kB │ 0.40 ms │ 2426.76 kB/s │
|
||||||
|
│ 960.gs - 960.css (source) │ 8.94 kB │ 3.00 ms │ 2979.49 kB/s │
|
||||||
|
│ 960.gs - 960_24_col.css (source) │ 7.48 kB │ 2.60 ms │ 2877.85 kB/s │
|
||||||
|
│ 960.gs - reset.css (minified) │ 0.63 kB │ 0.50 ms │ 1265.63 kB/s │
|
||||||
|
│ 960.gs - text.css (minified) │ 0.41 kB │ 0.40 ms │ 1020.51 kB/s │
|
||||||
|
│ 960.gs - 960.css (minified) │ 5.21 kB │ 2.60 ms │ 2004.21 kB/s │
|
||||||
|
│ 960.gs - 960_24_col.css (minified) │ 4.94 kB │ 2.40 ms │ 2057.70 kB/s │
|
||||||
|
├─────────────────────────────────────┼───────────┼────────────┼──────────────┤
|
||||||
|
│ CSS total │ 60.08 kB │ 38.60 ms │ 1556.43 kB/s │
|
||||||
|
├─────────────────────────────────────┼───────────┼────────────┼──────────────┤
|
||||||
|
│ Total │ 65.83 kB │ 40.60 ms │ 1621.50 kB/s │
|
||||||
|
└─────────────────────────────────────┴───────────┴────────────┴──────────────┘
|
||||||
|
Done in 0.60s.
|
@ -1,128 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
let chai = require("chai");
|
|
||||||
let peg = require("../../lib/peg");
|
|
||||||
|
|
||||||
let expect = chai.expect;
|
|
||||||
|
|
||||||
describe("plugin API", function() {
|
|
||||||
describe("use", function() {
|
|
||||||
let grammar = "start = 'a'";
|
|
||||||
|
|
||||||
it("is called for each plugin", function() {
|
|
||||||
let pluginsUsed = [false, false, false];
|
|
||||||
let plugins = [
|
|
||||||
{ use() { pluginsUsed[0] = true; } },
|
|
||||||
{ use() { pluginsUsed[1] = true; } },
|
|
||||||
{ use() { pluginsUsed[2] = true; } }
|
|
||||||
];
|
|
||||||
|
|
||||||
peg.generate(grammar, { plugins: plugins });
|
|
||||||
|
|
||||||
expect(pluginsUsed).to.deep.equal([true, true, true]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("receives configuration", function() {
|
|
||||||
let plugin = {
|
|
||||||
use(config) {
|
|
||||||
expect(config).to.be.an("object");
|
|
||||||
|
|
||||||
expect(config.parser).to.be.an("object");
|
|
||||||
expect(config.parser.parse("start = 'a'")).to.be.an("object");
|
|
||||||
|
|
||||||
expect(config.passes).to.be.an("object");
|
|
||||||
|
|
||||||
expect(config.passes.check).to.be.an("array");
|
|
||||||
config.passes.check.forEach(pass => {
|
|
||||||
expect(pass).to.be.a("function");
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(config.passes.transform).to.be.an("array");
|
|
||||||
config.passes.transform.forEach(pass => {
|
|
||||||
expect(pass).to.be.a("function");
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(config.passes.generate).to.be.an("array");
|
|
||||||
config.passes.generate.forEach(pass => {
|
|
||||||
expect(pass).to.be.a("function");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
peg.generate(grammar, { plugins: [plugin] });
|
|
||||||
});
|
|
||||||
|
|
||||||
it("receives options", function() {
|
|
||||||
let plugin = {
|
|
||||||
use(config, options) {
|
|
||||||
expect(options).to.equal(generateOptions);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let generateOptions = { plugins: [plugin], foo: 42 };
|
|
||||||
|
|
||||||
peg.generate(grammar, generateOptions);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("can replace parser", function() {
|
|
||||||
let plugin = {
|
|
||||||
use(config) {
|
|
||||||
let parser = peg.generate([
|
|
||||||
"start = .* {",
|
|
||||||
" return {",
|
|
||||||
" type: 'grammar',",
|
|
||||||
" rules: [",
|
|
||||||
" {",
|
|
||||||
" type: 'rule',",
|
|
||||||
" name: 'start',",
|
|
||||||
" expression: { type: 'literal', value: text(), ignoreCase: false }",
|
|
||||||
" }",
|
|
||||||
" ]",
|
|
||||||
" };",
|
|
||||||
"}"
|
|
||||||
].join("\n"));
|
|
||||||
|
|
||||||
config.parser = parser;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let parser = peg.generate("a", { plugins: [plugin] });
|
|
||||||
|
|
||||||
expect(parser.parse("a")).to.equal("a");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("can change compiler passes", function() {
|
|
||||||
let plugin = {
|
|
||||||
use(config) {
|
|
||||||
function pass(ast) {
|
|
||||||
ast.code = "({ parse: function() { return 42; } })";
|
|
||||||
}
|
|
||||||
|
|
||||||
config.passes.generate = [pass];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let parser = peg.generate(grammar, { plugins: [plugin] });
|
|
||||||
|
|
||||||
expect(parser.parse("a")).to.equal(42);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("can change options", function() {
|
|
||||||
let grammar = [
|
|
||||||
"a = 'x'",
|
|
||||||
"b = 'x'",
|
|
||||||
"c = 'x'"
|
|
||||||
].join("\n");
|
|
||||||
let plugin = {
|
|
||||||
use(config, options) {
|
|
||||||
options.allowedStartRules = ["b", "c"];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let parser = peg.generate(grammar, {
|
|
||||||
allowedStartRules: ["a"],
|
|
||||||
plugins: [plugin]
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(() => { parser.parse("x", { startRule: "a" }); }).to.throw();
|
|
||||||
expect(parser.parse("x", { startRule: "b" })).to.equal("x");
|
|
||||||
expect(parser.parse("x", { startRule: "c" })).to.equal("x");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue