File tree Expand file tree Collapse file tree 5 files changed +101
-83
lines changed
Expand file tree Collapse file tree 5 files changed +101
-83
lines changed Original file line number Diff line number Diff line change @@ -204,6 +204,9 @@ declare namespace ast {
204204/** Current Peggy version in semver format. */
205205export 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. */
Original file line number Diff line number Diff line change @@ -5,9 +5,52 @@ const compiler = require("./compiler");
55const parser = require ( "./parser" ) ;
66const 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+
847const 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 ) ;
Original file line number Diff line number Diff line change 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
8548Grammar
Original file line number Diff line number Diff 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 } ) ;
You can’t perform that action at this time.
0 commit comments