Skip to content

Commit 09a092c

Browse files
committed
Reserved: Move reserved words from the parser definition to the config
1 parent 67d57b8 commit 09a092c

File tree

5 files changed

+101
-83
lines changed

5 files changed

+101
-83
lines changed

lib/parser.js

Lines changed: 5 additions & 40 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/peg.d.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,9 @@ declare namespace ast {
204204
/** Current Peggy version in semver format. */
205205
export const VERSION: string;
206206

207+
/** Default list of reserved words. Contains list of JavaScript reserved words */
208+
export const RESERVED_WORDS: string[];
209+
207210
/**
208211
* The entry that maps object in the `source` property of error locations
209212
* to the actual source text of a grammar. That entries is necessary for
@@ -282,6 +285,11 @@ export namespace parser {
282285
* File object.
283286
*/
284287
grammarSource?: any;
288+
/**
289+
* List of words that won't be allowed as label names. Using such word will
290+
* produce a syntax error.
291+
*/
292+
reservedWords: string[];
285293
/** The only acceptable rule is `"Grammar"`, all other values leads to the exception */
286294
startRule?: "Grammar";
287295
}
@@ -759,6 +767,13 @@ export interface Config {
759767
* to add their own pass.
760768
*/
761769
passes: Stages;
770+
/**
771+
* List of words that won't be allowed as label names. Using such word will
772+
* produce a syntax error. This property can be replaced by the plugin if
773+
* it want to change list of reserved words. By default this list is equals
774+
* to `RESERVED_WORDS`.
775+
*/
776+
reservedWords: string[];
762777
}
763778

764779
/** Interface for the Peggy extenders. */

lib/peg.js

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,52 @@ const compiler = require("./compiler");
55
const parser = require("./parser");
66
const VERSION = require("./version");
77

8+
const RESERVED_WORDS = [
9+
"break",
10+
"case",
11+
"catch",
12+
"class",
13+
"const",
14+
"continue",
15+
"debugger",
16+
"default",
17+
"delete",
18+
"do",
19+
"else",
20+
"enum",
21+
"export",
22+
"extends",
23+
"false",
24+
"finally",
25+
"for",
26+
"function",
27+
"if",
28+
"import",
29+
"instanceof",
30+
"in",
31+
"new",
32+
"null",
33+
"return",
34+
"super",
35+
"switch",
36+
"this",
37+
"throw",
38+
"true",
39+
"try",
40+
"typeof",
41+
"var",
42+
"void",
43+
"while",
44+
"with"
45+
];
46+
847
const peg = {
948
// Peggy version (filled in by /tools/release).
1049
VERSION,
50+
/**
51+
* Default list of reserved words.
52+
*/
53+
RESERVED_WORDS,
1154
GrammarError,
1255
parser,
1356
compiler,
@@ -38,13 +81,17 @@ const peg = {
3881
const plugins = "plugins" in options ? options.plugins : [];
3982
const config = {
4083
parser: peg.parser,
41-
passes: convertPasses(peg.compiler.passes)
84+
passes: convertPasses(peg.compiler.passes),
85+
reservedWords: peg.RESERVED_WORDS.slice(),
4286
};
4387

4488
plugins.forEach(p => { p.use(config, options); });
4589

4690
return peg.compiler.compile(
47-
config.parser.parse(grammar, { grammarSource: options.grammarSource }),
91+
config.parser.parse(grammar, {
92+
grammarSource: options.grammarSource,
93+
reservedWords: config.reservedWords,
94+
}),
4895
config.passes,
4996
options
5097
);

src/parser.pegjs

Lines changed: 4 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -38,48 +38,11 @@
3838
"&": "semantic_and",
3939
"!": "semantic_not"
4040
};
41-
42-
// Cannot use Set here because of native IE support.
43-
const reservedWords = [
44-
"break",
45-
"case",
46-
"catch",
47-
"class",
48-
"const",
49-
"continue",
50-
"debugger",
51-
"default",
52-
"delete",
53-
"do",
54-
"else",
55-
"enum",
56-
"export",
57-
"extends",
58-
"false",
59-
"finally",
60-
"for",
61-
"function",
62-
"if",
63-
"import",
64-
"instanceof",
65-
"in",
66-
"new",
67-
"null",
68-
"return",
69-
"super",
70-
"switch",
71-
"this",
72-
"throw",
73-
"true",
74-
"try",
75-
"typeof",
76-
"var",
77-
"void",
78-
"while",
79-
"with"
80-
];
8141
}}
82-
42+
{
43+
// Cannot use Set here because of native IE support.
44+
const reservedWords = options.reservedWords || [];
45+
}
8346
// ---- Syntactic Grammar -----
8447

8548
Grammar

test/api/pegjs-api.spec.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,34 @@ describe("Peggy API", function() {
164164

165165
// The |plugins| option is tested in plugin API tests.
166166

167+
describe("reserved words", function() {
168+
describe("throws an exception on reserved JS words used as a label", function() {
169+
for (const label of peg.RESERVED_WORDS) {
170+
it(label, function() {
171+
expect(() => {
172+
peg.generate([
173+
"start = " + label + ":end",
174+
"end = 'a'"
175+
].join("\n"), { output: "source" });
176+
}).to.throw(peg.parser.SyntaxError);
177+
});
178+
}
179+
});
180+
181+
describe("does not throws an exception on reserved JS words used as a rule name", function() {
182+
for (const rule of peg.RESERVED_WORDS) {
183+
it(rule, function() {
184+
expect(() => {
185+
peg.generate([
186+
"start = " + rule,
187+
rule + " = 'a'"
188+
].join("\n"), { output: "source" });
189+
}).to.not.throw(peg.parser.SyntaxError);
190+
});
191+
}
192+
});
193+
});
194+
167195
it("accepts custom options", function() {
168196
peg.generate("start = 'a'", { grammarSource: 42 });
169197
});

0 commit comments

Comments
 (0)