Codebase list pegjs / 98971f9
Update upstream source from tag 'upstream/0.10.0' Update to upstream version '0.10.0' with Debian dir 2a6b5482c573f121fe5466d6e0a4cbf34b67e126 Xavier Guimard 4 years ago
106 changed file(s) with 21658 addition(s) and 15766 deletion(s). Raw diff Collapse all Expand all
0 {
1 "extends": "eslint:recommended",
2 "rules": {
3 "no-control-regex": "off"
4 }
5 }
+0
-201
CHANGELOG less more
0 0.7.0 (2012-04-18)
1 ------------------
2
3 Big Changes:
4
5 * Added ability to pass options to |PEG.buildParser|.
6 * Implemented the |trackLineAndColumn| option for |PEG.buildParser| (together
7 with the "--track-line-and-column" command-line option). It makes the
8 generated parser track line and column during parsing. These are made
9 available inside actions and predicates as |line| and |column| variables.
10 * Implemented the |cache| option for |PEG.buildParser| (together with the
11 "--cache" command-line option). This option enables/disables the results cache
12 in generated parsers, resulting in dramatic speedup when the cache is disabled
13 (the default now). The cost is breaking the linear parsing time guarantee.
14 * The current parse position is visible inside actions and predicates as the
15 |offset| variable.
16 * Exceptions thrown by the parser have |offset|, |expected| and |found|
17 properties containing machine-readable information about the parse failure
18 (based on a patch by Marcin Stefaniuk).
19 * Semantic predicates have access to preceding labels. [GH-69]
20 * Implemented case-insensitive literal and class matching. [GH-34]
21 * Rewrote the code generator -- split some computations into separate passes and
22 based it on a proper templating system (Codie).
23 * Rewrote variable handling in generated parsers in a stack-like fashion,
24 simplifying the code and making the parsers smaller and faster.
25 * Adapted to Node.js 0.6.6+ (no longer supported in older versions).
26 * Dropped support for IE < 8.
27 * As a result of several optimizations, parsers generated by 0.7.0 are ~6.4
28 times faster and ~19% smaller than those generated by 0.6.2 (as reported by
29 /tools/impact).
30
31 Small Changes:
32
33 * Fixed reported error position when part of the input is not consumed. [GH-48]
34 * Fixed incorrect disjunction operator in |computeErrorPosition| (original patch
35 by Wolfgang Kluge).
36 * Fixed regexp for detecting command-line options in /bin/pegjs. [GH-51]
37 * Generate more efficient code for empty literals (original patch by Wolfgang
38 Kluge).
39 * Fixed comment typos (patches by Wolfgang Kluge and Jason Davies). [GH-59]
40 * Fixed a typo in JavaScript example grammar. [GH-62]
41 * Made copy & paste inclusion of the PEG.js library into another code easier by
42 changing how the library is exported.
43 * Improved the copyright comment and the "Generated by..." header.
44 * Replaced Jakefile with Makefile.
45 * Added "make hint" task that checks all JavaScript files using JSHint and
46 resolved all issues it reported. All JavaScript files and also generated
47 parsers are JSHint-clean now.
48 * Fixed output printed during test failures (expected value was being printed
49 instead of the actual one). Original patch by Wolfgang Kluge.
50 * Added a /tools/impact script to measure speed and size impact of commits.
51 * Various generated code improvements and fixes.
52 * Various internal code improvements and fixes.
53 * Improved README.md.
54
55 0.6.2 (2011-08-20)
56 ------------------
57
58 Small Changes:
59
60 * Reset parser position when action returns |null|.
61 * Fixed typo in JavaScript example grammar.
62
63 0.6.1 (2011-04-14)
64 ------------------
65
66 Small Changes:
67
68 * Use --ascii option when generating a minified version.
69
70 0.6.0 (2011-04-14)
71 ------------------
72
73 Big Changes:
74
75 * Rewrote the command-line mode to be based on Node.js instead of Rhino -- no
76 more Java dependency. This also means that PEG.js is available as a Node.js
77 package and can be required as a module.
78 * Version for the browser is built separately from the command-ine one in two
79 flavors (normal and minified).
80 * Parser variable name is no longer required argument of bin/pegjs -- it is
81 "module.exports" by default and can be set using the -e/--export-var option.
82 This makes parsers generated by /bin/pegjs Node.js modules by default.
83 * Added ability to start parsing from any grammar rule.
84 * Added several compiler optimizations -- 0.6 is ~12% faster than 0.5.1 in the
85 benchmark on V8.
86
87 Small Changes:
88
89 * Split the source code into multiple files combined together using a build
90 system.
91 * Jake is now used instead of Rake for build scripts -- no more Ruby dependency.
92 * Test suite can be run from the command-line.
93 * Benchmark suite can be run from the command-line.
94 * Benchmark browser runner improvements (users can specify number of runs,
95 benchmarks are run using |setTimeout|, table is centered and fixed-width).
96 * Added PEG.js version to "Generated by..." line in generated parsers.
97 * Added PEG.js version information and homepage header to peg.js.
98 * Generated code improvements and fixes.
99 * Internal code improvements and fixes.
100 * Rewrote README.md.
101
102 0.5.1 (2010-11-28)
103 ------------------
104
105 Small Changes:
106
107 * Fixed a problem where "SyntaxError: Invalid range in character class." error
108 appeared when using command-line version on Widnows (GH-13).
109 * Fixed wrong version reported by "bin/pegjs --version".
110 * Removed two unused variables in the code.
111 * Fixed incorrect variable name on two places.
112
113 0.5 (2010-06-10)
114 ----------------
115
116 Big Changes:
117
118 * Syntax change: Use labeled expressions and variables instead of $1, $2, etc.
119 * Syntax change: Replaced ":" after a rule name with "=".
120 * Syntax change: Allow trailing semicolon (";") for rules
121 * Semantic change: Start rule of the grammar is now implicitly its first rule.
122 * Implemented semantic predicates.
123 * Implemented initializers.
124 * Removed ability to change the start rule when generating the parser.
125 * Added several compiler optimizations -- 0.5 is ~11% faster than 0.4 in the
126 benchmark on V8.
127
128 Small Changes:
129
130 * PEG.buildParser now accepts grammars only in string format.
131 * Added "Generated by ..." message to the generated parsers.
132 * Formatted all grammars more consistently and transparently.
133 * Added notes about ECMA-262, 5th ed. compatibility to the JSON example grammar.
134 * Guarded against redefinition of |undefined|.
135 * Made bin/pegjs work when called via a symlink (issue #1).
136 * Fixed bug causing incorrect error messages (issue #2).
137 * Fixed error message for invalid character range.
138 * Fixed string literal parsing in the JavaScript grammar.
139 * Generated code improvements and fixes.
140 * Internal code improvements and fixes.
141 * Improved README.md.
142
143 0.4 (2010-04-17)
144 ----------------
145
146 Big Changes:
147
148 * Improved IE compatibility -- IE6+ is now fully supported.
149 * Generated parsers are now standalone (no runtime is required).
150 * Added example grammars for JavaScript, CSS and JSON.
151 * Added a benchmark suite.
152 * Implemented negative character classes (e.g. [^a-z]).
153 * Project moved from BitBucket to GitHub.
154
155 Small Changes:
156
157 * Code generated for the character classes is now regexp-based (= simpler and
158 more scalable).
159 * Added \uFEFF (BOM) to the definition of whitespace in the metagrammar.
160 * When building a parser, left-recursive rules (both direct and indirect) are
161 reported as errors.
162 * When building a parser, missing rules are reported as errors.
163 * Expected items in the error messages do not contain duplicates and they are
164 sorted.
165 * Fixed several bugs in the example arithmetics grammar.
166 * Converted README to GitHub Flavored Markdown and improved it.
167 * Added CHANGELOG.
168 * Internal code improvements.
169
170 0.3 (2010-03-14)
171 ----------------
172
173 * Wrote README.
174 * Bootstrapped the grammar parser.
175 * Metagrammar recognizes JavaScript-like comments.
176 * Changed standard grammar extension from .peg to .pegjs (it is more specific).
177 * Simplified the example arithmetics grammar + added comment.
178 * Fixed a bug with reporting of invalid ranges such as [b-a] in the metagrammar.
179 * Fixed --start vs. --start-rule inconsistency between help and actual option
180 processing code.
181 * Avoided ugliness in QUnit output.
182 * Fixed typo in help: "parserVar" -> "parser_var".
183 * Internal code improvements.
184
185 0.2.1 (2010-03-08)
186 ------------------
187
188 * Added "pegjs-" prefix to the name of the minified runtime file.
189
190 0.2 (2010-03-08)
191 ----------------
192
193 * Added Rakefile that builds minified runtime using Google Closure Compiler API.
194 * Removed trailing commas in object initializers (Google Closure does not like
195 them).
196
197 0.1 (2010-03-08)
198 ----------------
199
200 * Initial release.
0 Change Log
1 ==========
2
3 This file documents all notable changes to PEG.js. The releases follow [semantic
4 versioning](http://semver.org/).
5
6 0.10.0
7 ------
8
9 Released: August 19, 2016
10
11 ### Major Changes
12
13 * **Parsers can be generated in multiple module formats.** The available
14 formats are: CommonJS (the default), AMD, UMD, globals, and bare (not
15 available from the command-line).
16
17 The format can be specified using the `format` option of the `peg.generate`
18 function or the `--format` option on the command-line.
19
20 It is also possible to specify parser dependencies using the `dependencies`
21 option of the `peg.generate` function or the `--dependency`/`-d` option on
22 the command-line. This is mainly useful for the UMD format, where the
23 dependencies are translated into both AMD dependencies and CommonJS
24 `require` calls.
25
26 * **Browser version of PEG.js is now in the UMD format.** This means it will try
27 to detect AMD or Node.js/CommonJS module loader and define itself as a
28 module. If no loader is found, it will export itself using a global
29 variable.
30
31 * **API polishing.** The `peg.buildParser` function was renamed to
32 `peg.generate`. The global variable the browser version of PEG.js is
33 available in when no loader is detected was renamed from `PEG` to `peg`.
34
35 * **CLI improvements.** There is new `--output`/`-o` command-line option which
36 allows to specify the output file. The old way of specifying the output file
37 using a second argument was removed. To make room for the new `-o` option
38 the old one (a shortcut for `--optimize`) was renamed to `-O`. All these
39 changes make PEG.js conform to traditional compiler command-line interface.
40
41 It is now also possible to use `-` as a file name on the command-line (with
42 the usual meaning of standard input/output).
43
44 * **Improved error messages.** Both messages produced by PEG.js and generated
45 parsers were improved.
46
47 * **Duplicate rule definitions are reported as errors.**
48
49 * **Duplicate labels are reported as errors.**
50
51 ### Minor Changes
52
53 * Exposed the AST node visitor builder as `peg.compiler.visitor`. This is
54 useful mainly for plugins which manipulate the AST.
55
56 * Exposed the function which builds messages of exceptions produced by
57 generated parsers as `SyntaxError.buildMessage`. This is useful mainly for
58 customizing these error messages.
59
60 * The `error` and `expected` functions now accept an optional `location`
61 parameter. This allows to customize the location in which the resulting
62 syntax error is reported.
63
64 * Refactored expectations reported in the `expected` property of exceptions
65 produced by generated parsers. They are no longer de-duplicated and sorted,
66 their format changed to be more machine-readable, and they no longer contain
67 human-readable descriptions.
68
69 * The `found` property of exceptions produced by the `error` function is now
70 set to `null`.
71
72 * Removed access to the parser object in parser code via the `parser`
73 variable.
74
75 * Made handling of optional parameters consistent with ES 2015. Specifically,
76 passing `undefined` as a parameter value is now equivalent to not passing
77 the parameter at all.
78
79 * Renamed several compiler passes.
80
81 * Generated parsers no longer consider `\r`, `\u2028`, and `\u2029` as
82 newlines (only `\n` and `\r\n`).
83
84 * Simplified the arithmetics example grammar.
85
86 * Switched from `first`/`rest` to `head`/`tail` in PEG.js grammar and example
87 grammars.
88
89 * Started using ESLint instead of JSHint and fixed various problems it found.
90
91 * Added [contribution
92 guidelines](https://github.com/pegjs/pegjs/blob/master/CONTRIBUTING.md).
93
94 * Removed support for io.js.
95
96 ### Bug Fixes
97
98 * Fixed `bin/pegjs` so that invoking it with one non-option argument which is
99 an extension-less file doesn’t cause that file to be overwritten.
100
101 * Fixed label scoping so that labels in expressions like `(a:"a")` or `(a:"a"
102 b:"b" c:"c")` aren’t visible from the outside.
103
104 * Fixed escaping of generated JavaScript strings & regexps to also escape DEL
105 (U+007F).
106
107 * Fixed the JSON example grammar to correctly handle characters with code
108 points above U+10FF in strings.
109
110 * Fixed multiple compatibility issues of `tools/impact` on OS X.
111
112 * Fixed slow deduplication of expectation descriptions.
113
114 [Complete set of changes](https://github.com/pegjs/pegjs/compare/v0.9.0...v0.10.0)
115
116 0.9.0
117 -----
118
119 Released: August 30, 2015
120
121 ### Major Changes
122
123 * **Tracing support.** Parsers can be compiled with support for tracing their
124 progress, which can help debugging complex grammars. This feature is
125 experimental and is expected to evolve over time as experience is gained.
126 [More details](https://github.com/pegjs/pegjs/commit/da57118a43a904f753d44d407994cf0b36358adc)
127
128 * **Infinite loop detection.** Grammar constructs that could cause infinite
129 loops in generated parsers are detected during compilation and cause errors.
130
131 * **Improved location information API.** The `line`, `column`, and `offset`
132 functions available in parser code were replaced by a single `location`
133 function which returns an object describing the current location. Similarly,
134 the `line`, `column`, and `offset` properties of exceptions were replaced by
135 a single `location` property. The location is no longer a single point but a
136 character range, which is meaningful mainly in actions where the range
137 covers action’s expression.
138 [More details](https://github.com/pegjs/pegjs/compare/e75f21dc8f0e66b3d87c4c19b3fcb8f89d9c3acd...eaca5f0acf97b66ef141fed84aa95d4e72e33757)
139
140 * **Improved error reporting.** All exceptions thrown when generating a parser
141 have associated location information. And all exceptions thrown by generated
142 parser and PEG.js itself have a stack trace (the `stack` property) in
143 environments that support `Error.captureStackTrace`.
144
145 * **Strict mode code**. All PEG.js and generated parser code is written using
146 [JavaScript strict mode](https://developer.mozilla.org/cs/docs/Web/JavaScript/Reference/Strict_mode).
147
148 ### Minor Changes
149
150 * Labels behave like block-scoped variables. This means parser code can see
151 labels defined outside expressions containing code.
152
153 * Empty sequences are no longer allowed.
154
155 * Label names can’t be JavaScript reserved words.
156
157 * Rule and label names can contain Unicode characters like in JavaScript.
158
159 * Rules have to be separated either by `;` or a newline (until now, any
160 whitespace was enough).
161
162 * The PEG.js grammar and all the example grammars were completely rewritten.
163 This rewrite included a number of cleanups, formatting changes, naming
164 changes, and bug fixes.
165
166 * The parser object can now be accessed as `parser` in parser code.
167
168 * Location information computation is faster.
169
170 * Added support for Node.js >= 0.10.x, io.js, and Edge. Removed support for
171 Node.js < 0.10.x.
172
173 ### Bug Fixes
174
175 * Fixed left recursion detector which missed many cases.
176
177 * Fixed escaping of U+0100—U+107F and U+1000—U+107F in generated code and
178 error messages.
179
180 * Renamed `parse` and `SyntaxError` to `peg$parse` and `peg$SyntaxError` to
181 mark them as internal identifiers.
182
183 [Complete set of changes](https://github.com/pegjs/pegjs/compare/v0.8.0...v0.9.0)
184
185 0.8.0
186 -----
187
188 Released: December 24, 2013
189
190 ### Big Changes
191
192 * Completely rewrote the code generator. Among other things, it allows
193 optimizing generated parsers for parsing speed or code size using the
194 `optimize` option of the `PEG.buildParser` method or the `--optimize`/`-o`
195 option on the command-line. All internal identifiers in generated code now
196 also have a `peg$` prefix to discourage their use and avoid conflicts.
197 [[#35](https://github.com/dmajda/pegjs/issues/35),
198 [#92](https://github.com/dmajda/pegjs/issues/92)]
199
200 * Completely redesigned error handling. Instead of returning `null` inside
201 actions to indicate match failure, new `expected` and `error` functions can
202 be called to trigger an error. Also, expectation inside the `SyntaxError`
203 exceptions are now structured to allow easier machine processing.
204 [[#198](https://github.com/dmajda/pegjs/issues/198)]
205
206 * Implemented a plugin API. The list of plugins to use can be specified using
207 the `plugins` option of the `PEG.buildParser` method or the `--plugin`
208 option on the command-line. Also implemented the `--extra-options` and
209 `--extra-options-file` command-line options, which are mainly useful to pass
210 additional options to plugins.
211 [[#106](https://github.com/dmajda/pegjs/issues/106)]
212
213 * Made `offset`, `line` and `column` functions, not variables. They are now
214 available in all parsers and return lazily-computed position data. Removed
215 now useless `trackLineAndColumn` option of the `PEG.buildParser` method and
216 the `--track-line-and-column` option on the command-line.
217
218 * Added a new `text` function. When called inside an action, it returns the
219 text matched by action's expression.
220 [[#131](https://github.com/dmajda/pegjs/issues/131)]
221
222 * Added a new `$` operator. It extracts matched strings from expressions.
223
224 * The `?` operator now returns `null` on unsuccessful match.
225
226 * Predicates now always return `undefined`.
227
228 * Replaced the `startRule` parameter of the `parse` method in generated
229 parsers with more generic `options` parameter. The start rule can now be
230 specified as the `startRule` option. The `options` parameter can be also
231 used to pass custom options to the parser because it is visible as the
232 `options` variable inside parser code.
233 [[#37](https://github.com/dmajda/pegjs/issues/37)]
234
235 * The list of allowed start rules of a generated parser now has to be
236 specified explicitly using the `allowedStartRules` option of the
237 `PEG.buildParser` method or the `--allowed-start-rule` option on the
238 command-line. This will make certain optimizations like rule inlining easier
239 in the future.
240
241 * Removed the `toSource` method of generated parsers and introduced a new
242 `output` option of the `PEG.buildParser` method. It allows callers to
243 specify whether they want to get back the parser object or its source code.
244
245 * The source code is now a valid npm package. This makes using development
246 versions easier.
247 [[#32](https://github.com/dmajda/pegjs/issues/32)]
248
249 * Generated parsers are now ~25% faster and ~62%/~3% smaller (when optimized
250 for size/speed) than those generated by 0.7.0.
251
252 * Requires Node.js 0.8.0+.
253
254 ### Small Changes
255
256 * `bin/pegjs` now outputs just the parser source if the value of the
257 `--export-var` option is empty. This makes embedding generated parsers into
258 other files easier.
259 [[#143](https://github.com/dmajda/pegjs/issues/143)]
260
261 * Changed the value of the `name` property of `PEG.GrammarError` instances
262 from “PEG.GrammarError” to just “GrammarError”. This better reflects the
263 fact that PEG.js can get required with different variable name than `PEG`.
264
265 * Setup prototype chain for `PEG.GrammarError` correctly.
266
267 * Setup prototype chain for `SyntaxError` in generated parsers correctly.
268
269 * Fixed error messages in certain cases with trailing input
270 [[#119](https://github.com/dmajda/pegjs/issues/119)]
271
272 * Fixed code generated for classes starting with `\^`.
273 [[#125](https://github.com/dmajda/pegjs/issues/125)]
274
275 * Fixed too eager proxy rules removal.
276 [[#137](https://github.com/dmajda/pegjs/issues/137)]
277
278 * Added a license to all vendored libraries.
279 [[#207](https://github.com/dmajda/pegjs/issues/207)]
280
281 * Converted the test suite from QUnit to Jasmine, cleaning it up on the way.
282
283 * Travis CI integration.
284
285 * Various internal code improvements and fixes.
286
287 * Various generated code improvements and fixes.
288
289 * Various example grammar improvements and fixes.
290
291 * Improved `README.md`.
292
293 * Converted `CHANGELOG` to Markdown.
294
295 0.7.0
296 -----
297
298 Released: April 18, 2012
299
300 ### Big Changes
301
302 * Added ability to pass options to `PEG.buildParser`.
303
304 * Implemented the `trackLineAndColumn` option for `PEG.buildParser` (together
305 with the `--track-line-and-column` command-line option). It makes the
306 generated parser track line and column during parsing. These are made
307 available inside actions and predicates as `line` and `column` variables.
308
309 * Implemented the `cache` option for `PEG.buildParser` (together with the
310 `--cache` command-line option). This option enables/disables the results
311 cache in generated parsers, resulting in dramatic speedup when the cache is
312 disabled (the default now). The cost is breaking the linear parsing time
313 guarantee.
314
315 * The current parse position is visible inside actions and predicates as the
316 `offset` variable.
317
318 * Exceptions thrown by the parser have `offset`, `expected` and `found`
319 properties containing machine-readable information about the parse failure
320 (based on a patch by Marcin Stefaniuk).
321
322 * Semantic predicates have access to preceding labels.
323 [[GH-69](https://github.com/dmajda/pegjs/issues/69)]
324
325 * Implemented case-insensitive literal and class matching.
326 [[GH-34](https://github.com/dmajda/pegjs/issues/34)]
327
328 * Rewrote the code generator — split some computations into separate passes
329 and based it on a proper templating system (Codie).
330
331 * Rewrote variable handling in generated parsers in a stack-like fashion,
332 simplifying the code and making the parsers smaller and faster.
333
334 * Adapted to Node.js 0.6.6+ (no longer supported in older versions).
335
336 * Dropped support for IE < 8.
337
338 * As a result of several optimizations, parsers generated by 0.7.0 are ~6.4
339 times faster and ~19% smaller than those generated by 0.6.2 (as reported by
340 `/tools/impact`).
341
342 ### Small Changes
343
344 * Fixed reported error position when part of the input is not consumed.
345 [[GH-48](https://github.com/dmajda/pegjs/issues/48)]
346
347 * Fixed incorrect disjunction operator in `computeErrorPosition` (original
348 patch by Wolfgang Kluge).
349
350 * Fixed regexp for detecting command-line options in `/bin/pegjs`.
351 [[GH-51](https://github.com/dmajda/pegjs/issues/51)]
352
353 * Generate more efficient code for empty literals (original patch by Wolfgang
354 Kluge).
355
356 * Fixed comment typos (patches by Wolfgang Kluge and Jason Davies).
357 [[GH-59](https://github.com/dmajda/pegjs/issues/59)]
358
359 * Fixed a typo in JavaScript example grammar.
360 [[GH-62](https://github.com/dmajda/pegjs/issues/62)]
361
362 * Made copy & paste inclusion of the PEG.js library into another code easier
363 by changing how the library is exported.
364
365 * Improved the copyright comment and the “Generated by...” header.
366
367 * Replaced `Jakefile` with `Makefile`.
368
369 * Added `make hint` task that checks all JavaScript files using JSHint and
370 resolved all issues it reported. All JavaScript files and also generated
371 parsers are JSHint-clean now.
372
373 * Fixed output printed during test failures (expected value was being printed
374 instead of the actual one). Original patch by Wolfgang Kluge.
375
376 * Added a `/tools/impact` script to measure speed and size impact of commits.
377
378 * Various generated code improvements and fixes.
379
380 * Various internal code improvements and fixes.
381
382 * Improved `README.md`.
383
384 0.6.2
385 -----
386
387 Released: August 20, 2011
388
389 ### Small Changes
390
391 * Reset parser position when action returns `null`.
392
393 * Fixed typo in JavaScript example grammar.
394
395 0.6.1
396 -----
397
398 Released: April 14, 2011
399
400 ### Small Changes
401
402 * Use `--ascii` option when generating a minified version.
403
404 0.6.0
405 -----
406
407 Released: April 14, 2011
408
409 ### Big Changes
410
411 * Rewrote the command-line mode to be based on Node.js instead of Rhino — no
412 more Java dependency. This also means that PEG.js is available as a Node.js
413 package and can be required as a module.
414
415 * Version for the browser is built separately from the command-line one in two
416 flavors (normal and minified).
417
418 * Parser variable name is no longer required argument of `bin/pegjs` — it is
419 `module.exports` by default and can be set using the `-e`/`--export-var`
420 option. This makes parsers generated by `/bin/pegjs` Node.js modules by
421 default.
422
423 * Added ability to start parsing from any grammar rule.
424
425 * Added several compiler optimizations — 0.6 is ~12% faster than 0.5.1 in the
426 benchmark on V8.
427
428 ### Small Changes
429
430 * Split the source code into multiple files combined together using a build
431 system.
432
433 * Jake is now used instead of Rake for build scripts — no more Ruby
434 dependency.
435
436 * Test suite can be run from the command-line.
437
438 * Benchmark suite can be run from the command-line.
439
440 * Benchmark browser runner improvements (users can specify number of runs,
441 benchmarks are run using `setTimeout`, table is centered and fixed-width).
442
443 * Added PEG.js version to “Generated by...” line in generated parsers.
444
445 * Added PEG.js version information and homepage header to `peg.js`.
446
447 * Generated code improvements and fixes.
448
449 * Internal code improvements and fixes.
450
451 * Rewrote `README.md`.
452
453 0.5.1
454 -----
455
456 Released: November 28, 2010
457
458 ### Small Changes
459
460 * Fixed a problem where “SyntaxError: Invalid range in character class.” error
461 appeared when using command-line version on Widnows
462 ([GH-13](https://github.com/dmajda/pegjs/issues/13)).
463
464 * Fixed wrong version reported by `bin/pegjs --version`.
465
466 * Removed two unused variables in the code.
467
468 * Fixed incorrect variable name on two places.
469
470 0.5
471 ---
472
473 Released: June 10, 2010
474
475 ### Big Changes
476
477 * Syntax change: Use labeled expressions and variables instead of `$1`, `$2`,
478 etc.
479
480 * Syntax change: Replaced `:` after a rule name with `=`.
481
482 * Syntax change: Allow trailing semicolon (`;`) for rules
483
484 * Semantic change: Start rule of the grammar is now implicitly its first rule.
485
486 * Implemented semantic predicates.
487
488 * Implemented initializers.
489
490 * Removed ability to change the start rule when generating the parser.
491
492 * Added several compiler optimizations — 0.5 is ~11% faster than 0.4 in the
493 benchmark on V8.
494
495 ### Small Changes
496
497 * `PEG.buildParser` now accepts grammars only in string format.
498
499 * Added “Generated by ...” message to the generated parsers.
500
501 * Formatted all grammars more consistently and transparently.
502
503 * Added notes about ECMA-262, 5th ed. compatibility to the JSON example
504 grammar.
505
506 * Guarded against redefinition of `undefined`.
507
508 * Made `bin/pegjs` work when called via a symlink
509 ([issue #1](https://github.com/dmajda/pegjs/issues/1)).
510
511 * Fixed bug causing incorrect error messages
512 ([issue #2](https://github.com/dmajda/pegjs/issues/2)).
513
514 * Fixed error message for invalid character range.
515
516 * Fixed string literal parsing in the JavaScript grammar.
517
518 * Generated code improvements and fixes.
519
520 * Internal code improvements and fixes.
521
522 * Improved `README.md`.
523
524 0.4
525 ---
526
527 Released: April 17, 2010
528
529 ### Big Changes
530
531 * Improved IE compatibility — IE6+ is now fully supported.
532
533 * Generated parsers are now standalone (no runtime is required).
534
535 * Added example grammars for JavaScript, CSS and JSON.
536
537 * Added a benchmark suite.
538
539 * Implemented negative character classes (e.g. `[^a-z]`).
540
541 * Project moved from BitBucket to GitHub.
542
543 ### Small Changes
544
545 * Code generated for the character classes is now regexp-based (= simpler and
546 more scalable).
547
548 * Added `\uFEFF` (BOM) to the definition of whitespace in the metagrammar.
549
550 * When building a parser, left-recursive rules (both direct and indirect) are
551 reported as errors.
552
553 * When building a parser, missing rules are reported as errors.
554
555 * Expected items in the error messages do not contain duplicates and they are
556 sorted.
557
558 * Fixed several bugs in the example arithmetics grammar.
559
560 * Converted `README` to GitHub Flavored Markdown and improved it.
561
562 * Added `CHANGELOG`.
563
564 * Internal code improvements.
565
566 0.3
567 ---
568
569 Released: March 14, 2010
570
571 * Wrote `README`.
572
573 * Bootstrapped the grammar parser.
574
575 * Metagrammar recognizes JavaScript-like comments.
576
577 * Changed standard grammar extension from `.peg` to `.pegjs` (it is more
578 specific).
579
580 * Simplified the example arithmetics grammar + added comment.
581
582 * Fixed a bug with reporting of invalid ranges such as `[b-a]` in the
583 metagrammar.
584
585 * Fixed `--start` vs. `--start-rule` inconsistency between help and actual
586 option processing code.
587
588 * Avoided ugliness in QUnit output.
589
590 * Fixed typo in help: `parserVar` → `parser_var`.
591
592 * Internal code improvements.
593
594 0.2.1
595 -----
596
597 Released: March 8, 2010
598
599 * Added `pegjs-` prefix to the name of the minified runtime file.
600
601 0.2
602 ---
603
604 Released: March 8, 2010
605
606 * Added `Rakefile` that builds minified runtime using Google Closure Compiler
607 API.
608
609 * Removed trailing commas in object initializers (Google Closure does not like
610 them).
611
612 0.1
613 ---
614
615 Released: March 8, 2010
616
617 * Initial release.
0 # Contribution Guidelines
1
2 The best way to contribute to PEG.js is by using it and giving back useful
3 feedback — reporting discovered bugs or requesting missing features.
4
5 You can also contribute code, but be advised that many patches end up being
6 rejected, usually because the change doesn’t fit the project or because of
7 various implementation issues. In almost all cases it’s best to get in touch
8 first before sending a patch.
9
10 ## Reporting Bugs
11
12 Report bugs using [GitHub issues][issues]. Before submitting a bug report,
13 please [search existing reports][issues-search-bugs] to see if the bug wasn’t
14 reported already.
15
16 In the report, please describe:
17
18 * Steps to reproduce the problem
19 * Expected result(s)
20 * Actual result(s)
21
22 In most cases, it’s also useful to include a **minimal** example (grammar +
23 input) reproducing the problem.
24
25 ## Requesting Features
26
27 Request features using [GitHub issues][issues]. Before submitting a feature
28 request, please [search existing requests][issues-search-enhancements] to see if
29 the feature wasn’t requested already.
30
31 In the request, please describe:
32
33 * How the feature should work
34 * Use case(s) behind it
35
36 ## Contributing Code
37
38 Contribute code using [GitHub pull requests][pulls]. For non-trivial changes,
39 first file a corresponding bug report or feature request. This will ensure the
40 *problem* is separated from a *solution*.
41
42 Split your change into atomic commits with descriptive messages adhering to
43 [these conventions][git-commit-messages]. Have a look in the commit history to
44 see good examples.
45
46 When appropriate, add documentation and tests.
47
48 Before submitting, make sure your change passes the specs (`make spec`) and
49 ESLint checks (`make lint`).
50
51 [issues]: https://github.com/pegjs/pegjs/issues
52 [issues-search-bugs]: https://github.com/pegjs/pegjs/issues?q=is%3Aopen+is%3Aissue+label%3ABug
53 [issues-search-enhancements]: https://github.com/pegjs/pegjs/issues?q=is%3Aopen+is%3Aissue+label%3AEnhancement
54 [pulls]: https://github.com/pegjs/pegjs/pulls
55 [git-commit-messages]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
0 Copyright (c) 2010-2012 David Majda
0 Copyright (c) 2010-2016 David Majda
11
22 Permission is hereby granted, free of charge, to any person
33 obtaining a copy of this software and associated documentation
0 # ===== Directories =====
1
2 SRC_DIR = src
3 BIN_DIR = bin
4 TEST_DIR = test
5 BENCHMARK_DIR = benchmark
6 EXAMPLES_DIR = examples
7 LIB_DIR = lib
8 DIST_DIR = dist
9 DIST_WEB_DIR = $(DIST_DIR)/web
10 DIST_NODE_DIR = $(DIST_DIR)/node
11
12 # ===== Files =====
13
14 PARSER_SRC_FILE = $(SRC_DIR)/parser.pegjs
15 PARSER_OUT_FILE = $(SRC_DIR)/parser.js
16
17 PEGJS_SRC_FILE = $(SRC_DIR)/peg.js
18 PEGJS_LIB_FILE = $(LIB_DIR)/peg.js
19
20 PACKAGE_JSON_SRC_FILE = package.json
21 PACKAGE_JSON_DIST_FILE = $(DIST_NODE_DIR)/package.json
22
23 PEGJS_DIST_FILE_DEV = $(DIST_WEB_DIR)/peg-$(PEGJS_VERSION).js
24 PEGJS_DIST_FILE_MIN = $(DIST_WEB_DIR)/peg-$(PEGJS_VERSION).min.js
25
26 CHANGELOG_FILE = CHANGELOG
27 LICENSE_FILE = LICENSE
28 README_FILE = README.md
29 VERSION_FILE = VERSION
30
31 # ===== Executables =====
32
33 JSHINT ?= jshint
34 UGLIFYJS ?= uglifyjs
35 PEGJS = $(BIN_DIR)/pegjs
36 TEST_RUN = $(TEST_DIR)/run
37 BENCHMARK_RUN = $(BENCHMARK_DIR)/run
38
390 # ===== Variables =====
401
412 PEGJS_VERSION = `cat $(VERSION_FILE)`
423
43 DIST_NAME = pegjs
44 DIST_VERSION = $(PEGJS_VERSION)
45 DIST_BASE = $(DIST_NAME)-$(DIST_VERSION)
4 # ===== Directories =====
465
47 # ===== Preprocessor =====
6 SRC_DIR = src
7 LIB_DIR = lib
8 BIN_DIR = bin
9 BROWSER_DIR = browser
10 SPEC_DIR = spec
11 BENCHMARK_DIR = benchmark
12 NODE_MODULES_DIR = node_modules
13 NODE_MODULES_BIN_DIR = $(NODE_MODULES_DIR)/.bin
4814
49 # A simple preprocessor that recognizes two directives:
50 #
51 # @VERSION -- insert PEG.js version
52 # @include "<file>" -- include <file> here
53 #
54 # This could have been implemented many ways. I chose Perl because everyone will
55 # have it.
56 PREPROCESS=perl -e ' \
57 use strict; \
58 use warnings; \
59 \
60 use File::Basename; \
61 \
62 open(my $$f, "$(VERSION_FILE)") or die "Can\x27t open $(VERSION_FILE): $$!"; \
63 my $$PEGJS_VERSION = <$$f>; \
64 close($$f); \
65 chomp($$PEGJS_VERSION); \
66 \
67 sub preprocess { \
68 my $$file = shift; \
69 my $$output = ""; \
70 \
71 open(my $$f, $$file) or die "Can\x27t open $$file: $$!"; \
72 while(<$$f>) { \
73 s/\@VERSION/$$PEGJS_VERSION/g; \
74 \
75 if (/^\s*\/\/\s*\@include\s*"([^"]*)"\s*$$/) { \
76 $$output .= preprocess(dirname($$file) . "/" . $$1); \
77 next; \
78 } \
79 \
80 $$output .= $$_; \
81 } \
82 close($$f); \
83 \
84 return $$output; \
85 } \
86 \
87 print preprocess($$ARGV[0]); \
88 '
15 # ===== Files =====
16
17 MAIN_FILE = $(LIB_DIR)/peg.js
18
19 PARSER_SRC_FILE = $(SRC_DIR)/parser.pegjs
20 PARSER_OUT_FILE = $(LIB_DIR)/parser.js
21 PARSER_OUT_FILE_NEW = $(LIB_DIR)/parser.js.new
22
23 BROWSER_FILE_DEV = $(BROWSER_DIR)/peg-$(PEGJS_VERSION).js
24 BROWSER_FILE_MIN = $(BROWSER_DIR)/peg-$(PEGJS_VERSION).min.js
25
26 VERSION_FILE = VERSION
27
28 # ===== Executables =====
29
30 ESLINT = $(NODE_MODULES_BIN_DIR)/eslint
31 BROWSERIFY = $(NODE_MODULES_BIN_DIR)/browserify
32 UGLIFYJS = $(NODE_MODULES_BIN_DIR)/uglifyjs
33 JASMINE_NODE = $(NODE_MODULES_BIN_DIR)/jasmine-node
34 PEGJS = $(BIN_DIR)/pegjs
35 BENCHMARK_RUN = $(BENCHMARK_DIR)/run
8936
9037 # ===== Targets =====
9138
39 # Default target
40 all: browser
41
9242 # Generate the grammar parser
9343 parser:
94 $(PEGJS) --export-var PEG.parser $(PARSER_SRC_FILE) $(PARSER_OUT_FILE)
44 # We need to prepend ESLint header to the generated parser file because we
45 # don't want the various unused variables there to get reported. This is a bit
46 # tricky because the file is used when generating its own new version, which
47 # means we can't start writing the header there until we call $(PEGJS).
9548
96 # Build the PEG.js library
97 build:
98 mkdir -p $(LIB_DIR)
99 $(PREPROCESS) $(PEGJS_SRC_FILE) > $(PEGJS_LIB_FILE)
49 $(PEGJS) -o $(PARSER_OUT_FILE_NEW) $(PARSER_SRC_FILE)
10050
101 # Remove built PEG.js library (created by "build")
102 clean:
103 rm -rf $(LIB_DIR)
51 rm -f $(PARSER_OUT_FILE)
10452
105 # Prepare dstribution files
106 dist: build
107 # Web
108 mkdir -p $(DIST_WEB_DIR)
109 cp $(PEGJS_LIB_FILE) $(PEGJS_DIST_FILE_DEV)
110 $(UGLIFYJS) --ascii -o $(PEGJS_DIST_FILE_MIN) $(PEGJS_LIB_FILE)
53 echo '/* eslint-env node, amd */' >> $(PARSER_OUT_FILE)
54 echo '/* eslint no-unused-vars: 0 */' >> $(PARSER_OUT_FILE)
55 echo >> $(PARSER_OUT_FILE)
56 cat $(PARSER_OUT_FILE_NEW) >> $(PARSER_OUT_FILE)
11157
112 # Node.js
113 mkdir -p $(DIST_NODE_DIR)
114 cp -r \
115 $(LIB_DIR) \
116 $(BIN_DIR) \
117 $(EXAMPLES_DIR) \
118 $(CHANGELOG_FILE) \
119 $(LICENSE_FILE) \
120 $(README_FILE) \
121 $(VERSION_FILE) \
122 $(DIST_NODE_DIR)
123 $(PREPROCESS) $(PACKAGE_JSON_SRC_FILE) > $(PACKAGE_JSON_DIST_FILE)
58 rm $(PARSER_OUT_FILE_NEW)
12459
125 # Remove distribution file (created by "dist")
126 distclean:
127 rm -rf $(DIST_DIR)
60 # Build the browser version of the library
61 browser:
62 mkdir -p $(BROWSER_DIR)
12863
129 # Run the test suite
130 test: build
131 $(TEST_RUN)
64 rm -f $(BROWSER_FILE_DEV)
65 rm -f $(BROWSER_FILE_MIN)
66
67 echo '/*' >> $(BROWSER_FILE_DEV)
68 echo " * PEG.js $(PEGJS_VERSION)" >> $(BROWSER_FILE_DEV)
69 echo ' *' >> $(BROWSER_FILE_DEV)
70 echo ' * http://pegjs.org/' >> $(BROWSER_FILE_DEV)
71 echo ' *' >> $(BROWSER_FILE_DEV)
72 echo ' * Copyright (c) 2010-2016 David Majda' >> $(BROWSER_FILE_DEV)
73 echo ' * Licensed under the MIT license.' >> $(BROWSER_FILE_DEV)
74 echo ' */' >> $(BROWSER_FILE_DEV)
75
76 $(BROWSERIFY) --standalone peg $(MAIN_FILE) >> $(BROWSER_FILE_DEV)
77
78 $(UGLIFYJS) \
79 --mangle \
80 --compress warnings=false \
81 --comments /Copyright/ \
82 -o $(BROWSER_FILE_MIN) \
83 $(BROWSER_FILE_DEV)
84
85 # Remove browser version of the library (created by "browser")
86 browserclean:
87 rm -rf $(BROWSER_DIR)
88
89 # Run the spec suite
90 spec:
91 $(JASMINE_NODE) --verbose $(SPEC_DIR)
13292
13393 # Run the benchmark suite
134 benchmark: build
94 benchmark:
13595 $(BENCHMARK_RUN)
13696
137 # Run JSHint on the source
138 hint: build
139 $(JSHINT) \
140 $(SRC_DIR)/*.js \
141 $(TEST_DIR)/*.js \
142 $(TEST_RUN) \
143 $(BENCHMARK_DIR)/*.js \
144 $(BENCHMARK_RUN) \
97 # Run ESLint on the source
98 lint:
99 $(ESLINT) \
100 `find $(LIB_DIR) -name '*.js'` \
101 `find $(SPEC_DIR) -name '*.js' -and -not -path '$(SPEC_DIR)/vendor/*'` \
102 $(BENCHMARK_DIR)/*.js \
103 $(BENCHMARK_RUN) \
145104 $(PEGJS)
146105
147 # Make a distribution tarball for packaging
148 # Note: we don't currently include the benchmark tree in the dist tarball
149 # because it contains non-human-readable jQuery artifacts and this can
150 # be an impediment to distribution in free software archives such as
151 # Debian and Fedora.
152 # Run the benchmark from git if required.
153 srcdist:
154 -rm -rf $(DIST_BASE)
155 mkdir $(DIST_BASE)
156 cp -r bin CHANGELOG examples lib LICENSE Makefile package.json README.md src test tools VERSION $(DIST_BASE)
157 tar czf $(DIST_BASE).tar.gz $(DIST_BASE)
158
159
160 .PHONY: test benchmark hint parser build clean dist distclean
161 .SILENT: test benchmark hint parser build clean dist distclean
106 .PHONY: all parser browser browserclean spec benchmark lint
107 .SILENT: all parser browser browserclean spec benchmark lint
0 [![Build status](https://img.shields.io/travis/pegjs/pegjs.svg)](https://travis-ci.org/pegjs/pegjs)
1 [![npm version](https://img.shields.io/npm/v/pegjs.svg)](https://www.npmjs.com/package/pegjs)
2 [![Bower version](https://img.shields.io/bower/v/pegjs.svg)](https://github.com/pegjs/bower)
3 [![License](https://img.shields.io/badge/license-mit-blue.svg)](https://opensource.org/licenses/MIT)
4
05 PEG.js
16 ======
27
3 PEG.js is a simple parser generator for JavaScript that produces fast parsers with excellent error reporting. You can use it to process complex data or computer languages and build transformers, interpreters, compilers and other tools easily.
8 PEG.js is a simple parser generator for JavaScript that produces fast parsers
9 with excellent error reporting. You can use it to process complex data or
10 computer languages and build transformers, interpreters, compilers and other
11 tools easily.
412
513 Features
614 --------
816 * Simple and expressive grammar syntax
917 * Integrates both lexical and syntactical analysis
1018 * Parsers have excellent error reporting out of the box
11 * Based on [parsing expression grammar](http://en.wikipedia.org/wiki/Parsing_expression_grammar) formalism — more powerful than traditional LL(*k*) and LR(*k*) parsers
12 * Usable [from your browser](http://pegjs.majda.cz/online), from the command line, or via JavaScript API
19 * Based on [parsing expression
20 grammar](http://en.wikipedia.org/wiki/Parsing_expression_grammar) formalism
21 — more powerful than traditional LL(*k*) and LR(*k*) parsers
22 * Usable [from your browser](http://pegjs.org/online), from the command line,
23 or via JavaScript API
1324
1425 Getting Started
1526 ---------------
1627
17 [Online version](http://pegjs.majda.cz/online) is the easiest way to generate a parser. Just enter your grammar, try parsing few inputs, and download generated parser code.
28 [Online version](http://pegjs.org/online) is the easiest way to generate a
29 parser. Just enter your grammar, try parsing few inputs, and download generated
30 parser code.
1831
1932 Installation
2033 ------------
2336
2437 To use the `pegjs` command, install PEG.js globally:
2538
26 $ npm install -g pegjs
39 ```console
40 $ npm install -g pegjs
41 ```
2742
2843 To use the JavaScript API, install PEG.js locally:
2944
30 $ npm install pegjs
31
32 If you need both the `pegjs` command and the JavaScript API, install PEG.js both ways.
45 ```console
46 $ npm install pegjs
47 ```
48
49 If you need both the `pegjs` command and the JavaScript API, install PEG.js both
50 ways.
3351
3452 ### Browser
3553
36 [Download](http://pegjs.majda.cz/#download) the PEG.js library (regular or minified version).
54 [Download](http://pegjs.org/#download) the PEG.js library (regular or minified
55 version) or install it using Bower:
56
57 ```console
58 $ bower install pegjs
59 ```
3760
3861 Generating a Parser
3962 -------------------
4063
41 PEG.js generates parser from a grammar that describes expected input and can specify what the parser returns (using semantic actions on matched parts of the input). Generated parser itself is a JavaScript object with a simple API.
64 PEG.js generates parser from a grammar that describes expected input and can
65 specify what the parser returns (using semantic actions on matched parts of the
66 input). Generated parser itself is a JavaScript object with a simple API.
4267
4368 ### Command Line
4469
4570 To generate a parser from your grammar, use the `pegjs` command:
4671
47 $ pegjs arithmetics.pegjs
48
49 This writes parser source code into a file with the same name as the grammar file but with “.js” extension. You can also specify the output file explicitly:
50
51 $ pegjs arithmetics.pegjs arithmetics-parser.js
52
53 If you omit both input and ouptut file, standard input and output are used.
54
55 By default, the parser object is assigned to `module.exports`, which makes the output a Node.js module. You can assign it to another variable by passing a variable name using the `-e`/`--export-var` option. This may be helpful if you want to use the parser in browser environment.
56
57 You can tweak the generated parser with two options:
58
59 * `--cache` — makes the parser cache results, avoiding exponential parsing time in pathological cases but making the parser slower
60 * `--track-line-and-column` — makes the parser track line and column (available as `line` and `column` variables in the actions and predicates)
72 ```console
73 $ pegjs arithmetics.pegjs
74 ```
75
76 This writes parser source code into a file with the same name as the grammar
77 file but with “.js” extension. You can also specify the output file explicitly:
78
79 ```console
80 $ pegjs -o arithmetics-parser.js arithmetics.pegjs
81 ```
82
83 If you omit both input and output file, standard input and output are used.
84
85 By default, the generated parser is in the Node.js module format. You can
86 override this using the `--format` option.
87
88 You can tweak the generated parser with several options:
89
90 * `--allowed-start-rules` — comma-separated list of rules the parser will be
91 allowed to start parsing from (default: the first rule in the grammar)
92 * `--cache` — makes the parser cache results, avoiding exponential parsing
93 time in pathological cases but making the parser slower
94 * `--dependency` — makes the parser require a specified dependency (can be
95 specified multiple times)
96 * `--export-var` — name of a global variable into which the parser object is
97 assigned to when no module loader is detected
98 * `--extra-options` — additional options (in JSON format) to pass to
99 `peg.generate`
100 * `--extra-options-file` — file with additional options (in JSON format) to
101 pass to `peg.generate`
102 * `--format` — format of the generated parser: `amd`, `commonjs`, `globals`,
103 `umd` (default: `commonjs`)
104 * `--optimize` — selects between optimizing the generated parser for parsing
105 speed (`speed`) or code size (`size`) (default: `speed`)
106 * `--plugin` — makes PEG.js use a specified plugin (can be specified multiple
107 times)
108 * `--trace` — makes the parser trace its progress
61109
62110 ### JavaScript API
63111
64112 In Node.js, require the PEG.js parser generator module:
65113
66 var PEG = require("pegjs");
67
68 In browser, include the PEG.js library in your web page or application using the `<script>` tag. The API will be available in the `PEG` global object.
69
70 To generate a parser, call the `PEG.buildParser` method and pass your grammar as a parameter:
71
72 var parser = PEG.buildParser("start = ('a' / 'b')+");
73
74 The method will return generated parser object or throw an exception if the grammar is invalid. The exception will contain `message` property with more details about the error.
75
76 To get parser’s source code, call the `toSource` method on the parser.
77
78 You can tweak the generated parser by passing a second parameter with an options object to `PEG.buildParser`. The following options are supported:
79
80 * `cache` — if `true`, makes the parser cache results, avoiding exponential parsing time in pathological cases but making the parser slower (default: `false`)
81 * `trackLineAndColumn` — if `true`, makes the parser track line and column (available as `line` and `column` variables in the actions and predicates) (default: `false`)
114 ```javascript
115 var peg = require("pegjs");
116 ```
117
118 In browser, include the PEG.js library in your web page or application using the
119 `<script>` tag. If PEG.js detects an AMD loader, it will define itself as a
120 module, otherwise the API will be available in the `peg` global object.
121
122 To generate a parser, call the `peg.generate` method and pass your grammar as a
123 parameter:
124
125 ```javascript
126 var parser = peg.generate("start = ('a' / 'b')+");
127 ```
128
129 The method will return generated parser object or its source code as a string
130 (depending on the value of the `output` option — see below). It will throw an
131 exception if the grammar is invalid. The exception will contain `message`
132 property with more details about the error.
133
134 You can tweak the generated parser by passing a second parameter with an options
135 object to `peg.generate`. The following options are supported:
136
137 * `allowedStartRules` — rules the parser will be allowed to start parsing from
138 (default: the first rule in the grammar)
139 * `cache` — if `true`, makes the parser cache results, avoiding exponential
140 parsing time in pathological cases but making the parser slower (default:
141 `false`)
142 * `dependencies` — parser dependencies, the value is an object which maps
143 variables used to access the dependencies in the parser to module IDs used
144 to load them; valid only when `format` is set to `"amd"`, `"commonjs"`, or
145 `"umd"` (default: `{}`)
146 * `exportVar` — name of a global variable into which the parser object is
147 assigned to when no module loader is detected; valid only when `format` is
148 set to `"globals"` or `"umd"` (default: `null`)
149 * `format` — format of the genreated parser (`"amd"`, `"bare"`, `"commonjs"`,
150 `"globals"`, or `"umd"`); valid only when `output` is set to `"source"`
151 (default: `"bare"`)
152 * `optimize`— selects between optimizing the generated parser for parsing
153 speed (`"speed"`) or code size (`"size"`) (default: `"speed"`)
154 * `output` — if set to `"parser"`, the method will return generated parser
155 object; if set to `"source"`, it will return parser source code as a string
156 (default: `"parser"`)
157 * `plugins` — plugins to use
158 * `trace` — makes the parser trace its progress (default: `false`)
82159
83160 Using the Parser
84161 ----------------
85162
86 Using the generated parser is simple — just call its `parse` method and pass an input string as a parameter. The method will return a parse result (the exact value depends on the grammar used to build the parser) or throw an exception if the input is invalid. The exception will contain `offset`, `line`, `column`, `expected`, `found` and `message` properties with more details about the error.
87
88 parser.parse("abba"); // returns ["a", "b", "b", "a"]
89
90 parser.parse("abcd"); // throws an exception
91
92 You can also start parsing from a specific rule in the grammar. Just pass the rule name to the `parse` method as a second parameter.
163 Using the generated parser is simple — just call its `parse` method and pass an
164 input string as a parameter. The method will return a parse result (the exact
165 value depends on the grammar used to generate the parser) or throw an exception
166 if the input is invalid. The exception will contain `location`, `expected`,
167 `found`, and `message` properties with more details about the error.
168
169 ```javascript
170 parser.parse("abba"); // returns ["a", "b", "b", "a"]
171
172 parser.parse("abcd"); // throws an exception
173 ```
174
175 You can tweak parser behavior by passing a second parameter with an options
176 object to the `parse` method. The following options are supported:
177
178 * `startRule` — name of the rule to start parsing from
179 * `tracer` — tracer to use
180
181 Parsers can also support their own custom options.
93182
94183 Grammar Syntax and Semantics
95184 ----------------------------
96185
97 The grammar syntax is similar to JavaScript in that it is not line-oriented and ignores whitespace between tokens. You can also use JavaScript-style comments (`// ...` and `/* ... */`).
98
99 Let's look at example grammar that recognizes simple arithmetic expressions like `2*(3+4)`. A parser generated from this grammar computes their values.
100
101 start
102 = additive
103
104 additive
105 = left:multiplicative "+" right:additive { return left + right; }
106 / multiplicative
107
108 multiplicative
109 = left:primary "*" right:multiplicative { return left * right; }
110 / primary
111
112 primary
113 = integer
114 / "(" additive:additive ")" { return additive; }
115
116 integer "integer"
117 = digits:[0-9]+ { return parseInt(digits.join(""), 10); }
118
119 On the top level, the grammar consists of *rules* (in our example, there are five of them). Each rule has a *name* (e.g. `integer`) that identifies the rule, and a *parsing expression* (e.g. `digits:[0-9]+ { return parseInt(digits.join(""), 10); }`) that defines a pattern to match against the input text and possibly contains some JavaScript code that determines what happens when the pattern matches successfully. A rule can also contain *human-readable name* that is used in error messages (in our example, only the `integer` rule has a human-readable name). The parsing starts at the first rule, which is also called the *start rule*.
120
121 A rule name must be a JavaScript identifier. It is followed by an equality sign (“=”) and a parsing expression. If the rule has a human-readable name, it is written as a JavaScript string between the name and separating equality sign. Rules need to be separated only by whitespace (their beginning is easily recognizable), but a semicolon (“;”) after the parsing expression is allowed.
122
123 Rules can be preceded by an *initializer* — a piece of JavaScript code in curly braces (“{” and “}”). This code is executed before the generated parser starts parsing. All variables and functions defined in the initializer are accessible in rule actions and semantic predicates. Curly braces in the initializer code must be balanced.
124
125 The parsing expressions of the rules are used to match the input text to the grammar. There are various types of expressions — matching characters or character classes, indicating optional parts and repetition, etc. Expressions can also contain references to other rules. See detailed description below.
126
127 If an expression successfully matches a part of the text when running the generated parser, it produces a *match result*, which is a JavaScript value. For example:
128
129 * An expression matching a literal string produces a JavaScript string containing matched part of the input.
130 * An expression matching repeated occurrence of some subexpression produces a JavaScript array with all the matches.
131
132 The match results propagate through the rules when the rule names are used in expressions, up to the start rule. The generated parser returns start rule's match result when parsing is successful.
133
134 One special case of parser expression is a *parser action* — a piece of JavaScript code inside curly braces (“{” and “}”) that takes match results of some of the the preceding expressions and returns a JavaScript value. This value is considered match result of the preceding expression (in other words, the parser action is a match result transformer).
135
136 In our arithmetics example, there are many parser actions. Consider the action in expression `digits:[0-9]+ { return parseInt(digits.join(""), 10); }`. It takes the match result of the expression [0-9]+, which is an array of strings containing digits, as its parameter. It joins the digits together to form a number and converts it to a JavaScript `number` object.
186 The grammar syntax is similar to JavaScript in that it is not line-oriented and
187 ignores whitespace between tokens. You can also use JavaScript-style comments
188 (`// ...` and `/* ... */`).
189
190 Let's look at example grammar that recognizes simple arithmetic expressions like
191 `2*(3+4)`. A parser generated from this grammar computes their values.
192
193 ```pegjs
194 start
195 = additive
196
197 additive
198 = left:multiplicative "+" right:additive { return left + right; }
199 / multiplicative
200
201 multiplicative
202 = left:primary "*" right:multiplicative { return left * right; }
203 / primary
204
205 primary
206 = integer
207 / "(" additive:additive ")" { return additive; }
208
209 integer "integer"
210 = digits:[0-9]+ { return parseInt(digits.join(""), 10); }
211 ```
212
213 On the top level, the grammar consists of *rules* (in our example, there are
214 five of them). Each rule has a *name* (e.g. `integer`) that identifies the rule,
215 and a *parsing expression* (e.g. `digits:[0-9]+ { return
216 parseInt(digits.join(""), 10); }`) that defines a pattern to match against the
217 input text and possibly contains some JavaScript code that determines what
218 happens when the pattern matches successfully. A rule can also contain
219 *human-readable name* that is used in error messages (in our example, only the
220 `integer` rule has a human-readable name). The parsing starts at the first rule,
221 which is also called the *start rule*.
222
223 A rule name must be a JavaScript identifier. It is followed by an equality sign
224 (“=”) and a parsing expression. If the rule has a human-readable name, it is
225 written as a JavaScript string between the name and separating equality sign.
226 Rules need to be separated only by whitespace (their beginning is easily
227 recognizable), but a semicolon (“;”) after the parsing expression is allowed.
228
229 The first rule can be preceded by an *initializer* — a piece of JavaScript code
230 in curly braces (“{” and “}”). This code is executed before the generated parser
231 starts parsing. All variables and functions defined in the initializer are
232 accessible in rule actions and semantic predicates. The code inside the
233 initializer can access options passed to the parser using the `options`
234 variable. Curly braces in the initializer code must be balanced. Let's look at
235 the example grammar from above using a simple initializer.
236
237 ```pegjs
238 {
239 function makeInteger(o) {
240 return parseInt(o.join(""), 10);
241 }
242 }
243
244 start
245 = additive
246
247 additive
248 = left:multiplicative "+" right:additive { return left + right; }
249 / multiplicative
250
251 multiplicative
252 = left:primary "*" right:multiplicative { return left * right; }
253 / primary
254
255 primary
256 = integer
257 / "(" additive:additive ")" { return additive; }
258
259 integer "integer"
260 = digits:[0-9]+ { return makeInteger(digits); }
261 ```
262
263 The parsing expressions of the rules are used to match the input text to the
264 grammar. There are various types of expressions — matching characters or
265 character classes, indicating optional parts and repetition, etc. Expressions
266 can also contain references to other rules. See detailed description below.
267
268 If an expression successfully matches a part of the text when running the
269 generated parser, it produces a *match result*, which is a JavaScript value. For
270 example:
271
272 * An expression matching a literal string produces a JavaScript string
273 containing matched text.
274 * An expression matching repeated occurrence of some subexpression produces a
275 JavaScript array with all the matches.
276
277 The match results propagate through the rules when the rule names are used in
278 expressions, up to the start rule. The generated parser returns start rule's
279 match result when parsing is successful.
280
281 One special case of parser expression is a *parser action* — a piece of
282 JavaScript code inside curly braces (“{” and “}”) that takes match results of
283 some of the the preceding expressions and returns a JavaScript value. This value
284 is considered match result of the preceding expression (in other words, the
285 parser action is a match result transformer).
286
287 In our arithmetics example, there are many parser actions. Consider the action
288 in expression `digits:[0-9]+ { return parseInt(digits.join(""), 10); }`. It
289 takes the match result of the expression [0-9]+, which is an array of strings
290 containing digits, as its parameter. It joins the digits together to form a
291 number and converts it to a JavaScript `number` object.
137292
138293 ### Parsing Expression Types
139294
140 There are several types of parsing expressions, some of them containing subexpressions and thus forming a recursive structure:
295 There are several types of parsing expressions, some of them containing
296 subexpressions and thus forming a recursive structure:
141297
142298 #### "*literal*"<br>'*literal*'
143299
144 Match exact literal string and return it. The string syntax is the same as in JavaScript. Appending `i` right after the literal makes the match case-insensitive.
300 Match exact literal string and return it. The string syntax is the same as in
301 JavaScript. Appending `i` right after the literal makes the match
302 case-insensitive.
145303
146304 #### .
147305
149307
150308 #### [*characters*]
151309
152 Match one character from a set and return it as a string. The characters in the list can be escaped in exactly the same way as in JavaScript string. The list of characters can also contain ranges (e.g. `[a-z]` means “all lowercase letters”). Preceding the characters with `^` inverts the matched set (e.g. `[^a-z]` means “all character but lowercase letters”). Appending `i` right after the right bracket makes the match case-insensitive.
310 Match one character from a set and return it as a string. The characters in the
311 list can be escaped in exactly the same way as in JavaScript string. The list of
312 characters can also contain ranges (e.g. `[a-z]` means “all lowercase letters”).
313 Preceding the characters with `^` inverts the matched set (e.g. `[^a-z]` means
314 “all character but lowercase letters”). Appending `i` right after the right
315 bracket makes the match case-insensitive.
153316
154317 #### *rule*
155318
161324
162325 #### *expression* \*
163326
164 Match zero or more repetitions of the expression and return their match results in an array. The matching is greedy, i.e. the parser tries to match the expression as many times as possible.
327 Match zero or more repetitions of the expression and return their match results
328 in an array. The matching is greedy, i.e. the parser tries to match the
329 expression as many times as possible. Unlike in regular expressions, there is no
330 backtracking.
165331
166332 #### *expression* +
167333
168 Match one or more repetitions of the expression and return their match results in an array. The matching is greedy, i.e. the parser tries to match the expression as many times as possible.
334 Match one or more repetitions of the expression and return their match results
335 in an array. The matching is greedy, i.e. the parser tries to match the
336 expression as many times as possible. Unlike in regular expressions, there is no
337 backtracking.
169338
170339 #### *expression* ?
171340
172 Try to match the expression. If the match succeeds, return its match result, otherwise return an empty string.
341 Try to match the expression. If the match succeeds, return its match result,
342 otherwise return `null`. Unlike in regular expressions, there is no
343 backtracking.
173344
174345 #### & *expression*
175346
176 Try to match the expression. If the match succeeds, just return an empty string and do not advance the parser position, otherwise consider the match failed.
347 Try to match the expression. If the match succeeds, just return `undefined` and
348 do not consume any input, otherwise consider the match failed.
177349
178350 #### ! *expression*
179351
180 Try to match the expression and. If the match does not succeed, just return an empty string and do not advance the parser position, otherwise consider the match failed.
352 Try to match the expression. If the match does not succeed, just return
353 `undefined` and do not consume any input, otherwise consider the match failed.
181354
182355 #### & { *predicate* }
183356
184 The predicate is a piece of JavaScript code that is executed as if it was inside a function. It gets the match results of labeled expressions in preceding expression as its arguments. It should return some JavaScript value using the `return` statement. If the returned value evaluates to `true` in boolean context, just return an empty string and do not advance the parser position; otherwise consider the match failed.
185
186 The code inside the predicate can access all variables and functions defined in the initializer at the beginning of the grammar.
187
188 The code inside the predicate can also access the current parse position using the `offset` variable. It is a zero-based character index into the input string. If the `trackLineAndColumn` option was set to `true` when the parser was generated (or `--track-line-and-column` was used on the command line), the code can also access the current line and column using the `line` and `column` variables. Both are one-based indexes.
357 The predicate is a piece of JavaScript code that is executed as if it was inside
358 a function. It gets the match results of labeled expressions in preceding
359 expression as its arguments. It should return some JavaScript value using the
360 `return` statement. If the returned value evaluates to `true` in boolean
361 context, just return `undefined` and do not consume any input; otherwise
362 consider the match failed.
363
364 The code inside the predicate can access all variables and functions defined in
365 the initializer at the beginning of the grammar.
366
367 The code inside the predicate can also access location information using the
368 `location` function. It returns an object like this:
369
370 ```javascript
371 {
372 start: { offset: 23, line: 5, column: 6 },
373 end: { offset: 23, line: 5, column: 6 }
374 }
375 ```
376
377 The `start` and `end` properties both refer to the current parse position. The
378 `offset` property contains an offset as a zero-based index and `line` and
379 `column` properties contain a line and a column as one-based indices.
380
381 The code inside the predicate can also access options passed to the parser using
382 the `options` variable.
189383
190384 Note that curly braces in the predicate code must be balanced.
191385
192386 #### ! { *predicate* }
193387
194 The predicate is a piece of JavaScript code that is executed as if it was inside a function. It gets the match results of labeled expressions in preceding expression as its arguments. It should return some JavaScript value using the `return` statement. If the returned value evaluates to `false` in boolean context, just return an empty string and do not advance the parser position; otherwise consider the match failed.
195
196 The code inside the predicate can access all variables and functions defined in the initializer at the beginning of the grammar.
197
198 The code inside the predicate can also access the current parse position using the `offset` variable. It is a zero-based character index into the input string. If the `trackLineAndColumn` option was set to `true` when the parser was generated (or `--track-line-and-column` was used on the command line), the code can also access the current line and column using the `line` and `column` variables. Both are one-based indexes.
388 The predicate is a piece of JavaScript code that is executed as if it was inside
389 a function. It gets the match results of labeled expressions in preceding
390 expression as its arguments. It should return some JavaScript value using the
391 `return` statement. If the returned value evaluates to `false` in boolean
392 context, just return `undefined` and do not consume any input; otherwise
393 consider the match failed.
394
395 The code inside the predicate can access all variables and functions defined in
396 the initializer at the beginning of the grammar.
397
398 The code inside the predicate can also access location information using the
399 `location` function. It returns an object like this:
400
401 ```javascript
402 {
403 start: { offset: 23, line: 5, column: 6 },
404 end: { offset: 23, line: 5, column: 6 }
405 }
406 ```
407
408 The `start` and `end` properties both refer to the current parse position. The
409 `offset` property contains an offset as a zero-based index and `line` and
410 `column` properties contain a line and a column as one-based indices.
411
412 The code inside the predicate can also access options passed to the parser using
413 the `options` variable.
199414
200415 Note that curly braces in the predicate code must be balanced.
201416
417 #### $ *expression*
418
419 Try to match the expression. If the match succeeds, return the matched text
420 instead of the match result.
421
202422 #### *label* : *expression*
203423
204 Match the expression and remember its match result under given lablel. The label must be a JavaScript identifier.
205
206 Labeled expressions are useful together with actions, where saved match results can be accessed by action's JavaScript code.
207
208 #### *expression<sub>1</sub>* *expression<sub>2</sub>* ... *expression<sub>n</sub>*
424 Match the expression and remember its match result under given label. The label
425 must be a JavaScript identifier.
426
427 Labeled expressions are useful together with actions, where saved match results
428 can be accessed by action's JavaScript code.
429
430 #### *expression<sub>1</sub>* *expression<sub>2</sub>* ... *expression<sub>n</sub>*
209431
210432 Match a sequence of expressions and return their match results in an array.
211433
212434 #### *expression* { *action* }
213435
214 Match the expression. If the match is successful, run the action, otherwise consider the match failed.
215
216 The action is a piece of JavaScript code that is executed as if it was inside a function. It gets the match results of labeled expressions in preceding expression as its arguments. The action should return some JavaScript value using the `return` statement. This value is considered match result of the preceding expression. The action can return `null` to indicate a match failure.
217
218 The code inside the action can access all variables and functions defined in the initializer at the beginning of the grammar. Curly braces in the action code must be balanced.
219
220 The code inside the action can also access the parse position at the beginning of the action's expression using the `offset` variable. It is a zero-based character index into the input string. If the `trackLineAndColumn` option was set to `true` when the parser was generated (or `--track-line-and-column` was used on the command line), the code can also access the line and column at the beginning of the action's expression using the `line` and `column` variables. Both are one-based indexes.
436 Match the expression. If the match is successful, run the action, otherwise
437 consider the match failed.
438
439 The action is a piece of JavaScript code that is executed as if it was inside a
440 function. It gets the match results of labeled expressions in preceding
441 expression as its arguments. The action should return some JavaScript value
442 using the `return` statement. This value is considered match result of the
443 preceding expression.
444
445 To indicate an error, the code inside the action can invoke the `expected`
446 function, which makes the parser throw an exception. The function takes two
447 parameters — a description of what was expected at the current position and
448 optional location information (the default is what `location` would return — see
449 below). The description will be used as part of a message of the thrown
450 exception.
451
452 The code inside an action can also invoke the `error` function, which also makes
453 the parser throw an exception. The function takes two parameters — an error
454 message and optional location information (the default is what `location` would
455 return — see below). The message will be used by the thrown exception.
456
457 The code inside the action can access all variables and functions defined in the
458 initializer at the beginning of the grammar. Curly braces in the action code
459 must be balanced.
460
461 The code inside the action can also access the text matched by the expression
462 using the `text` function.
463
464
465 The code inside the action can also access location information using the
466 `location` function. It returns an object like this:
467
468 ```javascript
469 {
470 start: { offset: 23, line: 5, column: 6 },
471 end: { offset: 25, line: 5, column: 8 }
472 }
473 ```
474
475 The `start` property refers to the position at the beginning of the expression,
476 the `end` property refers to position after the end of the expression. The
477 `offset` property contains an offset as a zero-based index and `line` and
478 `column` properties contain a line and a column as one-based indices.
479
480 The code inside the action can also access options passed to the parser using
481 the `options` variable.
221482
222483 Note that curly braces in the action code must be balanced.
223484
224485 #### *expression<sub>1</sub>* / *expression<sub>2</sub>* / ... / *expression<sub>n</sub>*
225486
226 Try to match the first expression, if it does not succeed, try the second one, etc. Return the match result of the first successfully matched expression. If no expression matches, consider the match failed.
487 Try to match the first expression, if it does not succeed, try the second one,
488 etc. Return the match result of the first successfully matched expression. If no
489 expression matches, consider the match failed.
227490
228491 Compatibility
229492 -------------
230493
231 Both the parser generator and generated parsers should run well in the following environments:
232
233 * Node.js 0.6.6+
234 * IE 8+
494 Both the parser generator and generated parsers should run well in the following
495 environments:
496
497 * Node.js 0.10.0+
498 * Internet Explorer 8+
499 * Edge
235500 * Firefox
236501 * Chrome
237502 * Safari
240505 Development
241506 -----------
242507
243 * [Project website](https://pegjs.majda.cz/)
244 * [Source code](https://github.com/dmajda/pegjs)
245 * [Issue tracker](https://github.com/dmajda/pegjs/issues)
508 * [Project website](http://pegjs.org/)
509 * [Wiki](https://github.com/pegjs/pegjs/wiki)
510 * [Source code](https://github.com/pegjs/pegjs)
511 * [Issue tracker](https://github.com/pegjs/pegjs/issues)
246512 * [Google Group](http://groups.google.com/group/pegjs)
247513 * [Twitter](http://twitter.com/peg_js)
248514
249 PEG.js is developed by [David Majda](http://majda.cz/) ([@dmajda](http://twitter.com/dmajda)). You are welcome to contribute code. Unless your contribution is really trivial you should get in touch with me first — this can prevent wasted effort on both sides. You can send code both as a patch or a GitHub pull request.
250
251 Note that PEG.js is still very much work in progress. There are no compatibility guarantees until version 1.0.
515 PEG.js is developed by [David Majda](http://majda.cz/)
516 ([@dmajda](http://twitter.com/dmajda)). The [Bower
517 package](https://github.com/pegjs/bower) is maintained by [Michel
518 Krämer](http://www.michel-kraemer.com/)
519 ([@michelkraemer](https://twitter.com/michelkraemer)).
520
521 You are welcome to contribute code. Unless your contribution is really trivial
522 you should get in touch with me first — this can prevent wasted effort on both
523 sides. You can send code both as a patch or a GitHub pull request.
524
525 Note that PEG.js is still very much work in progress. There are no compatibility
526 guarantees until version 1.0.
0 0.7.0
0 0.10.0
0 PEG.js Benchmark Suite
1 ======================
2
3 This is the PEG.js benchmark suite. It measures speed of the parsers generated
4 by PEG.js on various inputs. Its main goal is to provide data for code generator
5 optimizations.
6
7 Running in Node.js
8 ------------------
9
10 All commands in the following steps need to be executed in PEG.js root directory
11 (one level up from this one).
12
13 1. Install all PEG.js dependencies, including development ones:
14
15 ```console
16 $ npm install
17 ```
18
19 2. Execute the benchmark suite:
20
21 ```console
22 $ make spec
23 ```
24
25 3. Wait for results.
26
27 Running in the Browser
28 ----------------------
29
30 All commands in the following steps need to be executed in PEG.js root directory
31 (one level up from this one).
32
33 1. Make sure you have Node.js installed.
34
35 2. Install all PEG.js dependencies, including development ones:
36
37 ```console
38 $ npm install
39 ```
40
41 3. Build browser version of PEG.js:
42
43 ```console
44 $ make browser
45 ```
46
47 4. Serve PEG.js root directory using a web server:
48
49 ```console
50 $ node_modules/.bin/http-server
51 ```
52
53 5. Point your browser to the [benchmark suite](http://localhost:8080/benchmark/index.html).
54
55 6. Click the **Run** button and wait for results.
0 /* global module */
1
2 "use strict";
3
4 (function(root, factory) {
5 if (typeof module !== 'undefined' && module.exports) {
6 module.exports = factory();
7 } else {
8 root.benchmarks = factory();
9 }
10 }(this, function() {
11
12 return [
13 {
14 id: "json",
15 title: "JSON",
16 tests: [
17 { file: "example1.json", title: "Example 1" },
18 { file: "example2.json", title: "Example 2" },
19 { file: "example3.json", title: "Example 3" },
20 { file: "example4.json", title: "Example 4" },
21 { file: "example5.json", title: "Example 5" }
22 ]
23 },
24 {
25 id: "css",
26 title: "CSS",
27 tests: [
28 { file: "blueprint/src/reset.css", title: "Blueprint - reset.css (source)" },
29 { file: "blueprint/src/typography.css", title: "Blueprint - typography.css (source)" },
30 { file: "blueprint/src/forms.css", title: "Blueprint - forms.css (source)" },
31 { file: "blueprint/src/grid.css", title: "Blueprint - grid.css (source)" },
32 { file: "blueprint/src/print.css", title: "Blueprint - print.css (source)" },
33 // Contains syntax errors.
34 // { file: "blueprint/src/ie.css", title: "Blueprint - ie.css (source)" },
35 { file: "blueprint/min/screen.css", title: "Blueprint - screen.css (minified)" },
36 { file: "blueprint/min/print.css", title: "Blueprint - print.css (minified)" },
37 // Contains syntax errors.
38 // { file: "blueprint/min/ie.css", title: "Blueprint - ie.css (minified)" },
39 { file: "960.gs/src/reset.css", title: "960.gs - reset.css (source)" },
40 { file: "960.gs/src/text.css", title: "960.gs - text.css (source)" },
41 { file: "960.gs/src/960.css", title: "960.gs - 960.css (source)" },
42 { file: "960.gs/src/960_24_col.css", title: "960.gs - 960_24_col.css (source)" },
43 { file: "960.gs/min/reset.css", title: "960.gs - reset.css (minified)" },
44 { file: "960.gs/min/text.css", title: "960.gs - text.css (minified)" },
45 { file: "960.gs/min/960.css", title: "960.gs - 960.css (minified)" },
46 { file: "960.gs/min/960_24_col.css", title: "960.gs - 960_24_col.css (minified)" }
47 ]
48 }
49 ];
50
51 }));
0 .container_12,.container_16{margin-left:auto;margin-right:auto;width:960px}.grid_1,.grid_2,.grid_3,.grid_4,.grid_5,.grid_6,.grid_7,.grid_8,.grid_9,.grid_10,.grid_11,.grid_12,.grid_13,.grid_14,.grid_15,.grid_16{display:inline;float:left;position:relative;margin-left:10px;margin-right:10px}.container_12 .grid_3,.container_16 .grid_4{width:220px}.container_12 .grid_6,.container_16 .grid_8{width:460px}.container_12 .grid_9,.container_16 .grid_12{width:700px}.container_12 .grid_12,.container_16 .grid_16{width:940px}.alpha{margin-left:0}.omega{margin-right:0}.container_12 .grid_1{width:60px}.container_12 .grid_2{width:140px}.container_12 .grid_4{width:300px}.container_12 .grid_5{width:380px}.container_12 .grid_7{width:540px}.container_12 .grid_8{width:620px}.container_12 .grid_10{width:780px}.container_12 .grid_11{width:860px}.container_16 .grid_1{width:40px}.container_16 .grid_2{width:100px}.container_16 .grid_3{width:160px}.container_16 .grid_5{width:280px}.container_16 .grid_6{width:340px}.container_16 .grid_7{width:400px}.container_16 .grid_9{width:520px}.container_16 .grid_10{width:580px}.container_16 .grid_11{width:640px}.container_16 .grid_13{width:760px}.container_16 .grid_14{width:820px}.container_16 .grid_15{width:880px}.container_12 .prefix_3,.container_16 .prefix_4{padding-left:240px}.container_12 .prefix_6,.container_16 .prefix_8{padding-left:480px}.container_12 .prefix_9,.container_16 .prefix_12{padding-left:720px}.container_12 .prefix_1{padding-left:80px}.container_12 .prefix_2{padding-left:160px}.container_12 .prefix_4{padding-left:320px}.container_12 .prefix_5{padding-left:400px}.container_12 .prefix_7{padding-left:560px}.container_12 .prefix_8{padding-left:640px}.container_12 .prefix_10{padding-left:800px}.container_12 .prefix_11{padding-left:880px}.container_16 .prefix_1{padding-left:60px}.container_16 .prefix_2{padding-left:120px}.container_16 .prefix_3{padding-left:180px}.container_16 .prefix_5{padding-left:300px}.container_16 .prefix_6{padding-left:360px}.container_16 .prefix_7{padding-left:420px}.container_16 .prefix_9{padding-left:540px}.container_16 .prefix_10{padding-left:600px}.container_16 .prefix_11{padding-left:660px}.container_16 .prefix_13{padding-left:780px}.container_16 .prefix_14{padding-left:840px}.container_16 .prefix_15{padding-left:900px}.container_12 .suffix_3,.container_16 .suffix_4{padding-right:240px}.container_12 .suffix_6,.container_16 .suffix_8{padding-right:480px}.container_12 .suffix_9,.container_16 .suffix_12{padding-right:720px}.container_12 .suffix_1{padding-right:80px}.container_12 .suffix_2{padding-right:160px}.container_12 .suffix_4{padding-right:320px}.container_12 .suffix_5{padding-right:400px}.container_12 .suffix_7{padding-right:560px}.container_12 .suffix_8{padding-right:640px}.container_12 .suffix_10{padding-right:800px}.container_12 .suffix_11{padding-right:880px}.container_16 .suffix_1{padding-right:60px}.container_16 .suffix_2{padding-right:120px}.container_16 .suffix_3{padding-right:180px}.container_16 .suffix_5{padding-right:300px}.container_16 .suffix_6{padding-right:360px}.container_16 .suffix_7{padding-right:420px}.container_16 .suffix_9{padding-right:540px}.container_16 .suffix_10{padding-right:600px}.container_16 .suffix_11{padding-right:660px}.container_16 .suffix_13{padding-right:780px}.container_16 .suffix_14{padding-right:840px}.container_16 .suffix_15{padding-right:900px}.container_12 .push_3,.container_16 .push_4{left:240px}.container_12 .push_6,.container_16 .push_8{left:480px}.container_12 .push_9,.container_16 .push_12{left:720px}.container_12 .push_1{left:80px}.container_12 .push_2{left:160px}.container_12 .push_4{left:320px}.container_12 .push_5{left:400px}.container_12 .push_7{left:560px}.container_12 .push_8{left:640px}.container_12 .push_10{left:800px}.container_12 .push_11{left:880px}.container_16 .push_1{left:60px}.container_16 .push_2{left:120px}.container_16 .push_3{left:180px}.container_16 .push_5{left:300px}.container_16 .push_6{left:360px}.container_16 .push_7{left:420px}.container_16 .push_9{left:540px}.container_16 .push_10{left:600px}.container_16 .push_11{left:660px}.container_16 .push_13{left:780px}.container_16 .push_14{left:840px}.container_16 .push_15{left:900px}.container_12 .pull_3,.container_16 .pull_4{left:-240px}.container_12 .pull_6,.container_16 .pull_8{left:-480px}.container_12 .pull_9,.container_16 .pull_12{left:-720px}.container_12 .pull_1{left:-80px}.container_12 .pull_2{left:-160px}.container_12 .pull_4{left:-320px}.container_12 .pull_5{left:-400px}.container_12 .pull_7{left:-560px}.container_12 .pull_8{left:-640px}.container_12 .pull_10{left:-800px}.container_12 .pull_11{left:-880px}.container_16 .pull_1{left:-60px}.container_16 .pull_2{left:-120px}.container_16 .pull_3{left:-180px}.container_16 .pull_5{left:-300px}.container_16 .pull_6{left:-360px}.container_16 .pull_7{left:-420px}.container_16 .pull_9{left:-540px}.container_16 .pull_10{left:-600px}.container_16 .pull_11{left:-660px}.container_16 .pull_13{left:-780px}.container_16 .pull_14{left:-840px}.container_16 .pull_15{left:-900px}.clear{clear:both;display:block;overflow:hidden;visibility:hidden;width:0;height:0}.clearfix:after{clear:both;content:' ';display:block;font-size:0;line-height:0;visibility:hidden;width:0;height:0}* html .clearfix,*:first-child+html .clearfix{zoom:1}
0 .container_24{margin-left:auto;margin-right:auto;width:960px}.grid_1,.grid_2,.grid_3,.grid_4,.grid_5,.grid_6,.grid_7,.grid_8,.grid_9,.grid_10,.grid_11,.grid_12,.grid_13,.grid_14,.grid_15,.grid_16,.grid_17,.grid_18,.grid_19,.grid_20,.grid_21,.grid_22,.grid_23,.grid_24{display:inline;float:left;position:relative;margin-left:5px;margin-right:5px}.alpha{margin-left:0}.omega{margin-right:0}.container_24 .grid_1{width:30px}.container_24 .grid_2{width:70px}.container_24 .grid_3{width:110px}.container_24 .grid_4{width:150px}.container_24 .grid_5{width:190px}.container_24 .grid_6{width:230px}.container_24 .grid_7{width:270px}.container_24 .grid_8{width:310px}.container_24 .grid_9{width:350px}.container_24 .grid_10{width:390px}.container_24 .grid_11{width:430px}.container_24 .grid_12{width:470px}.container_24 .grid_13{width:510px}.container_24 .grid_14{width:550px}.container_24 .grid_15{width:590px}.container_24 .grid_16{width:630px}.container_24 .grid_17{width:670px}.container_24 .grid_18{width:710px}.container_24 .grid_19{width:750px}.container_24 .grid_20{width:790px}.container_24 .grid_21{width:830px}.container_24 .grid_22{width:870px}.container_24 .grid_23{width:910px}.container_24 .grid_24{width:950px}.container_24 .prefix_1{padding-left:40px}.container_24 .prefix_2{padding-left:80px}.container_24 .prefix_3{padding-left:120px}.container_24 .prefix_4{padding-left:160px}.container_24 .prefix_5{padding-left:200px}.container_24 .prefix_6{padding-left:240px}.container_24 .prefix_7{padding-left:280px}.container_24 .prefix_8{padding-left:320px}.container_24 .prefix_9{padding-left:360px}.container_24 .prefix_10{padding-left:400px}.container_24 .prefix_11{padding-left:440px}.container_24 .prefix_12{padding-left:480px}.container_24 .prefix_13{padding-left:520px}.container_24 .prefix_14{padding-left:560px}.container_24 .prefix_15{padding-left:600px}.container_24 .prefix_16{padding-left:640px}.container_24 .prefix_17{padding-left:680px}.container_24 .prefix_18{padding-left:720px}.container_24 .prefix_19{padding-left:760px}.container_24 .prefix_20{padding-left:800px}.container_24 .prefix_21{padding-left:840px}.container_24 .prefix_22{padding-left:880px}.container_24 .prefix_23{padding-left:920px}.container_24 .suffix_1{padding-right:40px}.container_24 .suffix_2{padding-right:80px}.container_24 .suffix_3{padding-right:120px}.container_24 .suffix_4{padding-right:160px}.container_24 .suffix_5{padding-right:200px}.container_24 .suffix_6{padding-right:240px}.container_24 .suffix_7{padding-right:280px}.container_24 .suffix_8{padding-right:320px}.container_24 .suffix_9{padding-right:360px}.container_24 .suffix_10{padding-right:400px}.container_24 .suffix_11{padding-right:440px}.container_24 .suffix_12{padding-right:480px}.container_24 .suffix_13{padding-right:520px}.container_24 .suffix_14{padding-right:560px}.container_24 .suffix_15{padding-right:600px}.container_24 .suffix_16{padding-right:640px}.container_24 .suffix_17{padding-right:680px}.container_24 .suffix_18{padding-right:720px}.container_24 .suffix_19{padding-right:760px}.container_24 .suffix_20{padding-right:800px}.container_24 .suffix_21{padding-right:840px}.container_24 .suffix_22{padding-right:880px}.container_24 .suffix_23{padding-right:920px}.container_24 .push_1{left:40px}.container_24 .push_2{left:80px}.container_24 .push_3{left:120px}.container_24 .push_4{left:160px}.container_24 .push_5{left:200px}.container_24 .push_6{left:240px}.container_24 .push_7{left:280px}.container_24 .push_8{left:320px}.container_24 .push_9{left:360px}.container_24 .push_10{left:400px}.container_24 .push_11{left:440px}.container_24 .push_12{left:480px}.container_24 .push_13{left:520px}.container_24 .push_14{left:560px}.container_24 .push_15{left:600px}.container_24 .push_16{left:640px}.container_24 .push_17{left:680px}.container_24 .push_18{left:720px}.container_24 .push_19{left:760px}.container_24 .push_20{left:800px}.container_24 .push_21{left:840px}.container_24 .push_22{left:880px}.container_24 .push_23{left:920px}.container_24 .pull_1{left:-40px}.container_24 .pull_2{left:-80px}.container_24 .pull_3{left:-120px}.container_24 .pull_4{left:-160px}.container_24 .pull_5{left:-200px}.container_24 .pull_6{left:-240px}.container_24 .pull_7{left:-280px}.container_24 .pull_8{left:-320px}.container_24 .pull_9{left:-360px}.container_24 .pull_10{left:-400px}.container_24 .pull_11{left:-440px}.container_24 .pull_12{left:-480px}.container_24 .pull_13{left:-520px}.container_24 .pull_14{left:-560px}.container_24 .pull_15{left:-600px}.container_24 .pull_16{left:-640px}.container_24 .pull_17{left:-680px}.container_24 .pull_18{left:-720px}.container_24 .pull_19{left:-760px}.container_24 .pull_20{left:-800px}.container_24 .pull_21{left:-840px}.container_24 .pull_22{left:-880px}.container_24 .pull_23{left:-920px}.clear{clear:both;display:block;overflow:hidden;visibility:hidden;width:0;height:0}.clearfix:after{clear:both;content:' ';display:block;font-size:0;line-height:0;visibility:hidden;width:0;height:0}* html .clearfix,*:first-child+html .clearfix{zoom:1}
0 html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;border:0;outline:0;font-size:100%;vertical-align:baseline;background:transparent}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:'';content:none}:focus{outline:0}ins{text-decoration:none}del{text-decoration:line-through}table{border-collapse:collapse;border-spacing:0}
0 body{font:13px/1.5 'Helvetica Neue',Arial,'Liberation Sans',FreeSans,sans-serif}a:focus{outline:1px dotted}hr{border:0 #ccc solid;border-top-width:1px;clear:both;height:0}h1{font-size:25px}h2{font-size:23px}h3{font-size:21px}h4{font-size:19px}h5{font-size:17px}h6{font-size:15px}ol{list-style:decimal}ul{list-style:disc}li{margin-left:30px}p,dl,hr,h1,h2,h3,h4,h5,h6,ol,ul,pre,table,address,fieldset{margin-bottom:20px}
0 /*
1 960 Grid System ~ Core CSS.
2 Learn more ~ http://960.gs/
3
4 Licensed under GPL and MIT.
5 */
6
7 /* `Containers
8 ----------------------------------------------------------------------------------------------------*/
9
10 .container_12,
11 .container_16 {
12 margin-left: auto;
13 margin-right: auto;
14 width: 960px;
15 }
16
17 /* `Grid >> Global
18 ----------------------------------------------------------------------------------------------------*/
19
20 .grid_1,
21 .grid_2,
22 .grid_3,
23 .grid_4,
24 .grid_5,
25 .grid_6,
26 .grid_7,
27 .grid_8,
28 .grid_9,
29 .grid_10,
30 .grid_11,
31 .grid_12,
32 .grid_13,
33 .grid_14,
34 .grid_15,
35 .grid_16 {
36 display: inline;
37 float: left;
38 position: relative;
39 margin-left: 10px;
40 margin-right: 10px;
41 }
42
43 .container_12 .grid_3,
44 .container_16 .grid_4 {
45 width: 220px;
46 }
47
48 .container_12 .grid_6,
49 .container_16 .grid_8 {
50 width: 460px;
51 }
52
53 .container_12 .grid_9,
54 .container_16 .grid_12 {
55 width: 700px;
56 }
57
58 .container_12 .grid_12,
59 .container_16 .grid_16 {
60 width: 940px;
61 }
62
63 /* `Grid >> Children (Alpha ~ First, Omega ~ Last)
64 ----------------------------------------------------------------------------------------------------*/
65
66 .alpha {
67 margin-left: 0;
68 }
69
70 .omega {
71 margin-right: 0;
72 }
73
74 /* `Grid >> 12 Columns
75 ----------------------------------------------------------------------------------------------------*/
76
77 .container_12 .grid_1 {
78 width: 60px;
79 }
80
81 .container_12 .grid_2 {
82 width: 140px;
83 }
84
85 .container_12 .grid_4 {
86 width: 300px;
87 }
88
89 .container_12 .grid_5 {
90 width: 380px;
91 }
92
93 .container_12 .grid_7 {
94 width: 540px;
95 }
96
97 .container_12 .grid_8 {
98 width: 620px;
99 }
100
101 .container_12 .grid_10 {
102 width: 780px;
103 }
104
105 .container_12 .grid_11 {
106 width: 860px;
107 }
108
109 /* `Grid >> 16 Columns
110 ----------------------------------------------------------------------------------------------------*/
111
112 .container_16 .grid_1 {
113 width: 40px;
114 }
115
116 .container_16 .grid_2 {
117 width: 100px;
118 }
119
120 .container_16 .grid_3 {
121 width: 160px;
122 }
123
124 .container_16 .grid_5 {
125 width: 280px;
126 }
127
128 .container_16 .grid_6 {
129 width: 340px;
130 }
131
132 .container_16 .grid_7 {
133 width: 400px;
134 }
135
136 .container_16 .grid_9 {
137 width: 520px;
138 }
139
140 .container_16 .grid_10 {
141 width: 580px;
142 }
143
144 .container_16 .grid_11 {
145 width: 640px;
146 }
147
148 .container_16 .grid_13 {
149 width: 760px;
150 }
151
152 .container_16 .grid_14 {
153 width: 820px;
154 }
155
156 .container_16 .grid_15 {
157 width: 880px;
158 }
159
160 /* `Prefix Extra Space >> Global
161 ----------------------------------------------------------------------------------------------------*/
162
163 .container_12 .prefix_3,
164 .container_16 .prefix_4 {
165 padding-left: 240px;
166 }
167
168 .container_12 .prefix_6,
169 .container_16 .prefix_8 {
170 padding-left: 480px;
171 }
172
173 .container_12 .prefix_9,
174 .container_16 .prefix_12 {
175 padding-left: 720px;
176 }
177
178 /* `Prefix Extra Space >> 12 Columns
179 ----------------------------------------------------------------------------------------------------*/
180
181 .container_12 .prefix_1 {
182 padding-left: 80px;
183 }
184
185 .container_12 .prefix_2 {
186 padding-left: 160px;
187 }
188
189 .container_12 .prefix_4 {
190 padding-left: 320px;
191 }
192
193 .container_12 .prefix_5 {
194 padding-left: 400px;
195 }
196
197 .container_12 .prefix_7 {
198 padding-left: 560px;
199 }
200
201 .container_12 .prefix_8 {
202 padding-left: 640px;
203 }
204
205 .container_12 .prefix_10 {
206 padding-left: 800px;
207 }
208
209 .container_12 .prefix_11 {
210 padding-left: 880px;
211 }
212
213 /* `Prefix Extra Space >> 16 Columns
214 ----------------------------------------------------------------------------------------------------*/
215
216 .container_16 .prefix_1 {
217 padding-left: 60px;
218 }
219
220 .container_16 .prefix_2 {
221 padding-left: 120px;
222 }
223
224 .container_16 .prefix_3 {
225 padding-left: 180px;
226 }
227
228 .container_16 .prefix_5 {
229 padding-left: 300px;
230 }
231
232 .container_16 .prefix_6 {
233 padding-left: 360px;
234 }
235
236 .container_16 .prefix_7 {
237 padding-left: 420px;
238 }
239
240 .container_16 .prefix_9 {
241 padding-left: 540px;
242 }
243
244 .container_16 .prefix_10 {
245 padding-left: 600px;
246 }
247
248 .container_16 .prefix_11 {
249 padding-left: 660px;
250 }
251
252 .container_16 .prefix_13 {
253 padding-left: 780px;
254 }
255
256 .container_16 .prefix_14 {
257 padding-left: 840px;
258 }
259
260 .container_16 .prefix_15 {
261 padding-left: 900px;
262 }
263
264 /* `Suffix Extra Space >> Global
265 ----------------------------------------------------------------------------------------------------*/
266
267 .container_12 .suffix_3,
268 .container_16 .suffix_4 {
269 padding-right: 240px;
270 }
271
272 .container_12 .suffix_6,
273 .container_16 .suffix_8 {
274 padding-right: 480px;
275 }
276
277 .container_12 .suffix_9,
278 .container_16 .suffix_12 {
279 padding-right: 720px;
280 }
281
282 /* `Suffix Extra Space >> 12 Columns
283 ----------------------------------------------------------------------------------------------------*/
284
285 .container_12 .suffix_1 {
286 padding-right: 80px;
287 }
288
289 .container_12 .suffix_2 {
290 padding-right: 160px;
291 }
292
293 .container_12 .suffix_4 {
294 padding-right: 320px;
295 }
296
297 .container_12 .suffix_5 {
298 padding-right: 400px;
299 }
300
301 .container_12 .suffix_7 {
302 padding-right: 560px;
303 }
304
305 .container_12 .suffix_8 {
306 padding-right: 640px;
307 }
308
309 .container_12 .suffix_10 {
310 padding-right: 800px;
311 }
312
313 .container_12 .suffix_11 {
314 padding-right: 880px;
315 }
316
317 /* `Suffix Extra Space >> 16 Columns
318 ----------------------------------------------------------------------------------------------------*/
319
320 .container_16 .suffix_1 {
321 padding-right: 60px;
322 }
323
324 .container_16 .suffix_2 {
325 padding-right: 120px;
326 }
327
328 .container_16 .suffix_3 {
329 padding-right: 180px;
330 }
331
332 .container_16 .suffix_5 {
333 padding-right: 300px;
334 }
335
336 .container_16 .suffix_6 {
337 padding-right: 360px;
338 }
339
340 .container_16 .suffix_7 {
341 padding-right: 420px;
342 }
343
344 .container_16 .suffix_9 {
345 padding-right: 540px;
346 }
347
348 .container_16 .suffix_10 {
349 padding-right: 600px;
350 }
351
352 .container_16 .suffix_11 {
353 padding-right: 660px;
354 }
355
356 .container_16 .suffix_13 {
357 padding-right: 780px;
358 }
359
360 .container_16 .suffix_14 {
361 padding-right: 840px;
362 }
363
364 .container_16 .suffix_15 {
365 padding-right: 900px;
366 }
367
368 /* `Push Space >> Global
369 ----------------------------------------------------------------------------------------------------*/
370
371 .container_12 .push_3,
372 .container_16 .push_4 {
373 left: 240px;
374 }
375
376 .container_12 .push_6,
377 .container_16 .push_8 {
378 left: 480px;
379 }
380
381 .container_12 .push_9,
382 .container_16 .push_12 {
383 left: 720px;
384 }
385
386 /* `Push Space >> 12 Columns
387 ----------------------------------------------------------------------------------------------------*/
388
389 .container_12 .push_1 {
390 left: 80px;
391 }
392
393 .container_12 .push_2 {
394 left: 160px;
395 }
396
397 .container_12 .push_4 {
398 left: 320px;
399 }
400
401 .container_12 .push_5 {
402 left: 400px;
403 }
404
405 .container_12 .push_7 {
406 left: 560px;
407 }
408
409 .container_12 .push_8 {
410 left: 640px;
411 }
412
413 .container_12 .push_10 {
414 left: 800px;
415 }
416
417 .container_12 .push_11 {
418 left: 880px;
419 }
420
421 /* `Push Space >> 16 Columns
422 ----------------------------------------------------------------------------------------------------*/
423
424 .container_16 .push_1 {
425 left: 60px;
426 }
427
428 .container_16 .push_2 {
429 left: 120px;
430 }
431
432 .container_16 .push_3 {
433 left: 180px;
434 }
435
436 .container_16 .push_5 {
437 left: 300px;
438 }
439
440 .container_16 .push_6 {
441 left: 360px;
442 }
443
444 .container_16 .push_7 {
445 left: 420px;
446 }
447
448 .container_16 .push_9 {
449 left: 540px;
450 }
451
452 .container_16 .push_10 {
453 left: 600px;
454 }
455
456 .container_16 .push_11 {
457 left: 660px;
458 }
459
460 .container_16 .push_13 {
461 left: 780px;
462 }
463
464 .container_16 .push_14 {
465 left: 840px;
466 }
467
468 .container_16 .push_15 {
469 left: 900px;
470 }
471
472 /* `Pull Space >> Global
473 ----------------------------------------------------------------------------------------------------*/
474
475 .container_12 .pull_3,
476 .container_16 .pull_4 {
477 left: -240px;
478 }
479
480 .container_12 .pull_6,
481 .container_16 .pull_8 {
482 left: -480px;
483 }
484
485 .container_12 .pull_9,
486 .container_16 .pull_12 {
487 left: -720px;
488 }
489
490 /* `Pull Space >> 12 Columns
491 ----------------------------------------------------------------------------------------------------*/
492
493 .container_12 .pull_1 {
494 left: -80px;
495 }
496
497 .container_12 .pull_2 {
498 left: -160px;
499 }
500
501 .container_12 .pull_4 {
502 left: -320px;
503 }
504
505 .container_12 .pull_5 {
506 left: -400px;
507 }
508
509 .container_12 .pull_7 {
510 left: -560px;
511 }
512
513 .container_12 .pull_8 {
514 left: -640px;
515 }
516
517 .container_12 .pull_10 {
518 left: -800px;
519 }
520
521 .container_12 .pull_11 {
522 left: -880px;
523 }
524
525 /* `Pull Space >> 16 Columns
526 ----------------------------------------------------------------------------------------------------*/
527
528 .container_16 .pull_1 {
529 left: -60px;
530 }
531
532 .container_16 .pull_2 {
533 left: -120px;
534 }
535
536 .container_16 .pull_3 {
537 left: -180px;
538 }
539
540 .container_16 .pull_5 {
541 left: -300px;
542 }
543
544 .container_16 .pull_6 {
545 left: -360px;
546 }
547
548 .container_16 .pull_7 {
549 left: -420px;
550 }
551
552 .container_16 .pull_9 {
553 left: -540px;
554 }
555
556 .container_16 .pull_10 {
557 left: -600px;
558 }
559
560 .container_16 .pull_11 {
561 left: -660px;
562 }
563
564 .container_16 .pull_13 {
565 left: -780px;
566 }
567
568 .container_16 .pull_14 {
569 left: -840px;
570 }
571
572 .container_16 .pull_15 {
573 left: -900px;
574 }
575
576 /* `Clear Floated Elements
577 ----------------------------------------------------------------------------------------------------*/
578
579 /* http://sonspring.com/journal/clearing-floats */
580
581 .clear {
582 clear: both;
583 display: block;
584 overflow: hidden;
585 visibility: hidden;
586 width: 0;
587 height: 0;
588 }
589
590 /* http://perishablepress.com/press/2009/12/06/new-clearfix-hack */
591
592 .clearfix:after {
593 clear: both;
594 content: ' ';
595 display: block;
596 font-size: 0;
597 line-height: 0;
598 visibility: hidden;
599 width: 0;
600 height: 0;
601 }
602
603 /*
604 The following zoom:1 rule is specifically for IE6 + IE7.
605 Move to separate stylesheet if invalid CSS is a problem.
606 */
607 * html .clearfix,
608 *:first-child+html .clearfix {
609 zoom: 1;
610 }
0 /*
1 960 Grid System ~ Core CSS.
2 Learn more ~ http://960.gs/
3
4 Licensed under GPL and MIT.
5 */
6
7 /* Container >> 24 Columns
8 ----------------------------------------------------------------------------------------------------*/
9 .container_24 {
10 margin-left: auto;
11 margin-right: auto;
12 width: 960px;
13 }
14
15 /* Grid >> Global
16 ----------------------------------------------------------------------------------------------------*/
17
18 .grid_1,
19 .grid_2,
20 .grid_3,
21 .grid_4,
22 .grid_5,
23 .grid_6,
24 .grid_7,
25 .grid_8,
26 .grid_9,
27 .grid_10,
28 .grid_11,
29 .grid_12,
30 .grid_13,
31 .grid_14,
32 .grid_15,
33 .grid_16,
34 .grid_17,
35 .grid_18,
36 .grid_19,
37 .grid_20,
38 .grid_21,
39 .grid_22,
40 .grid_23,
41 .grid_24 {
42 display: inline;
43 float: left;
44 position: relative;
45 margin-left: 5px;
46 margin-right: 5px;
47 }
48
49 /* Grid >> Children (Alpha ~ First, Omega ~ Last)
50 ----------------------------------------------------------------------------------------------------*/
51
52 .alpha {
53 margin-left: 0;
54 }
55
56 .omega {
57 margin-right: 0;
58 }
59
60 /* Grid >> 24 Columns
61 ----------------------------------------------------------------------------------------------------*/
62
63 .container_24 .grid_1 {
64 width: 30px;
65 }
66
67 .container_24 .grid_2 {
68 width: 70px;
69 }
70
71 .container_24 .grid_3 {
72 width: 110px;
73 }
74
75 .container_24 .grid_4 {
76 width: 150px;
77 }
78
79 .container_24 .grid_5 {
80 width: 190px;
81 }
82
83 .container_24 .grid_6 {
84 width: 230px;
85 }
86
87 .container_24 .grid_7 {
88 width: 270px;
89 }
90
91 .container_24 .grid_8 {
92 width: 310px;
93 }
94
95 .container_24 .grid_9 {
96 width: 350px;
97 }
98
99 .container_24 .grid_10 {
100 width: 390px;
101 }
102
103 .container_24 .grid_11 {
104 width: 430px;
105 }
106
107 .container_24 .grid_12 {
108 width: 470px;
109 }
110
111 .container_24 .grid_13 {
112 width: 510px;
113 }
114
115 .container_24 .grid_14 {
116 width: 550px;
117 }
118
119 .container_24 .grid_15 {
120 width: 590px;
121 }
122
123 .container_24 .grid_16 {
124 width: 630px;
125 }
126
127 .container_24 .grid_17 {
128 width: 670px;
129 }
130
131 .container_24 .grid_18 {
132 width: 710px;
133 }
134
135 .container_24 .grid_19 {
136 width: 750px;
137 }
138
139 .container_24 .grid_20 {
140 width: 790px;
141 }
142
143 .container_24 .grid_21 {
144 width: 830px;
145 }
146
147 .container_24 .grid_22 {
148 width: 870px;
149 }
150
151 .container_24 .grid_23 {
152 width: 910px;
153 }
154
155 .container_24 .grid_24 {
156 width: 950px;
157 }
158
159 /* Prefix Extra Space >> 24 Columns
160 ----------------------------------------------------------------------------------------------------*/
161
162 .container_24 .prefix_1 {
163 padding-left: 40px;
164 }
165
166 .container_24 .prefix_2 {
167 padding-left: 80px;
168 }
169
170 .container_24 .prefix_3 {
171 padding-left: 120px;
172 }
173
174 .container_24 .prefix_4 {
175 padding-left: 160px;
176 }
177
178 .container_24 .prefix_5 {
179 padding-left: 200px;
180 }
181
182 .container_24 .prefix_6 {
183 padding-left: 240px;
184 }
185
186 .container_24 .prefix_7 {
187 padding-left: 280px;
188 }
189
190 .container_24 .prefix_8 {
191 padding-left: 320px;
192 }
193
194 .container_24 .prefix_9 {
195 padding-left: 360px;
196 }
197
198 .container_24 .prefix_10 {
199 padding-left: 400px;
200 }
201
202 .container_24 .prefix_11 {
203 padding-left: 440px;
204 }
205
206 .container_24 .prefix_12 {
207 padding-left: 480px;
208 }
209
210 .container_24 .prefix_13 {
211 padding-left: 520px;
212 }
213
214 .container_24 .prefix_14 {
215 padding-left: 560px;
216 }
217
218 .container_24 .prefix_15 {
219 padding-left: 600px;
220 }
221
222 .container_24 .prefix_16 {
223 padding-left: 640px;
224 }
225
226 .container_24 .prefix_17 {
227 padding-left: 680px;
228 }
229
230 .container_24 .prefix_18 {
231 padding-left: 720px;
232 }
233
234 .container_24 .prefix_19 {
235 padding-left: 760px;
236 }
237
238 .container_24 .prefix_20 {
239 padding-left: 800px;
240 }
241
242 .container_24 .prefix_21 {
243 padding-left: 840px;
244 }
245
246 .container_24 .prefix_22 {
247 padding-left: 880px;
248 }
249
250 .container_24 .prefix_23 {
251 padding-left: 920px;
252 }
253
254 /* Suffix Extra Space >> 24 Columns
255 ----------------------------------------------------------------------------------------------------*/
256
257 .container_24 .suffix_1 {
258 padding-right: 40px;
259 }
260
261 .container_24 .suffix_2 {
262 padding-right: 80px;
263 }
264
265 .container_24 .suffix_3 {
266 padding-right: 120px;
267 }
268
269 .container_24 .suffix_4 {
270 padding-right: 160px;
271 }
272
273 .container_24 .suffix_5 {
274 padding-right: 200px;
275 }
276
277 .container_24 .suffix_6 {
278 padding-right: 240px;
279 }
280
281 .container_24 .suffix_7 {
282 padding-right: 280px;
283 }
284
285 .container_24 .suffix_8 {
286 padding-right: 320px;
287 }
288
289 .container_24 .suffix_9 {
290 padding-right: 360px;
291 }
292
293 .container_24 .suffix_10 {
294 padding-right: 400px;
295 }
296
297 .container_24 .suffix_11 {
298 padding-right: 440px;
299 }
300
301 .container_24 .suffix_12 {
302 padding-right: 480px;
303 }
304
305 .container_24 .suffix_13 {
306 padding-right: 520px;
307 }
308
309 .container_24 .suffix_14 {
310 padding-right: 560px;
311 }
312
313 .container_24 .suffix_15 {
314 padding-right: 600px;
315 }
316
317 .container_24 .suffix_16 {
318 padding-right: 640px;
319 }
320
321 .container_24 .suffix_17 {
322 padding-right: 680px;
323 }
324
325 .container_24 .suffix_18 {
326 padding-right: 720px;
327 }
328
329 .container_24 .suffix_19 {
330 padding-right: 760px;
331 }
332
333 .container_24 .suffix_20 {
334 padding-right: 800px;
335 }
336
337 .container_24 .suffix_21 {
338 padding-right: 840px;
339 }
340
341 .container_24 .suffix_22 {
342 padding-right: 880px;
343 }
344
345 .container_24 .suffix_23 {
346 padding-right: 920px;
347 }
348
349 /* Push Space >> 24 Columns
350 ----------------------------------------------------------------------------------------------------*/
351
352 .container_24 .push_1 {
353 left: 40px;
354 }
355
356 .container_24 .push_2 {
357 left: 80px;
358 }
359
360 .container_24 .push_3 {
361 left: 120px;
362 }
363
364 .container_24 .push_4 {
365 left: 160px;
366 }
367
368 .container_24 .push_5 {
369 left: 200px;
370 }
371
372 .container_24 .push_6 {
373 left: 240px;
374 }
375
376 .container_24 .push_7 {
377 left: 280px;
378 }
379
380 .container_24 .push_8 {
381 left: 320px;
382 }
383
384 .container_24 .push_9 {
385 left: 360px;
386 }
387
388 .container_24 .push_10 {
389 left: 400px;
390 }
391
392 .container_24 .push_11 {
393 left: 440px;
394 }
395
396 .container_24 .push_12 {
397 left: 480px;
398 }
399
400 .container_24 .push_13 {
401 left: 520px;
402 }
403
404 .container_24 .push_14 {
405 left: 560px;
406 }
407
408 .container_24 .push_15 {
409 left: 600px;
410 }
411
412 .container_24 .push_16 {
413 left: 640px;
414 }
415
416 .container_24 .push_17 {
417 left: 680px;
418 }
419
420 .container_24 .push_18 {
421 left: 720px;
422 }
423
424 .container_24 .push_19 {
425 left: 760px;
426 }
427
428 .container_24 .push_20 {
429 left: 800px;
430 }
431
432 .container_24 .push_21 {
433 left: 840px;
434 }
435
436 .container_24 .push_22 {
437 left: 880px;
438 }
439
440 .container_24 .push_23 {
441 left: 920px;
442 }
443
444 /* Pull Space >> 24 Columns
445 ----------------------------------------------------------------------------------------------------*/
446
447 .container_24 .pull_1 {
448 left: -40px;
449 }
450
451 .container_24 .pull_2 {
452 left: -80px;
453 }
454
455 .container_24 .pull_3 {
456 left: -120px;
457 }
458
459 .container_24 .pull_4 {
460 left: -160px;
461 }
462
463 .container_24 .pull_5 {
464 left: -200px;
465 }
466
467 .container_24 .pull_6 {
468 left: -240px;
469 }
470
471 .container_24 .pull_7 {
472 left: -280px;
473 }
474
475 .container_24 .pull_8 {
476 left: -320px;
477 }
478
479 .container_24 .pull_9 {
480 left: -360px;
481 }
482
483 .container_24 .pull_10 {
484 left: -400px;
485 }
486
487 .container_24 .pull_11 {
488 left: -440px;
489 }
490
491 .container_24 .pull_12 {
492 left: -480px;
493 }
494
495 .container_24 .pull_13 {
496 left: -520px;
497 }
498
499 .container_24 .pull_14 {
500 left: -560px;
501 }
502
503 .container_24 .pull_15 {
504 left: -600px;
505 }
506
507 .container_24 .pull_16 {
508 left: -640px;
509 }
510
511 .container_24 .pull_17 {
512 left: -680px;
513 }
514
515 .container_24 .pull_18 {
516 left: -720px;
517 }
518
519 .container_24 .pull_19 {
520 left: -760px;
521 }
522
523 .container_24 .pull_20 {
524 left: -800px;
525 }
526
527 .container_24 .pull_21 {
528 left: -840px;
529 }
530
531 .container_24 .pull_22 {
532 left: -880px;
533 }
534
535 .container_24 .pull_23 {
536 left: -920px;
537 }
538
539 /* `Clear Floated Elements
540 ----------------------------------------------------------------------------------------------------*/
541
542 /* http://sonspring.com/journal/clearing-floats */
543
544 .clear {
545 clear: both;
546 display: block;
547 overflow: hidden;
548 visibility: hidden;
549 width: 0;
550 height: 0;
551 }
552
553 /* http://perishablepress.com/press/2009/12/06/new-clearfix-hack */
554
555 .clearfix:after {
556 clear: both;
557 content: ' ';
558 display: block;
559 font-size: 0;
560 line-height: 0;
561 visibility: hidden;
562 width: 0;
563 height: 0;
564 }
565
566 /*
567 The following zoom:1 rule is specifically for IE6 + IE7.
568 Move to separate stylesheet if invalid CSS is a problem.
569 */
570 * html .clearfix,
571 *:first-child+html .clearfix {
572 zoom: 1;
573 }
0 /* http://meyerweb.com/eric/tools/css/reset/ */
1 /* v1.0 | 20080212 */
2
3 html, body, div, span, applet, object, iframe,
4 h1, h2, h3, h4, h5, h6, p, blockquote, pre,
5 a, abbr, acronym, address, big, cite, code,
6 del, dfn, em, font, img, ins, kbd, q, s, samp,
7 small, strike, strong, sub, sup, tt, var,
8 b, u, i, center,
9 dl, dt, dd, ol, ul, li,
10 fieldset, form, label, legend,
11 table, caption, tbody, tfoot, thead, tr, th, td {
12 margin: 0;
13 padding: 0;
14 border: 0;
15 outline: 0;
16 font-size: 100%;
17 vertical-align: baseline;
18 background: transparent;
19 }
20 body {
21 line-height: 1;
22 }
23 ol, ul {
24 list-style: none;
25 }
26 blockquote, q {
27 quotes: none;
28 }
29 blockquote:before, blockquote:after,
30 q:before, q:after {
31 content: '';
32 content: none;
33 }
34
35 /* remember to define focus styles! */
36 :focus {
37 outline: 0;
38 }
39
40 /* remember to highlight inserts somehow! */
41 ins {
42 text-decoration: none;
43 }
44 del {
45 text-decoration: line-through;
46 }
47
48 /* tables still need 'cellspacing="0"' in the markup */
49 table {
50 border-collapse: collapse;
51 border-spacing: 0;
52 }
0 /*
1 960 Grid System ~ Text CSS.
2 Learn more ~ http://960.gs/
3
4 Licensed under GPL and MIT.
5 */
6
7 /* `Basic HTML
8 ----------------------------------------------------------------------------------------------------*/
9
10 body {
11 font: 13px/1.5 'Helvetica Neue', Arial, 'Liberation Sans', FreeSans, sans-serif;
12 }
13
14 a:focus {
15 outline: 1px dotted;
16 }
17
18 hr {
19 border: 0 #ccc solid;
20 border-top-width: 1px;
21 clear: both;
22 height: 0;
23 }
24
25 /* `Headings
26 ----------------------------------------------------------------------------------------------------*/
27
28 h1 {
29 font-size: 25px;
30 }
31
32 h2 {
33 font-size: 23px;
34 }
35
36 h3 {
37 font-size: 21px;
38 }
39
40 h4 {
41 font-size: 19px;
42 }
43
44 h5 {
45 font-size: 17px;
46 }
47
48 h6 {
49 font-size: 15px;
50 }
51
52 /* `Spacing
53 ----------------------------------------------------------------------------------------------------*/
54
55 ol {
56 list-style: decimal;
57 }
58
59 ul {
60 list-style: disc;
61 }
62
63 li {
64 margin-left: 30px;
65 }
66
67 p,
68 dl,
69 hr,
70 h1,
71 h2,
72 h3,
73 h4,
74 h5,
75 h6,
76 ol,
77 ul,
78 pre,
79 table,
80 address,
81 fieldset {
82 margin-bottom: 20px;
83 }
0 /* -----------------------------------------------------------------------
1
2
3 Blueprint CSS Framework 0.9
4 http://blueprintcss.org
5
6 * Copyright (c) 2007-Present. See LICENSE for more info.
7 * See README for instructions on how to use Blueprint.
8 * For credits and origins, see AUTHORS.
9 * This is a compressed file. See the sources in the 'src' directory.
10
11 ----------------------------------------------------------------------- */
12
13 /* ie.css */
14 body {text-align:center;}
15 .container {text-align:left;}
16 * html .column, * html .span-1, * html .span-2, * html .span-3, * html .span-4, * html .span-5, * html .span-6, * html .span-7, * html .span-8, * html .span-9, * html .span-10, * html .span-11, * html .span-12, * html .span-13, * html .span-14, * html .span-15, * html .span-16, * html .span-17, * html .span-18, * html .span-19, * html .span-20, * html .span-21, * html .span-22, * html .span-23, * html .span-24 {display:inline;overflow-x:hidden;}
17 * html legend {margin:0px -8px 16px 0;padding:0;}
18 sup {vertical-align:text-top;}
19 sub {vertical-align:text-bottom;}
20 html>body p code {*white-space:normal;}
21 hr {margin:-8px auto 11px;}
22 img {-ms-interpolation-mode:bicubic;}
23 .clearfix, .container {display:inline-block;}
24 * html .clearfix, * html .container {height:1%;}
25 fieldset {padding-top:0;}
26 textarea {overflow:auto;}
27 input.text, input.title, textarea {background-color:#fff;border:1px solid #bbb;}
28 input.text:focus, input.title:focus {border-color:#666;}
29 input.text, input.title, textarea, select {margin:0.5em 0;}
30 input.checkbox, input.radio {position:relative;top:.25em;}
31 form.inline div, form.inline p {vertical-align:middle;}
32 form.inline label {position:relative;top:-0.25em;}
33 form.inline input.checkbox, form.inline input.radio, form.inline input.button, form.inline button {margin:0.5em 0;}
34 button, input.button {position:relative;top:0.25em;}
0 /* -----------------------------------------------------------------------
1
2
3 Blueprint CSS Framework 0.9
4 http://blueprintcss.org
5
6 * Copyright (c) 2007-Present. See LICENSE for more info.
7 * See README for instructions on how to use Blueprint.
8 * For credits and origins, see AUTHORS.
9 * This is a compressed file. See the sources in the 'src' directory.
10
11 ----------------------------------------------------------------------- */
12
13 /* print.css */
14 body {line-height:1.5;font-family:"Helvetica Neue", Arial, Helvetica, sans-serif;color:#000;background:none;font-size:10pt;}
15 .container {background:none;}
16 hr {background:#ccc;color:#ccc;width:100%;height:2px;margin:2em 0;padding:0;border:none;}
17 hr.space {background:#fff;color:#fff;visibility:hidden;}
18 h1, h2, h3, h4, h5, h6 {font-family:"Helvetica Neue", Arial, "Lucida Grande", sans-serif;}
19 code {font:.9em "Courier New", Monaco, Courier, monospace;}
20 a img {border:none;}
21 p img.top {margin-top:0;}
22 blockquote {margin:1.5em;padding:1em;font-style:italic;font-size:.9em;}
23 .small {font-size:.9em;}
24 .large {font-size:1.1em;}
25 .quiet {color:#999;}
26 .hide {display:none;}
27 a:link, a:visited {background:transparent;font-weight:700;text-decoration:underline;}
28 a:link:after, a:visited:after {content:" (" attr(href) ")";font-size:90%;}
0 /* -----------------------------------------------------------------------
1
2
3 Blueprint CSS Framework 0.9
4 http://blueprintcss.org
5
6 * Copyright (c) 2007-Present. See LICENSE for more info.
7 * See README for instructions on how to use Blueprint.
8 * For credits and origins, see AUTHORS.
9 * This is a compressed file. See the sources in the 'src' directory.
10
11 ----------------------------------------------------------------------- */
12
13 /* reset.css */
14 html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, code, del, dfn, em, img, q, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, dialog, figure, footer, header, hgroup, nav, section {margin:0;padding:0;border:0;font-weight:inherit;font-style:inherit;font-size:100%;font-family:inherit;vertical-align:baseline;}
15 article, aside, dialog, figure, footer, header, hgroup, nav, section {display:block;}
16 body {line-height:1.5;}
17 table {border-collapse:separate;border-spacing:0;}
18 caption, th, td {text-align:left;font-weight:normal;}
19 table, td, th {vertical-align:middle;}
20 blockquote:before, blockquote:after, q:before, q:after {content:"";}
21 blockquote, q {quotes:"" "";}
22 a img {border:none;}
23
24 /* typography.css */
25 html {font-size:100.01%;}
26 body {font-size:75%;color:#222;background:#fff;font-family:"Helvetica Neue", Arial, Helvetica, sans-serif;}
27 h1, h2, h3, h4, h5, h6 {font-weight:normal;color:#111;}
28 h1 {font-size:3em;line-height:1;margin-bottom:0.5em;}
29 h2 {font-size:2em;margin-bottom:0.75em;}
30 h3 {font-size:1.5em;line-height:1;margin-bottom:1em;}
31 h4 {font-size:1.2em;line-height:1.25;margin-bottom:1.25em;}
32 h5 {font-size:1em;font-weight:bold;margin-bottom:1.5em;}
33 h6 {font-size:1em;font-weight:bold;}
34 h1 img, h2 img, h3 img, h4 img, h5 img, h6 img {margin:0;}
35 p {margin:0 0 1.5em;}
36 p img.left {float:left;margin:1.5em 1.5em 1.5em 0;padding:0;}
37 p img.right {float:right;margin:1.5em 0 1.5em 1.5em;}
38 a:focus, a:hover {color:#000;}
39 a {color:#009;text-decoration:underline;}
40 blockquote {margin:1.5em;color:#666;font-style:italic;}
41 strong {font-weight:bold;}
42 em, dfn {font-style:italic;}
43 dfn {font-weight:bold;}
44 sup, sub {line-height:0;}
45 abbr, acronym {border-bottom:1px dotted #666;}
46 address {margin:0 0 1.5em;font-style:italic;}
47 del {color:#666;}
48 pre {margin:1.5em 0;white-space:pre;}
49 pre, code, tt {font:1em 'andale mono', 'lucida console', monospace;line-height:1.5;}
50 li ul, li ol {margin:0;}
51 ul, ol {margin:0 1.5em 1.5em 0;padding-left:3.333em;}
52 ul {list-style-type:disc;}
53 ol {list-style-type:decimal;}
54 dl {margin:0 0 1.5em 0;}
55 dl dt {font-weight:bold;}
56 dd {margin-left:1.5em;}
57 table {margin-bottom:1.4em;width:100%;}
58 th {font-weight:bold;}
59 thead th {background:#c3d9ff;}
60 th, td, caption {padding:4px 10px 4px 5px;}
61 tr.even td {background:#e5ecf9;}
62 tfoot {font-style:italic;}
63 caption {background:#eee;}
64 .small {font-size:.8em;margin-bottom:1.875em;line-height:1.875em;}
65 .large {font-size:1.2em;line-height:2.5em;margin-bottom:1.25em;}
66 .hide {display:none;}
67 .quiet {color:#666;}
68 .loud {color:#000;}
69 .highlight {background:#ff0;}
70 .added {background:#060;color:#fff;}
71 .removed {background:#900;color:#fff;}
72 .first {margin-left:0;padding-left:0;}
73 .last {margin-right:0;padding-right:0;}
74 .top {margin-top:0;padding-top:0;}
75 .bottom {margin-bottom:0;padding-bottom:0;}
76
77 /* forms.css */
78 label {font-weight:bold;}
79 fieldset {padding:1.4em;margin:0 0 1.5em 0;border:1px solid #ccc;}
80 legend {font-weight:bold;font-size:1.2em;}
81 input[type=text], input[type=password], input.text, input.title, textarea, select {background-color:#fff;border:1px solid #bbb;}
82 input[type=text]:focus, input[type=password]:focus, input.text:focus, input.title:focus, textarea:focus, select:focus {border-color:#666;}
83 input[type=text], input[type=password], input.text, input.title, textarea, select {margin:0.5em 0;}
84 input.text, input.title {width:300px;padding:5px;}
85 input.title {font-size:1.5em;}
86 textarea {width:390px;height:250px;padding:5px;}
87 input[type=checkbox], input[type=radio], input.checkbox, input.radio {position:relative;top:.25em;}
88 form.inline {line-height:3;}
89 form.inline p {margin-bottom:0;}
90 .error, .notice, .success {padding:.8em;margin-bottom:1em;border:2px solid #ddd;}
91 .error {background:#FBE3E4;color:#8a1f11;border-color:#FBC2C4;}
92 .notice {background:#FFF6BF;color:#514721;border-color:#FFD324;}
93 .success {background:#E6EFC2;color:#264409;border-color:#C6D880;}
94 .error a {color:#8a1f11;}
95 .notice a {color:#514721;}
96 .success a {color:#264409;}
97
98 /* grid.css */
99 .container {width:950px;margin:0 auto;}
100 .showgrid {background:url(src/grid.png);}
101 .column, .span-1, .span-2, .span-3, .span-4, .span-5, .span-6, .span-7, .span-8, .span-9, .span-10, .span-11, .span-12, .span-13, .span-14, .span-15, .span-16, .span-17, .span-18, .span-19, .span-20, .span-21, .span-22, .span-23, .span-24 {float:left;margin-right:10px;}
102 .last {margin-right:0;}
103 .span-1 {width:30px;}
104 .span-2 {width:70px;}
105 .span-3 {width:110px;}
106 .span-4 {width:150px;}
107 .span-5 {width:190px;}
108 .span-6 {width:230px;}
109 .span-7 {width:270px;}
110 .span-8 {width:310px;}
111 .span-9 {width:350px;}
112 .span-10 {width:390px;}
113 .span-11 {width:430px;}
114 .span-12 {width:470px;}
115 .span-13 {width:510px;}
116 .span-14 {width:550px;}
117 .span-15 {width:590px;}
118 .span-16 {width:630px;}
119 .span-17 {width:670px;}
120 .span-18 {width:710px;}
121 .span-19 {width:750px;}
122 .span-20 {width:790px;}
123 .span-21 {width:830px;}
124 .span-22 {width:870px;}
125 .span-23 {width:910px;}
126 .span-24 {width:950px;margin-right:0;}
127 input.span-1, textarea.span-1, input.span-2, textarea.span-2, input.span-3, textarea.span-3, input.span-4, textarea.span-4, input.span-5, textarea.span-5, input.span-6, textarea.span-6, input.span-7, textarea.span-7, input.span-8, textarea.span-8, input.span-9, textarea.span-9, input.span-10, textarea.span-10, input.span-11, textarea.span-11, input.span-12, textarea.span-12, input.span-13, textarea.span-13, input.span-14, textarea.span-14, input.span-15, textarea.span-15, input.span-16, textarea.span-16, input.span-17, textarea.span-17, input.span-18, textarea.span-18, input.span-19, textarea.span-19, input.span-20, textarea.span-20, input.span-21, textarea.span-21, input.span-22, textarea.span-22, input.span-23, textarea.span-23, input.span-24, textarea.span-24 {border-left-width:1px!important;border-right-width:1px!important;padding-left:5px!important;padding-right:5px!important;}
128 input.span-1, textarea.span-1 {width:18px!important;}
129 input.span-2, textarea.span-2 {width:58px!important;}
130 input.span-3, textarea.span-3 {width:98px!important;}
131 input.span-4, textarea.span-4 {width:138px!important;}
132 input.span-5, textarea.span-5 {width:178px!important;}
133 input.span-6, textarea.span-6 {width:218px!important;}
134 input.span-7, textarea.span-7 {width:258px!important;}
135 input.span-8, textarea.span-8 {width:298px!important;}
136 input.span-9, textarea.span-9 {width:338px!important;}
137 input.span-10, textarea.span-10 {width:378px!important;}
138 input.span-11, textarea.span-11 {width:418px!important;}
139 input.span-12, textarea.span-12 {width:458px!important;}
140 input.span-13, textarea.span-13 {width:498px!important;}
141 input.span-14, textarea.span-14 {width:538px!important;}
142 input.span-15, textarea.span-15 {width:578px!important;}
143 input.span-16, textarea.span-16 {width:618px!important;}
144 input.span-17, textarea.span-17 {width:658px!important;}
145 input.span-18, textarea.span-18 {width:698px!important;}
146 input.span-19, textarea.span-19 {width:738px!important;}
147 input.span-20, textarea.span-20 {width:778px!important;}
148 input.span-21, textarea.span-21 {width:818px!important;}
149 input.span-22, textarea.span-22 {width:858px!important;}
150 input.span-23, textarea.span-23 {width:898px!important;}
151 input.span-24, textarea.span-24 {width:938px!important;}
152 .append-1 {padding-right:40px;}
153 .append-2 {padding-right:80px;}
154 .append-3 {padding-right:120px;}
155 .append-4 {padding-right:160px;}
156 .append-5 {padding-right:200px;}
157 .append-6 {padding-right:240px;}
158 .append-7 {padding-right:280px;}
159 .append-8 {padding-right:320px;}
160 .append-9 {padding-right:360px;}
161 .append-10 {padding-right:400px;}
162 .append-11 {padding-right:440px;}
163 .append-12 {padding-right:480px;}
164 .append-13 {padding-right:520px;}
165 .append-14 {padding-right:560px;}
166 .append-15 {padding-right:600px;}
167 .append-16 {padding-right:640px;}
168 .append-17 {padding-right:680px;}
169 .append-18 {padding-right:720px;}
170 .append-19 {padding-right:760px;}
171 .append-20 {padding-right:800px;}
172 .append-21 {padding-right:840px;}
173 .append-22 {padding-right:880px;}
174 .append-23 {padding-right:920px;}
175 .prepend-1 {padding-left:40px;}
176 .prepend-2 {padding-left:80px;}
177 .prepend-3 {padding-left:120px;}
178 .prepend-4 {padding-left:160px;}
179 .prepend-5 {padding-left:200px;}
180 .prepend-6 {padding-left:240px;}
181 .prepend-7 {padding-left:280px;}
182 .prepend-8 {padding-left:320px;}
183 .prepend-9 {padding-left:360px;}
184 .prepend-10 {padding-left:400px;}
185 .prepend-11 {padding-left:440px;}
186 .prepend-12 {padding-left:480px;}
187 .prepend-13 {padding-left:520px;}
188 .prepend-14 {padding-left:560px;}
189 .prepend-15 {padding-left:600px;}
190 .prepend-16 {padding-left:640px;}
191 .prepend-17 {padding-left:680px;}
192 .prepend-18 {padding-left:720px;}
193 .prepend-19 {padding-left:760px;}
194 .prepend-20 {padding-left:800px;}
195 .prepend-21 {padding-left:840px;}
196 .prepend-22 {padding-left:880px;}
197 .prepend-23 {padding-left:920px;}
198 .border {padding-right:4px;margin-right:5px;border-right:1px solid #eee;}
199 .colborder {padding-right:24px;margin-right:25px;border-right:1px solid #eee;}
200 .pull-1 {margin-left:-40px;}
201 .pull-2 {margin-left:-80px;}
202 .pull-3 {margin-left:-120px;}
203 .pull-4 {margin-left:-160px;}
204 .pull-5 {margin-left:-200px;}
205 .pull-6 {margin-left:-240px;}
206 .pull-7 {margin-left:-280px;}
207 .pull-8 {margin-left:-320px;}
208 .pull-9 {margin-left:-360px;}
209 .pull-10 {margin-left:-400px;}
210 .pull-11 {margin-left:-440px;}
211 .pull-12 {margin-left:-480px;}
212 .pull-13 {margin-left:-520px;}
213 .pull-14 {margin-left:-560px;}
214 .pull-15 {margin-left:-600px;}
215 .pull-16 {margin-left:-640px;}
216 .pull-17 {margin-left:-680px;}
217 .pull-18 {margin-left:-720px;}
218 .pull-19 {margin-left:-760px;}
219 .pull-20 {margin-left:-800px;}
220 .pull-21 {margin-left:-840px;}
221 .pull-22 {margin-left:-880px;}
222 .pull-23 {margin-left:-920px;}
223 .pull-24 {margin-left:-960px;}
224 .pull-1, .pull-2, .pull-3, .pull-4, .pull-5, .pull-6, .pull-7, .pull-8, .pull-9, .pull-10, .pull-11, .pull-12, .pull-13, .pull-14, .pull-15, .pull-16, .pull-17, .pull-18, .pull-19, .pull-20, .pull-21, .pull-22, .pull-23, .pull-24 {float:left;position:relative;}
225 .push-1 {margin:0 -40px 1.5em 40px;}
226 .push-2 {margin:0 -80px 1.5em 80px;}
227 .push-3 {margin:0 -120px 1.5em 120px;}
228 .push-4 {margin:0 -160px 1.5em 160px;}
229 .push-5 {margin:0 -200px 1.5em 200px;}
230 .push-6 {margin:0 -240px 1.5em 240px;}
231 .push-7 {margin:0 -280px 1.5em 280px;}
232 .push-8 {margin:0 -320px 1.5em 320px;}
233 .push-9 {margin:0 -360px 1.5em 360px;}
234 .push-10 {margin:0 -400px 1.5em 400px;}
235 .push-11 {margin:0 -440px 1.5em 440px;}
236 .push-12 {margin:0 -480px 1.5em 480px;}
237 .push-13 {margin:0 -520px 1.5em 520px;}
238 .push-14 {margin:0 -560px 1.5em 560px;}
239 .push-15 {margin:0 -600px 1.5em 600px;}
240 .push-16 {margin:0 -640px 1.5em 640px;}
241 .push-17 {margin:0 -680px 1.5em 680px;}
242 .push-18 {margin:0 -720px 1.5em 720px;}
243 .push-19 {margin:0 -760px 1.5em 760px;}
244 .push-20 {margin:0 -800px 1.5em 800px;}
245 .push-21 {margin:0 -840px 1.5em 840px;}
246 .push-22 {margin:0 -880px 1.5em 880px;}
247 .push-23 {margin:0 -920px 1.5em 920px;}
248 .push-24 {margin:0 -960px 1.5em 960px;}
249 .push-1, .push-2, .push-3, .push-4, .push-5, .push-6, .push-7, .push-8, .push-9, .push-10, .push-11, .push-12, .push-13, .push-14, .push-15, .push-16, .push-17, .push-18, .push-19, .push-20, .push-21, .push-22, .push-23, .push-24 {float:right;position:relative;}
250 .prepend-top {margin-top:1.5em;}
251 .append-bottom {margin-bottom:1.5em;}
252 .box {padding:1.5em;margin-bottom:1.5em;background:#E5ECF9;}
253 hr {background:#ddd;color:#ddd;clear:both;float:none;width:100%;height:.1em;margin:0 0 1.45em;border:none;}
254 hr.space {background:#fff;color:#fff;visibility:hidden;}
255 .clearfix:after, .container:after {content:"\0020";display:block;height:0;clear:both;visibility:hidden;overflow:hidden;}
256 .clearfix, .container {display:block;}
257 .clear {clear:both;}
0 /* --------------------------------------------------------------
1
2 forms.css
3 * Sets up some default styling for forms
4 * Gives you classes to enhance your forms
5
6 Usage:
7 * For text fields, use class .title or .text
8 * For inline forms, use .inline (even when using columns)
9
10 -------------------------------------------------------------- */
11
12 label { font-weight: bold; }
13 fieldset { padding:1.4em; margin: 0 0 1.5em 0; border: 1px solid #ccc; }
14 legend { font-weight: bold; font-size:1.2em; }
15
16
17 /* Form fields
18 -------------------------------------------------------------- */
19
20 input[type=text], input[type=password],
21 input.text, input.title,
22 textarea, select {
23 background-color:#fff;
24 border:1px solid #bbb;
25 }
26 input[type=text]:focus, input[type=password]:focus,
27 input.text:focus, input.title:focus,
28 textarea:focus, select:focus {
29 border-color:#666;
30 }
31
32 input[type=text], input[type=password],
33 input.text, input.title,
34 textarea, select {
35 margin:0.5em 0;
36 }
37
38 input.text,
39 input.title { width: 300px; padding:5px; }
40 input.title { font-size:1.5em; }
41 textarea { width: 390px; height: 250px; padding:5px; }
42
43 input[type=checkbox], input[type=radio],
44 input.checkbox, input.radio {
45 position:relative; top:.25em;
46 }
47
48 form.inline { line-height:3; }
49 form.inline p { margin-bottom:0; }
50
51
52 /* Success, notice and error boxes
53 -------------------------------------------------------------- */
54
55 .error,
56 .notice,
57 .success { padding: .8em; margin-bottom: 1em; border: 2px solid #ddd; }
58
59 .error { background: #FBE3E4; color: #8a1f11; border-color: #FBC2C4; }
60 .notice { background: #FFF6BF; color: #514721; border-color: #FFD324; }
61 .success { background: #E6EFC2; color: #264409; border-color: #C6D880; }
62 .error a { color: #8a1f11; }
63 .notice a { color: #514721; }
64 .success a { color: #264409; }
0 /* --------------------------------------------------------------
1
2 grid.css
3 * Sets up an easy-to-use grid of 24 columns.
4
5 By default, the grid is 950px wide, with 24 columns
6 spanning 30px, and a 10px margin between columns.
7
8 If you need fewer or more columns, namespaces or semantic
9 element names, use the compressor script (lib/compress.rb)
10
11 -------------------------------------------------------------- */
12
13 /* A container should group all your columns. */
14 .container {
15 width: 950px;
16 margin: 0 auto;
17 }
18
19 /* Use this class on any .span / container to see the grid. */
20 .showgrid {
21 background: url(src/grid.png);
22 }
23
24
25 /* Columns
26 -------------------------------------------------------------- */
27
28 /* Sets up basic grid floating and margin. */
29 .column, .span-1, .span-2, .span-3, .span-4, .span-5, .span-6, .span-7, .span-8, .span-9, .span-10, .span-11, .span-12, .span-13, .span-14, .span-15, .span-16, .span-17, .span-18, .span-19, .span-20, .span-21, .span-22, .span-23, .span-24 {
30 float: left;
31 margin-right: 10px;
32 }
33
34 /* The last column in a row needs this class. */
35 .last { margin-right: 0; }
36
37 /* Use these classes to set the width of a column. */
38 .span-1 {width: 30px;}
39
40 .span-2 {width: 70px;}
41 .span-3 {width: 110px;}
42 .span-4 {width: 150px;}
43 .span-5 {width: 190px;}
44 .span-6 {width: 230px;}
45 .span-7 {width: 270px;}
46 .span-8 {width: 310px;}
47 .span-9 {width: 350px;}
48 .span-10 {width: 390px;}
49 .span-11 {width: 430px;}
50 .span-12 {width: 470px;}
51 .span-13 {width: 510px;}
52 .span-14 {width: 550px;}
53 .span-15 {width: 590px;}
54 .span-16 {width: 630px;}
55 .span-17 {width: 670px;}
56 .span-18 {width: 710px;}
57 .span-19 {width: 750px;}
58 .span-20 {width: 790px;}
59 .span-21 {width: 830px;}
60 .span-22 {width: 870px;}
61 .span-23 {width: 910px;}
62 .span-24 {width:950px; margin-right:0;}
63
64 /* Use these classes to set the width of an input. */
65 input.span-1, textarea.span-1, input.span-2, textarea.span-2, input.span-3, textarea.span-3, input.span-4, textarea.span-4, input.span-5, textarea.span-5, input.span-6, textarea.span-6, input.span-7, textarea.span-7, input.span-8, textarea.span-8, input.span-9, textarea.span-9, input.span-10, textarea.span-10, input.span-11, textarea.span-11, input.span-12, textarea.span-12, input.span-13, textarea.span-13, input.span-14, textarea.span-14, input.span-15, textarea.span-15, input.span-16, textarea.span-16, input.span-17, textarea.span-17, input.span-18, textarea.span-18, input.span-19, textarea.span-19, input.span-20, textarea.span-20, input.span-21, textarea.span-21, input.span-22, textarea.span-22, input.span-23, textarea.span-23, input.span-24, textarea.span-24 {
66 border-left-width: 1px!important;
67 border-right-width: 1px!important;
68 padding-left: 5px!important;
69 padding-right: 5px!important;
70 }
71
72 input.span-1, textarea.span-1 { width: 18px!important; }
73 input.span-2, textarea.span-2 { width: 58px!important; }
74 input.span-3, textarea.span-3 { width: 98px!important; }
75 input.span-4, textarea.span-4 { width: 138px!important; }
76 input.span-5, textarea.span-5 { width: 178px!important; }
77 input.span-6, textarea.span-6 { width: 218px!important; }
78 input.span-7, textarea.span-7 { width: 258px!important; }
79 input.span-8, textarea.span-8 { width: 298px!important; }
80 input.span-9, textarea.span-9 { width: 338px!important; }
81 input.span-10, textarea.span-10 { width: 378px!important; }
82 input.span-11, textarea.span-11 { width: 418px!important; }
83 input.span-12, textarea.span-12 { width: 458px!important; }
84 input.span-13, textarea.span-13 { width: 498px!important; }
85 input.span-14, textarea.span-14 { width: 538px!important; }
86 input.span-15, textarea.span-15 { width: 578px!important; }
87 input.span-16, textarea.span-16 { width: 618px!important; }
88 input.span-17, textarea.span-17 { width: 658px!important; }
89 input.span-18, textarea.span-18 { width: 698px!important; }
90 input.span-19, textarea.span-19 { width: 738px!important; }
91 input.span-20, textarea.span-20 { width: 778px!important; }
92 input.span-21, textarea.span-21 { width: 818px!important; }
93 input.span-22, textarea.span-22 { width: 858px!important; }
94 input.span-23, textarea.span-23 { width: 898px!important; }
95 input.span-24, textarea.span-24 { width: 938px!important; }
96
97 /* Add these to a column to append empty cols. */
98
99 .append-1 { padding-right: 40px;}
100 .append-2 { padding-right: 80px;}
101 .append-3 { padding-right: 120px;}
102 .append-4 { padding-right: 160px;}
103 .append-5 { padding-right: 200px;}
104 .append-6 { padding-right: 240px;}
105 .append-7 { padding-right: 280px;}
106 .append-8 { padding-right: 320px;}
107 .append-9 { padding-right: 360px;}
108 .append-10 { padding-right: 400px;}
109 .append-11 { padding-right: 440px;}
110 .append-12 { padding-right: 480px;}
111 .append-13 { padding-right: 520px;}
112 .append-14 { padding-right: 560px;}
113 .append-15 { padding-right: 600px;}
114 .append-16 { padding-right: 640px;}
115 .append-17 { padding-right: 680px;}
116 .append-18 { padding-right: 720px;}
117 .append-19 { padding-right: 760px;}
118 .append-20 { padding-right: 800px;}
119 .append-21 { padding-right: 840px;}
120 .append-22 { padding-right: 880px;}
121 .append-23 { padding-right: 920px;}
122
123 /* Add these to a column to prepend empty cols. */
124
125 .prepend-1 { padding-left: 40px;}
126 .prepend-2 { padding-left: 80px;}
127 .prepend-3 { padding-left: 120px;}
128 .prepend-4 { padding-left: 160px;}
129 .prepend-5 { padding-left: 200px;}
130 .prepend-6 { padding-left: 240px;}
131 .prepend-7 { padding-left: 280px;}
132 .prepend-8 { padding-left: 320px;}
133 .prepend-9 { padding-left: 360px;}
134 .prepend-10 { padding-left: 400px;}
135 .prepend-11 { padding-left: 440px;}
136 .prepend-12 { padding-left: 480px;}
137 .prepend-13 { padding-left: 520px;}
138 .prepend-14 { padding-left: 560px;}
139 .prepend-15 { padding-left: 600px;}
140 .prepend-16 { padding-left: 640px;}
141 .prepend-17 { padding-left: 680px;}
142 .prepend-18 { padding-left: 720px;}
143 .prepend-19 { padding-left: 760px;}
144 .prepend-20 { padding-left: 800px;}
145 .prepend-21 { padding-left: 840px;}
146 .prepend-22 { padding-left: 880px;}
147 .prepend-23 { padding-left: 920px;}
148
149
150 /* Border on right hand side of a column. */
151 .border {
152 padding-right: 4px;
153 margin-right: 5px;
154 border-right: 1px solid #eee;
155 }
156
157 /* Border with more whitespace, spans one column. */
158 .colborder {
159 padding-right: 24px;
160 margin-right: 25px;
161 border-right: 1px solid #eee;
162 }
163
164
165 /* Use these classes on an element to push it into the
166 next column, or to pull it into the previous column. */
167
168
169 .pull-1 { margin-left: -40px; }
170 .pull-2 { margin-left: -80px; }
171 .pull-3 { margin-left: -120px; }
172 .pull-4 { margin-left: -160px; }
173 .pull-5 { margin-left: -200px; }
174 .pull-6 { margin-left: -240px; }
175 .pull-7 { margin-left: -280px; }
176 .pull-8 { margin-left: -320px; }
177 .pull-9 { margin-left: -360px; }
178 .pull-10 { margin-left: -400px; }
179 .pull-11 { margin-left: -440px; }
180 .pull-12 { margin-left: -480px; }
181 .pull-13 { margin-left: -520px; }
182 .pull-14 { margin-left: -560px; }
183 .pull-15 { margin-left: -600px; }
184 .pull-16 { margin-left: -640px; }
185 .pull-17 { margin-left: -680px; }
186 .pull-18 { margin-left: -720px; }
187 .pull-19 { margin-left: -760px; }
188 .pull-20 { margin-left: -800px; }
189 .pull-21 { margin-left: -840px; }
190 .pull-22 { margin-left: -880px; }
191 .pull-23 { margin-left: -920px; }
192 .pull-24 { margin-left: -960px; }
193
194 .pull-1, .pull-2, .pull-3, .pull-4, .pull-5, .pull-6, .pull-7, .pull-8, .pull-9, .pull-10, .pull-11, .pull-12, .pull-13, .pull-14, .pull-15, .pull-16, .pull-17, .pull-18, .pull-19, .pull-20, .pull-21, .pull-22, .pull-23, .pull-24 {float: left; position:relative;}
195
196
197 .push-1 { margin: 0 -40px 1.5em 40px; }
198 .push-2 { margin: 0 -80px 1.5em 80px; }
199 .push-3 { margin: 0 -120px 1.5em 120px; }
200 .push-4 { margin: 0 -160px 1.5em 160px; }
201 .push-5 { margin: 0 -200px 1.5em 200px; }
202 .push-6 { margin: 0 -240px 1.5em 240px; }
203 .push-7 { margin: 0 -280px 1.5em 280px; }
204 .push-8 { margin: 0 -320px 1.5em 320px; }
205 .push-9 { margin: 0 -360px 1.5em 360px; }
206 .push-10 { margin: 0 -400px 1.5em 400px; }
207 .push-11 { margin: 0 -440px 1.5em 440px; }
208 .push-12 { margin: 0 -480px 1.5em 480px; }
209 .push-13 { margin: 0 -520px 1.5em 520px; }
210 .push-14 { margin: 0 -560px 1.5em 560px; }
211 .push-15 { margin: 0 -600px 1.5em 600px; }
212 .push-16 { margin: 0 -640px 1.5em 640px; }
213 .push-17 { margin: 0 -680px 1.5em 680px; }
214 .push-18 { margin: 0 -720px 1.5em 720px; }
215 .push-19 { margin: 0 -760px 1.5em 760px; }
216 .push-20 { margin: 0 -800px 1.5em 800px; }
217 .push-21 { margin: 0 -840px 1.5em 840px; }
218 .push-22 { margin: 0 -880px 1.5em 880px; }
219 .push-23 { margin: 0 -920px 1.5em 920px; }
220 .push-24 { margin: 0 -960px 1.5em 960px; }
221
222 .push-1, .push-2, .push-3, .push-4, .push-5, .push-6, .push-7, .push-8, .push-9, .push-10, .push-11, .push-12, .push-13, .push-14, .push-15, .push-16, .push-17, .push-18, .push-19, .push-20, .push-21, .push-22, .push-23, .push-24 {float: right; position:relative;}
223
224
225 /* Misc classes and elements
226 -------------------------------------------------------------- */
227
228 /* In case you need to add a gutter above/below an element */
229 .prepend-top {
230 margin-top:1.5em;
231 }
232 .append-bottom {
233 margin-bottom:1.5em;
234 }
235
236 /* Use a .box to create a padded box inside a column. */
237 .box {
238 padding: 1.5em;
239 margin-bottom: 1.5em;
240 background: #E5ECF9;
241 }
242
243 /* Use this to create a horizontal ruler across a column. */
244 hr {
245 background: #ddd;
246 color: #ddd;
247 clear: both;
248 float: none;
249 width: 100%;
250 height: .1em;
251 margin: 0 0 1.45em;
252 border: none;
253 }
254
255 hr.space {
256 background: #fff;
257 color: #fff;
258 visibility: hidden;
259 }
260
261
262 /* Clearing floats without extra markup
263 Based on How To Clear Floats Without Structural Markup by PiE
264 [http://www.positioniseverything.net/easyclearing.html] */
265
266 .clearfix:after, .container:after {
267 content: "\0020";
268 display: block;
269 height: 0;
270 clear: both;
271 visibility: hidden;
272 overflow:hidden;
273 }
274 .clearfix, .container {display: block;}
275
276 /* Regular clearing
277 apply to column that should drop below previous ones. */
278
279 .clear { clear:both; }
0 /* --------------------------------------------------------------
1
2 ie.css
3
4 Contains every hack for Internet Explorer,
5 so that our core files stay sweet and nimble.
6
7 -------------------------------------------------------------- */
8
9 /* Make sure the layout is centered in IE5 */
10 body { text-align: center; }
11 .container { text-align: left; }
12
13 /* Fixes IE margin bugs */
14 * html .column, * html .span-1, * html .span-2,
15 * html .span-3, * html .span-4, * html .span-5,
16 * html .span-6, * html .span-7, * html .span-8,
17 * html .span-9, * html .span-10, * html .span-11,
18 * html .span-12, * html .span-13, * html .span-14,
19 * html .span-15, * html .span-16, * html .span-17,
20 * html .span-18, * html .span-19, * html .span-20,
21 * html .span-21, * html .span-22, * html .span-23,
22 * html .span-24 { display:inline; overflow-x: hidden; }
23
24
25 /* Elements
26 -------------------------------------------------------------- */
27
28 /* Fixes incorrect styling of legend in IE6. */
29 * html legend { margin:0px -8px 16px 0; padding:0; }
30
31 /* Fixes wrong line-height on sup/sub in IE. */
32 sup { vertical-align:text-top; }
33 sub { vertical-align:text-bottom; }
34
35 /* Fixes IE7 missing wrapping of code elements. */
36 html>body p code { *white-space: normal; }
37
38 /* IE 6&7 has problems with setting proper <hr> margins. */
39 hr { margin:-8px auto 11px; }
40
41 /* Explicitly set interpolation, allowing dynamically resized images to not look horrible */
42 img { -ms-interpolation-mode:bicubic; }
43
44 /* Clearing
45 -------------------------------------------------------------- */
46
47 /* Makes clearfix actually work in IE */
48 .clearfix, .container { display:inline-block; }
49 * html .clearfix,
50 * html .container { height:1%; }
51
52
53 /* Forms
54 -------------------------------------------------------------- */
55
56 /* Fixes padding on fieldset */
57 fieldset { padding-top:0; }
58
59 /* Makes classic textareas in IE 6 resemble other browsers */
60 textarea { overflow:auto; }
61
62 /* Fixes rule that IE 6 ignores */
63 input.text, input.title, textarea { background-color:#fff; border:1px solid #bbb; }
64 input.text:focus, input.title:focus { border-color:#666; }
65 input.text, input.title, textarea, select { margin:0.5em 0; }
66 input.checkbox, input.radio { position:relative; top:.25em; }
67
68 /* Fixes alignment of inline form elements */
69 form.inline div, form.inline p { vertical-align:middle; }
70 form.inline label { position:relative;top:-0.25em; }
71 form.inline input.checkbox, form.inline input.radio,
72 form.inline input.button, form.inline button {
73 margin:0.5em 0;
74 }
75 button, input.button { position:relative;top:0.25em; }
0 /* --------------------------------------------------------------
1
2 print.css
3 * Gives you some sensible styles for printing pages.
4 * See Readme file in this directory for further instructions.
5
6 Some additions you'll want to make, customized to your markup:
7 #header, #footer, #navigation { display:none; }
8
9 -------------------------------------------------------------- */
10
11 body {
12 line-height: 1.5;
13 font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;
14 color:#000;
15 background: none;
16 font-size: 10pt;
17 }
18
19
20 /* Layout
21 -------------------------------------------------------------- */
22
23 .container {
24 background: none;
25 }
26
27 hr {
28 background:#ccc;
29 color:#ccc;
30 width:100%;
31 height:2px;
32 margin:2em 0;
33 padding:0;
34 border:none;
35 }
36 hr.space {
37 background: #fff;
38 color: #fff;
39 visibility: hidden;
40 }
41
42
43 /* Text
44 -------------------------------------------------------------- */
45
46 h1,h2,h3,h4,h5,h6 { font-family: "Helvetica Neue", Arial, "Lucida Grande", sans-serif; }
47 code { font:.9em "Courier New", Monaco, Courier, monospace; }
48
49 a img { border:none; }
50 p img.top { margin-top: 0; }
51
52 blockquote {
53 margin:1.5em;
54 padding:1em;
55 font-style:italic;
56 font-size:.9em;
57 }
58
59 .small { font-size: .9em; }
60 .large { font-size: 1.1em; }
61 .quiet { color: #999; }
62 .hide { display:none; }
63
64
65 /* Links
66 -------------------------------------------------------------- */
67
68 a:link, a:visited {
69 background: transparent;
70 font-weight:700;
71 text-decoration: underline;
72 }
73
74 a:link:after, a:visited:after {
75 content: " (" attr(href) ")";
76 font-size: 90%;
77 }
78
79 /* If you're having trouble printing relative links, uncomment and customize this:
80 (note: This is valid CSS3, but it still won't go through the W3C CSS Validator) */
81
82 /* a[href^="/"]:after {
83 content: " (http://www.yourdomain.com" attr(href) ") ";
84 } */
0 /* --------------------------------------------------------------
1
2 reset.css
3 * Resets default browser CSS.
4
5 -------------------------------------------------------------- */
6
7 html, body, div, span, object, iframe,
8 h1, h2, h3, h4, h5, h6, p, blockquote, pre,
9 a, abbr, acronym, address, code,
10 del, dfn, em, img, q, dl, dt, dd, ol, ul, li,
11 fieldset, form, label, legend,
12 table, caption, tbody, tfoot, thead, tr, th, td,
13 article, aside, dialog, figure, footer, header,
14 hgroup, nav, section {
15 margin: 0;
16 padding: 0;
17 border: 0;
18 font-weight: inherit;
19 font-style: inherit;
20 font-size: 100%;
21 font-family: inherit;
22 vertical-align: baseline;
23 }
24
25 article, aside, dialog, figure, footer, header,
26 hgroup, nav, section {
27 display:block;
28 }
29
30 body {
31 line-height: 1.5;
32 }
33
34 /* Tables still need 'cellspacing="0"' in the markup. */
35 table { border-collapse: separate; border-spacing: 0; }
36 caption, th, td { text-align: left; font-weight: normal; }
37 table, td, th { vertical-align: middle; }
38
39 /* Remove possible quote marks (") from <q>, <blockquote>. */
40 blockquote:before, blockquote:after, q:before, q:after { content: ""; }
41 blockquote, q { quotes: "" ""; }
42
43 /* Remove annoying border on linked images. */
44 a img { border: none; }
0 /* --------------------------------------------------------------
1
2 typography.css
3 * Sets up some sensible default typography.
4
5 -------------------------------------------------------------- */
6
7 /* Default font settings.
8 The font-size percentage is of 16px. (0.75 * 16px = 12px) */
9 html { font-size:100.01%; }
10 body {
11 font-size: 75%;
12 color: #222;
13 background: #fff;
14 font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;
15 }
16
17
18 /* Headings
19 -------------------------------------------------------------- */
20
21 h1,h2,h3,h4,h5,h6 { font-weight: normal; color: #111; }
22
23 h1 { font-size: 3em; line-height: 1; margin-bottom: 0.5em; }
24 h2 { font-size: 2em; margin-bottom: 0.75em; }
25 h3 { font-size: 1.5em; line-height: 1; margin-bottom: 1em; }
26 h4 { font-size: 1.2em; line-height: 1.25; margin-bottom: 1.25em; }
27 h5 { font-size: 1em; font-weight: bold; margin-bottom: 1.5em; }
28 h6 { font-size: 1em; font-weight: bold; }
29
30 h1 img, h2 img, h3 img,
31 h4 img, h5 img, h6 img {
32 margin: 0;
33 }
34
35
36 /* Text elements
37 -------------------------------------------------------------- */
38
39 p { margin: 0 0 1.5em; }
40 p img.left { float: left; margin: 1.5em 1.5em 1.5em 0; padding: 0; }
41 p img.right { float: right; margin: 1.5em 0 1.5em 1.5em; }
42
43 a:focus,
44 a:hover { color: #000; }
45 a { color: #009; text-decoration: underline; }
46
47 blockquote { margin: 1.5em; color: #666; font-style: italic; }
48 strong { font-weight: bold; }
49 em,dfn { font-style: italic; }
50 dfn { font-weight: bold; }
51 sup, sub { line-height: 0; }
52
53 abbr,
54 acronym { border-bottom: 1px dotted #666; }
55 address { margin: 0 0 1.5em; font-style: italic; }
56 del { color:#666; }
57
58 pre { margin: 1.5em 0; white-space: pre; }
59 pre,code,tt { font: 1em 'andale mono', 'lucida console', monospace; line-height: 1.5; }
60
61
62 /* Lists
63 -------------------------------------------------------------- */
64
65 li ul,
66 li ol { margin: 0; }
67 ul, ol { margin: 0 1.5em 1.5em 0; padding-left: 3.333em; }
68
69 ul { list-style-type: disc; }
70 ol { list-style-type: decimal; }
71
72 dl { margin: 0 0 1.5em 0; }
73 dl dt { font-weight: bold; }
74 dd { margin-left: 1.5em;}
75
76
77 /* Tables
78 -------------------------------------------------------------- */
79
80 table { margin-bottom: 1.4em; width:100%; }
81 th { font-weight: bold; }
82 thead th { background: #c3d9ff; }
83 th,td,caption { padding: 4px 10px 4px 5px; }
84 tr.even td { background: #e5ecf9; }
85 tfoot { font-style: italic; }
86 caption { background: #eee; }
87
88
89 /* Misc classes
90 -------------------------------------------------------------- */
91
92 .small { font-size: .8em; margin-bottom: 1.875em; line-height: 1.875em; }
93 .large { font-size: 1.2em; line-height: 2.5em; margin-bottom: 1.25em; }
94 .hide { display: none; }
95
96 .quiet { color: #666; }
97 .loud { color: #000; }
98 .highlight { background:#ff0; }
99 .added { background:#060; color: #fff; }
100 .removed { background:#900; color: #fff; }
101
102 .first { margin-left:0; padding-left:0; }
103 .last { margin-right:0; padding-right:0; }
104 .top { margin-top:0; padding-top:0; }
105 .bottom { margin-bottom:0; padding-bottom:0; }
0 body {
1 margin: 2em 4em;
2 font-family: "Trebuchet MS", lucida, sans-serif;
3 line-height: 1.5;
4 color: black; background-color: white;
5 }
6
7 h1 { margin: 0 0 .75em 0; text-align: center; font-size: 200%; }
8
9 table { width: 48em; margin: 0 auto; border-spacing: 0; border-collapse: collapse; }
10 table td, table th { border: 1px solid silver; padding: .25em 1em; }
11 table td .unit { font-size: 75%; color: gray; }
12 table td.no-results { padding: 1em; text-align: center; }
13 table td.input-size { text-align: right; }
14 table td.parse-time { text-align: right; }
15 table td.parse-speed { text-align: right; }
16 table tr.columns th { border-color: #404040; color: white; background-color: #404040; }
17 table tr.heading th { background-color: #e0e0e0; }
18 table tr.benchmark-total td { font-weight: bold; }
19 table tr.total td { background-color: #ffff80; font-weight: bold; }
20 table tr.total td .unit { color: #808000; }
21 table tr.total td.parse-speed .value { font-size: 175%; }
22
23 a, a:visited { color: #3d586c; }
24
25 #options {
26 width: 45em;
27 margin: 2em auto; border-radius: .5em; -moz-border-radius: .5em; padding: .5em 1.5em;
28 background-color: #f0f0f0;
29 }
30 #options #run-count { width: 3em; }
31 #options #cache { margin-left: 2em; }
32 #options label[for=optimize] { margin-left: 2em; }
33 #options #run { float:right; width: 5em; }
0 <!DOCTYPE html>
1 <html>
2 <head>
3 <meta charset="utf-8">
4 <title>PEG.js Benchmark Suite</title>
5 <link rel="stylesheet" href="index.css">
6 </head>
7 <body>
8 <h1>PEG.js Benchmark Suite</h1>
9
10 <div id="options">
11 <label for="run-count">Run each test</label>
12 <input type="text" id="run-count" value="10"> times
13 <input type="checkbox" id="cache">
14 <label for="cache">Use results cache</label>
15 <label for="optimize">Optimize:</label>
16 <select id="optimize">
17 <option value="speed">Speed</option>
18 <option value="size">Size</option>
19 </select>
20 <input type="button" id="run" value="Run">
21 </div>
22
23 <table id="results-table">
24 <tr class="columns">
25 <th>Test</th>
26 <th>Input Size</th>
27 <th>Average Parse Time</th>
28 <th>Average Parse Speed</th>
29 </tr>
30 <tr>
31 <td class="no-results" colspan="4">No results available yet.</td>
32 </tr>
33 </table>
34
35 <script src="../browser/peg-0.10.0.js"></script>
36 <script src="vendor/jquery/jquery.js"></script>
37 <script src="vendor/jquery.scrollto/jquery.scrollTo.js"></script>
38 <script src="benchmarks.js"></script>
39 <script src="runner.js"></script>
40 <script src="index.js"></script>
41 </body>
42 </html>
0 /* eslint-env browser, jquery */
1 /* global benchmarks, Runner */
2
3 $("#run").click(function() {
4 "use strict";
5
6 /* Results Table Manipulation */
7
8 var resultsTable = $("#results-table");
9
10 function appendHeading(heading) {
11 resultsTable.append(
12 "<tr class='heading'><th colspan='4'>" + heading + "</th></tr>"
13 );
14 }
15
16 function appendResult(klass, title, url, inputSize, parseTime) {
17 var KB = 1024,
18 MS_IN_S = 1000;
19
20 resultsTable.append(
21 "<tr class='" + klass + "'>"
22 + "<td class='title'>"
23 + (url !== null ? "<a href='" + url + "'>" : "")
24 + title
25 + (url !== null ? "</a>" : "")
26 + "</td>"
27 + "<td class='input-size'>"
28 + "<span class='value'>"
29 + (inputSize / KB).toFixed(2)
30 + "</span>"
31 + "&nbsp;<span class='unit'>kB</span>"
32 + "</td>"
33 + "<td class='parse-time'>"
34 + "<span class='value'>"
35 + parseTime.toFixed(2)
36 + "</span>"
37 + "&nbsp;<span class='unit'>ms</span>"
38 + "</td>"
39 + "<td class='parse-speed'>"
40 + "<span class='value'>"
41 + ((inputSize / KB) / (parseTime / MS_IN_S)).toFixed(2)
42 + "</span>"
43 + "&nbsp;<span class='unit'>kB/s</span>"
44 + "</td>"
45 + "</tr>"
46 );
47 }
48
49 /* Main */
50
51 /*
52 * Each input is parsed multiple times and the results are averaged. We
53 * do this for two reasons:
54 *
55 * 1. To warm up the interpreter (PEG.js-generated parsers will be
56 * most likely used repeatedly, so it makes sense to measure
57 * performance after warming up).
58 *
59 * 2. To minimize random errors.
60 */
61
62 var runCount = parseInt($("#run-count").val(), 10),
63 options = {
64 cache: $("#cache").is(":checked"),
65 optimize: $("#optimize").val()
66 };
67
68 if (isNaN(runCount) || runCount <= 0) {
69 alert("Number of runs must be a positive integer.");
70 return;
71 }
72
73 Runner.run(benchmarks, runCount, options, {
74 readFile: function(file) {
75 return $.ajax({
76 type: "GET",
77 url: file,
78 dataType: "text",
79 async: false
80 }).responseText;
81 },
82
83 testStart: function() {
84 /* Nothing to do. */
85 },
86
87 testFinish: function(benchmark, test, inputSize, parseTime) {
88 appendResult(
89 "individual",
90 test.title,
91 benchmark.id + "/" + test.file,
92 inputSize,
93 parseTime
94 );
95 },
96
97 benchmarkStart: function(benchmark) {
98 appendHeading(benchmark.title);
99 },
100
101 benchmarkFinish: function(benchmark, inputSize, parseTime) {
102 appendResult(
103 "benchmark-total",
104 benchmark.title + " total",
105 null,
106 inputSize,
107 parseTime
108 );
109 },
110
111 start: function() {
112 $("#run-count, #cache, #run").attr("disabled", "disabled");
113
114 resultsTable.show();
115 $("#results-table tr").slice(1).remove();
116 },
117
118 finish: function(inputSize, parseTime) {
119 appendResult(
120 "total",
121 "Total",
122 null,
123 inputSize,
124 parseTime
125 );
126
127 $.scrollTo("max", { axis: "y", duration: 500 });
128
129 $("#run-count, #cache, #run").removeAttr("disabled");
130 }
131 });
132
133 });
134
135 $(document).ready(function() {
136 "use strict";
137
138 $("#run").focus();
139 });
0 {
1 "glossary": {
2 "title": "example glossary",
3 "GlossDiv": {
4 "title": "S",
5 "GlossList": {
6 "GlossEntry": {
7 "ID": "SGML",
8 "SortAs": "SGML",
9 "GlossTerm": "Standard Generalized Markup Language",
10 "Acronym": "SGML",
11 "Abbrev": "ISO 8879:1986",
12 "GlossDef": {
13 "para": "A meta-markup language, used to create markup languages such as DocBook.",
14 "GlossSeeAlso": ["GML", "XML"]
15 },
16 "GlossSee": "markup"
17 }
18 }
19 }
20 }
21 }
0 {"menu": {
1 "id": "file",
2 "value": "File",
3 "popup": {
4 "menuitem": [
5 {"value": "New", "onclick": "CreateNewDoc()"},
6 {"value": "Open", "onclick": "OpenDoc()"},
7 {"value": "Close", "onclick": "CloseDoc()"}
8 ]
9 }
10 }}
0 {"widget": {
1 "debug": "on",
2 "window": {
3 "title": "Sample Konfabulator Widget",
4 "name": "main_window",
5 "width": 500,
6 "height": 500
7 },
8 "image": {
9 "src": "Images/Sun.png",
10 "name": "sun1",
11 "hOffset": 250,
12 "vOffset": 250,
13 "alignment": "center"
14 },
15 "text": {
16 "data": "Click Here",
17 "size": 36,
18 "style": "bold",
19 "name": "text1",
20 "hOffset": 250,
21 "vOffset": 100,
22 "alignment": "center",
23 "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;"
24 }
25 }}
0 {"web-app": {
1 "servlet": [
2 {
3 "servlet-name": "cofaxCDS",
4 "servlet-class": "org.cofax.cds.CDSServlet",
5 "init-param": {
6 "configGlossary:installationAt": "Philadelphia, PA",
7 "configGlossary:adminEmail": "ksm@pobox.com",
8 "configGlossary:poweredBy": "Cofax",
9 "configGlossary:poweredByIcon": "/images/cofax.gif",
10 "configGlossary:staticPath": "/content/static",
11 "templateProcessorClass": "org.cofax.WysiwygTemplate",
12 "templateLoaderClass": "org.cofax.FilesTemplateLoader",
13 "templatePath": "templates",
14 "templateOverridePath": "",
15 "defaultListTemplate": "listTemplate.htm",
16 "defaultFileTemplate": "articleTemplate.htm",
17 "useJSP": false,
18 "jspListTemplate": "listTemplate.jsp",
19 "jspFileTemplate": "articleTemplate.jsp",
20 "cachePackageTagsTrack": 200,
21 "cachePackageTagsStore": 200,
22 "cachePackageTagsRefresh": 60,
23 "cacheTemplatesTrack": 100,
24 "cacheTemplatesStore": 50,
25 "cacheTemplatesRefresh": 15,
26 "cachePagesTrack": 200,
27 "cachePagesStore": 100,
28 "cachePagesRefresh": 10,
29 "cachePagesDirtyRead": 10,
30 "searchEngineListTemplate": "forSearchEnginesList.htm",
31 "searchEngineFileTemplate": "forSearchEngines.htm",
32 "searchEngineRobotsDb": "WEB-INF/robots.db",
33 "useDataStore": true,
34 "dataStoreClass": "org.cofax.SqlDataStore",
35 "redirectionClass": "org.cofax.SqlRedirection",
36 "dataStoreName": "cofax",
37 "dataStoreDriver": "com.microsoft.jdbc.sqlserver.SQLServerDriver",
38 "dataStoreUrl": "jdbc:microsoft:sqlserver://LOCALHOST:1433;DatabaseName=goon",
39 "dataStoreUser": "sa",
40 "dataStorePassword": "dataStoreTestQuery",
41 "dataStoreTestQuery": "SET NOCOUNT ON;select test='test';",
42 "dataStoreLogFile": "/usr/local/tomcat/logs/datastore.log",
43 "dataStoreInitConns": 10,
44 "dataStoreMaxConns": 100,
45 "dataStoreConnUsageLimit": 100,
46 "dataStoreLogLevel": "debug",
47 "maxUrlLength": 500}},
48 {
49 "servlet-name": "cofaxEmail",
50 "servlet-class": "org.cofax.cds.EmailServlet",
51 "init-param": {
52 "mailHost": "mail1",
53 "mailHostOverride": "mail2"}},
54 {
55 "servlet-name": "cofaxAdmin",
56 "servlet-class": "org.cofax.cds.AdminServlet"},
57
58 {
59 "servlet-name": "fileServlet",
60 "servlet-class": "org.cofax.cds.FileServlet"},
61 {
62 "servlet-name": "cofaxTools",
63 "servlet-class": "org.cofax.cms.CofaxToolsServlet",
64 "init-param": {
65 "templatePath": "toolstemplates/",
66 "log": 1,
67 "logLocation": "/usr/local/tomcat/logs/CofaxTools.log",
68 "logMaxSize": "",
69 "dataLog": 1,
70 "dataLogLocation": "/usr/local/tomcat/logs/dataLog.log",
71 "dataLogMaxSize": "",
72 "removePageCache": "/content/admin/remove?cache=pages&id=",
73 "removeTemplateCache": "/content/admin/remove?cache=templates&id=",
74 "fileTransferFolder": "/usr/local/tomcat/webapps/content/fileTransferFolder",
75 "lookInContext": 1,
76 "adminGroupID": 4,
77 "betaServer": true}}],
78 "servlet-mapping": {
79 "cofaxCDS": "/",
80 "cofaxEmail": "/cofaxutil/aemail/*",
81 "cofaxAdmin": "/admin/*",
82 "fileServlet": "/static/*",
83 "cofaxTools": "/tools/*"},
84
85 "taglib": {
86 "taglib-uri": "cofax.tld",
87 "taglib-location": "/WEB-INF/tlds/cofax.tld"}}}
0 {"menu": {
1 "header": "SVG Viewer",
2 "items": [
3 {"id": "Open"},
4 {"id": "OpenNew", "label": "Open New"},
5 null,
6 {"id": "ZoomIn", "label": "Zoom In"},
7 {"id": "ZoomOut", "label": "Zoom Out"},
8 {"id": "OriginalView", "label": "Original View"},
9 null,
10 {"id": "Quality"},
11 {"id": "Pause"},
12 {"id": "Mute"},
13 null,
14 {"id": "Find", "label": "Find..."},
15 {"id": "FindAgain", "label": "Find Again"},
16 {"id": "Copy"},
17 {"id": "CopyAgain", "label": "Copy Again"},
18 {"id": "CopySVG", "label": "Copy SVG"},
19 {"id": "ViewSVG", "label": "View SVG"},
20 {"id": "ViewSource", "label": "View Source"},
21 {"id": "SaveAs", "label": "Save As"},
22 null,
23 {"id": "Help"},
24 {"id": "About", "label": "About Adobe CVG Viewer..."}
25 ]
26 }}
0 #!/usr/bin/env node
1
2 /* eslint-env node */
3 /* eslint no-console: 0*/
4
5 "use strict";
6
7 var fs = require("fs");
8 var peg = require("../lib/peg");
9
10 var benchmarks = require("./benchmarks.js");
11 var Runner = require("./runner.js")(peg);
12
13 /* Results Table Manipulation */
14
15 function dup(text, count) {
16 var result = "";
17 for (var i = 1; i <= count; i++) {
18 result += text;
19 }
20 return result;
21 }
22
23 function padLeft(text, length) {
24 return dup(" ", length - text.length) + text;
25 }
26
27 function padRight(text, length) {
28 return text + dup(" ", length - text.length);
29 }
30
31 function center(text, length) {
32 var padLength = (length - text.length) / 2;
33 return dup(" ", Math.floor(padLength))
34 + text
35 + dup(" ", Math.ceil(padLength));
36 }
37
38 function writeTableHeader() {
39 console.log("┌─────────────────────────────────────┬───────────┬────────────┬──────────────┐");
40 console.log("│ Test │ Inp. size │ Avg. time │ Avg. speed │");
41 }
42
43 function writeHeading(heading) {
44 console.log("├─────────────────────────────────────┴───────────┴────────────┴──────────────┤");
45 console.log("│ " + center(heading, 75) + " │");
46 console.log("├─────────────────────────────────────┬───────────┬────────────┬──────────────┤");
47 }
48
49 function writeResult(title, inputSize, parseTime) {
50 var KB = 1024;
51 var MS_IN_S = 1000;
52
53 console.log("│ "
54 + padRight(title, 35)
55 + " │ "
56 + padLeft((inputSize / KB).toFixed(2), 6)
57 + " kB │ "
58 + padLeft(parseTime.toFixed(2), 7)
59 + " ms │ "
60 + padLeft(((inputSize / KB) / (parseTime / MS_IN_S)).toFixed(2), 7)
61 + " kB/s │"
62 );
63 }
64
65 function writeSeparator() {
66 console.log("├─────────────────────────────────────┼───────────┼────────────┼──────────────┤");
67 }
68
69 function writeTableFooter() {
70 console.log("└─────────────────────────────────────┴───────────┴────────────┴──────────────┘");
71 }
72
73 /* Helpers */
74
75 function printHelp() {
76 console.log("Usage: run [options]");
77 console.log("");
78 console.log("Runs PEG.js benchmark suite.");
79 console.log("");
80 console.log("Options:");
81 console.log(" -n, --run-count <n> number of runs (default: 10)");
82 console.log(" --cache make tested parsers cache results");
83 console.log(" -o, --optimize <goal> select optimization for speed or size (default:");
84 console.log(" speed)");
85 }
86
87 function exitSuccess() {
88 process.exit(0);
89 }
90
91 function exitFailure() {
92 process.exit(1);
93 }
94
95 function abort(message) {
96 console.error(message);
97 exitFailure();
98 }
99
100 /* Arguments */
101
102 var args = process.argv.slice(2); // Trim "node" and the script path.
103
104 function isOption(arg) {
105 return (/^-/).test(arg);
106 }
107
108 function nextArg() {
109 args.shift();
110 }
111
112 /* Main */
113
114 var runCount = 10;
115 var options = {
116 cache: false,
117 optimize: "speed"
118 };
119
120 while (args.length > 0 && isOption(args[0])) {
121 switch (args[0]) {
122 case "-n":
123 case "--run-count":
124 nextArg();
125 if (args.length === 0) {
126 abort("Missing parameter of the -n/--run-count option.");
127 }
128 runCount = parseInt(args[0], 10);
129 if (isNaN(runCount) || runCount <= 0) {
130 abort("Number of runs must be a positive integer.");
131 }
132 break;
133
134 case "--cache":
135 options.cache = true;
136 break;
137
138 case "-o":
139 case "--optimize":
140 nextArg();
141 if (args.length === 0) {
142 abort("Missing parameter of the -o/--optimize option.");
143 }
144 if (args[0] !== "speed" && args[0] !== "size") {
145 abort("Optimization goal must be either \"speed\" or \"size\".");
146 }
147 options.optimize = args[0];
148 break;
149
150 case "-h":
151 case "--help":
152 printHelp();
153 exitSuccess();
154 break;
155
156 default:
157 abort("Unknown option: " + args[0] + ".");
158 }
159 nextArg();
160 }
161
162 if (args.length > 0) {
163 abort("No arguments are allowed.");
164 }
165
166 Runner.run(benchmarks, runCount, options, {
167 readFile: function(file) {
168 return fs.readFileSync(__dirname + "/" + file, "utf8");
169 },
170
171 testStart: function() {
172 /* Nothing to do. */
173 },
174
175 testFinish: function(benchmark, test, inputSize, parseTime) {
176 writeResult(test.title, inputSize, parseTime);
177 },
178
179 benchmarkStart: function(benchmark) {
180 writeHeading(benchmark.title);
181 },
182
183 benchmarkFinish: function(benchmark, inputSize, parseTime) {
184 writeSeparator();
185 writeResult(benchmark.title + " total", inputSize, parseTime);
186 },
187
188 start: function() {
189 writeTableHeader();
190 },
191
192 finish: function(inputSize, parseTime) {
193 writeSeparator();
194 writeResult("Total", inputSize, parseTime);
195 writeTableFooter();
196 }
197 });
0 /* global module, setTimeout */
1
2 "use strict";
3
4 (function(root, factory) {
5 if (typeof module !== 'undefined' && module.exports) {
6 module.exports = factory;
7 } else {
8 root.Runner = factory(root.peg);
9 }
10 }(this, function(peg) {
11
12 return {
13 run: function(benchmarks, runCount, options, callbacks) {
14
15 /* Queue */
16
17 var Q = {
18 functions: [],
19
20 add: function(f) {
21 this.functions.push(f);
22 },
23
24 run: function() {
25 if (this.functions.length > 0) {
26 this.functions.shift()();
27
28 /*
29 * We can't use |arguments.callee| here because |this| would get
30 * messed-up in that case.
31 */
32 setTimeout(function() { Q.run(); }, 0);
33 }
34 }
35 };
36
37 /*
38 * The benchmark itself is factored out into several functions (some of them
39 * generated), which are enqueued and run one by one using |setTimeout|. We
40 * do this for two reasons:
41 *
42 * 1. To avoid bowser mechanism for interrupting long-running scripts to
43 * kick-in (or at least to not kick-in that often).
44 *
45 * 2. To ensure progressive rendering of results in the browser (some
46 * browsers do not render at all when running JavaScript code).
47 *
48 * The enqueued functions share state, which is all stored in the properties
49 * of the |state| object.
50 */
51
52 var state = {}, i, j;
53
54 function initialize() {
55 callbacks.start();
56
57 state.totalInputSize = 0;
58 state.totalParseTime = 0;
59 }
60
61 function benchmarkInitializer(i) {
62 return function() {
63 callbacks.benchmarkStart(benchmarks[i]);
64
65 state.parser = peg.generate(
66 callbacks.readFile("../examples/" + benchmarks[i].id + ".pegjs"),
67 options
68 );
69 state.benchmarkInputSize = 0;
70 state.benchmarkParseTime = 0;
71 };
72 }
73
74 function testRunner(i, j) {
75 return function() {
76 var benchmark = benchmarks[i],
77 test = benchmark.tests[j],
78 input, parseTime, averageParseTime, k, t;
79
80 callbacks.testStart(benchmark, test);
81
82 input = callbacks.readFile(benchmark.id + "/" + test.file);
83
84 parseTime = 0;
85 for (k = 0; k < runCount; k++) {
86 t = (new Date()).getTime();
87 state.parser.parse(input);
88 parseTime += (new Date()).getTime() - t;
89 }
90 averageParseTime = parseTime / runCount;
91
92 callbacks.testFinish(benchmark, test, input.length, averageParseTime);
93
94 state.benchmarkInputSize += input.length;
95 state.benchmarkParseTime += averageParseTime;
96 };
97 }
98
99 function benchmarkFinalizer(i) {
100 return function() {
101 callbacks.benchmarkFinish(
102 benchmarks[i],
103 state.benchmarkInputSize,
104 state.benchmarkParseTime
105 );
106
107 state.totalInputSize += state.benchmarkInputSize;
108 state.totalParseTime += state.benchmarkParseTime;
109 };
110 }
111
112 function finalize() {
113 callbacks.finish(state.totalInputSize, state.totalParseTime);
114 }
115
116 /* Main */
117
118 Q.add(initialize);
119 for (i = 0; i < benchmarks.length; i++) {
120 Q.add(benchmarkInitializer(i));
121 for (j = 0; j < benchmarks[i].tests.length; j++) {
122 Q.add(testRunner(i, j));
123 }
124 Q.add(benchmarkFinalizer(i));
125 }
126 Q.add(finalize);
127
128 Q.run();
129 }
130 };
131
132 }));
0 Copyright jQuery Foundation and other contributors, https://jquery.org/
1
2 This software consists of voluntary contributions made by many
3 individuals. For exact contribution history, see the revision history
4 available at https://github.com/jquery/jquery
5
6 The following license applies to all parts of this software except as
7 documented below:
8
9 ====
10
11 Permission is hereby granted, free of charge, to any person obtaining
12 a copy of this software and associated documentation files (the
13 "Software"), to deal in the Software without restriction, including
14 without limitation the rights to use, copy, modify, merge, publish,
15 distribute, sublicense, and/or sell copies of the Software, and to
16 permit persons to whom the Software is furnished to do so, subject to
17 the following conditions:
18
19 The above copyright notice and this permission notice shall be
20 included in all copies or substantial portions of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
30 ====
31
32 All files located in the node_modules and external directories are
33 externally maintained libraries used by this software which have their
34 own licenses; we recommend you read them, as their terms may differ from
35 the terms above.
0 /*! jQuery v1.12.4 | (c) jQuery Foundation | jquery.org/license */
1 !function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m="1.12.4",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:g,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!k.call(a,"constructor")&&!k.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(!l.ownFirst)for(b in a)return k.call(a,b);for(b in a);return void 0===b||k.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?i[j.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):g.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(h)return h.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=e.call(arguments,2),d=function(){return a.apply(b||this,c.concat(e.call(arguments)))},d.guid=a.guid=a.guid||n.guid++,d):void 0},now:function(){return+new Date},support:l}),"function"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){i["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=!!a&&"length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ga(),z=ga(),A=ga(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+M+"))|)"+L+"*\\]",O=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+N+")*)|.*)\\)|)",P=new RegExp(L+"+","g"),Q=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),R=new RegExp("^"+L+"*,"+L+"*"),S=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),T=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),U=new RegExp(O),V=new RegExp("^"+M+"$"),W={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M+"|[*])"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Z=/^[^{]+\{\s*\[native \w/,$=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,_=/[+~]/,aa=/'|\\/g,ba=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),ca=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},da=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(ea){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==x&&9!==x&&11!==x)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==x&&(o=$.exec(a)))if(f=o[1]){if(9===x){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(w&&(j=w.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(o[2])return H.apply(d,b.getElementsByTagName(a)),d;if((f=o[3])&&c.getElementsByClassName&&b.getElementsByClassName)return H.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==x)w=b,s=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(aa,"\\$&"):b.setAttribute("id",k=u),r=g(a),h=r.length,l=V.test(k)?"#"+k:"[id='"+k+"']";while(h--)r[h]=l+" "+qa(r[h]);s=r.join(","),w=_.test(a)&&oa(b.parentNode)||b}if(s)try{return H.apply(d,w.querySelectorAll(s)),d}catch(y){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(Q,"$1"),b,d,e)}function ga(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ha(a){return a[u]=!0,a}function ia(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ja(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function ka(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function la(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function na(a){return ha(function(b){return b=+b,ha(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function oa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=fa.support={},f=fa.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fa.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ia(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ia(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Z.test(n.getElementsByClassName),c.getById=ia(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Z.test(n.querySelectorAll))&&(ia(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\r\\' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ia(function(a){var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Z.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ia(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",O)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Z.test(o.compareDocumentPosition),t=b||Z.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return ka(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?ka(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},fa.matches=function(a,b){return fa(a,null,null,b)},fa.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(T,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fa(b,n,null,[a]).length>0},fa.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fa.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fa.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fa.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fa.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fa.selectors={cacheLength:50,createPseudo:ha,match:W,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ba,ca),a[3]=(a[3]||a[4]||a[5]||"").replace(ba,ca),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fa.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fa.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return W.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&U.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ba,ca).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fa.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(P," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fa.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ha(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ha(function(a){var b=[],c=[],d=h(a.replace(Q,"$1"));return d[u]?ha(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ha(function(a){return function(b){return fa(a,b).length>0}}),contains:ha(function(a){return a=a.replace(ba,ca),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ha(function(a){return V.test(a||"")||fa.error("unsupported lang: "+a),a=a.replace(ba,ca).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Y.test(a.nodeName)},input:function(a){return X.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:na(function(){return[0]}),last:na(function(a,b){return[b-1]}),eq:na(function(a,b,c){return[0>c?c+b:c]}),even:na(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:na(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:na(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:na(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=la(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=ma(b);function pa(){}pa.prototype=d.filters=d.pseudos,d.setFilters=new pa,g=fa.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){c&&!(e=R.exec(h))||(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=S.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(Q," ")}),h=h.slice(c.length));for(g in d.filter)!(e=W[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?fa.error(a):z(a,i).slice(0)};function qa(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function ra(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j,k=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(j=b[u]||(b[u]={}),i=j[b.uniqueID]||(j[b.uniqueID]={}),(h=i[d])&&h[0]===w&&h[1]===f)return k[2]=h[2];if(i[d]=k,k[2]=a(b,c,g))return!0}}}function sa(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}function ua(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)),ha(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ta(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ua(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ua(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ua(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ra(function(a){return a===b},h,!0),l=ra(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ra(sa(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return va(i>1&&sa(m),i>1&&qa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(Q,"$1"),c,e>i&&wa(a.slice(i,e)),f>e&&wa(a=a.slice(e)),f>e&&qa(a))}m.push(c)}return sa(m)}function xa(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=F.call(i));u=ua(u)}H.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&fa.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ha(f):f}return h=fa.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xa(e,d)),f.selector=a}return f},i=fa.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ba,ca),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=W.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ba,ca),_.test(j[0].type)&&oa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qa(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||_.test(a)&&oa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ia(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ia(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ja("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ia(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ja("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ia(function(a){return null==a.getAttribute("disabled")})||ja(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fa}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.uniqueSort=n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},v=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},w=n.expr.match.needsContext,x=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,y=/^.[^:#\[\.,]*$/;function z(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(y.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>-1!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(z(this,a||[],!1))},not:function(a){return this.pushStack(z(this,a||[],!0))},is:function(a){return!!z(this,"string"==typeof a&&w.test(a)?n(a):a||[],!1).length}});var A,B=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=n.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||A,"string"==typeof a){if(e="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:B.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),x.test(e[1])&&n.isPlainObject(b))for(e in b)n.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}if(f=d.getElementById(e[2]),f&&f.parentNode){if(f.id!==e[2])return A.find(a);this.length=1,this[0]=f}return this.context=d,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof c.ready?c.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};C.prototype=n.fn,A=n(d);var D=/^(?:parents|prev(?:Until|All))/,E={children:!0,contents:!0,next:!0,prev:!0};n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=w.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.uniqueSort(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function F(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return u(a,"parentNode")},parentsUntil:function(a,b,c){return u(a,"parentNode",c)},next:function(a){return F(a,"nextSibling")},prev:function(a){return F(a,"previousSibling")},nextAll:function(a){return u(a,"nextSibling")},prevAll:function(a){return u(a,"previousSibling")},nextUntil:function(a,b,c){return u(a,"nextSibling",c)},prevUntil:function(a,b,c){return u(a,"previousSibling",c)},siblings:function(a){return v((a.parentNode||{}).firstChild,a)},children:function(a){return v(a.firstChild)},contents:function(a){return n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(E[a]||(e=n.uniqueSort(e)),D.test(a)&&(e=e.reverse())),this.pushStack(e)}});var G=/\S+/g;function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?H(a):n.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h<f.length)f[h].apply(c[0],c[1])===!1&&a.stopOnFalse&&(h=f.length,c=!1)}a.memory||(c=!1),b=!1,e&&(f=c?[]:"")},j={add:function(){return f&&(c&&!b&&(h=f.length-1,g.push(c)),function d(b){n.each(b,function(b,c){n.isFunction(c)?a.unique&&j.has(c)||f.push(c):c&&c.length&&"string"!==n.type(c)&&d(c)})}(arguments),c&&!b&&i()),this},remove:function(){return n.each(arguments,function(a,b){var c;while((c=n.inArray(b,f,c))>-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?n.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=!0,c||j.disable(),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().progress(c.notify).done(c.resolve).fail(c.reject):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=e.call(arguments),d=c.length,f=1!==d||a&&n.isFunction(a.promise)?d:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?e.call(arguments):d,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(d>1)for(i=new Array(d),j=new Array(d),k=new Array(d);d>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().progress(h(b,j,i)).done(h(b,k,c)).fail(g.reject):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(d,[n]),n.fn.triggerHandler&&(n(d).triggerHandler("ready"),n(d).off("ready"))))}});function J(){d.addEventListener?(d.removeEventListener("DOMContentLoaded",K),a.removeEventListener("load",K)):(d.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(d.addEventListener||"load"===a.event.type||"complete"===d.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll)a.setTimeout(n.ready);else if(d.addEventListener)d.addEventListener("DOMContentLoaded",K),a.addEventListener("load",K);else{d.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&d.documentElement}catch(e){}c&&c.doScroll&&!function f(){if(!n.isReady){try{c.doScroll("left")}catch(b){return a.setTimeout(f,50)}J(),n.ready()}}()}return I.promise(b)},n.ready.promise();var L;for(L in n(l))break;l.ownFirst="0"===L,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c,e;c=d.getElementsByTagName("body")[0],c&&c.style&&(b=d.createElement("div"),e=d.createElement("div"),e.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(e).appendChild(b),"undefined"!=typeof b.style.zoom&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",l.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(e))}),function(){var a=d.createElement("div");l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}a=null}();var M=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b},N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0;
2 }return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function R(a,b,d,e){if(M(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),"object"!=typeof b&&"function"!=typeof b||(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f}}function S(a,b,c){if(M(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=void 0)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?n.queue(this[0],a):void 0===b?this:this.each(function(){var c=n.queue(this,a,b);n._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&n.dequeue(this,a)})},dequeue:function(a){return this.each(function(){n.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=n.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=n._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}}),function(){var a;l.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,e;return c=d.getElementsByTagName("body")[0],c&&c.style?(b=d.createElement("div"),e=d.createElement("div"),e.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(e).appendChild(b),"undefined"!=typeof b.style.zoom&&(b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",b.appendChild(d.createElement("div")).style.width="5px",a=3!==b.offsetWidth),c.removeChild(e),a):void 0}}();var T=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,U=new RegExp("^(?:([+-])=|)("+T+")([a-z%]*)$","i"),V=["Top","Right","Bottom","Left"],W=function(a,b){return a=b||a,"none"===n.css(a,"display")||!n.contains(a.ownerDocument,a)};function X(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return n.css(a,b,"")},i=h(),j=c&&c[3]||(n.cssNumber[b]?"":"px"),k=(n.cssNumber[b]||"px"!==j&&+i)&&U.exec(n.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||".5",k/=f,n.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var Y=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)Y(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},Z=/^(?:checkbox|radio)$/i,$=/<([\w:-]+)/,_=/^$|\/(?:java|ecma)script/i,aa=/^\s+/,ba="abbr|article|aside|audio|bdi|canvas|data|datalist|details|dialog|figcaption|figure|footer|header|hgroup|main|mark|meter|nav|output|picture|progress|section|summary|template|time|video";function ca(a){var b=ba.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}!function(){var a=d.createElement("div"),b=d.createDocumentFragment(),c=d.createElement("input");a.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",l.leadingWhitespace=3===a.firstChild.nodeType,l.tbody=!a.getElementsByTagName("tbody").length,l.htmlSerialize=!!a.getElementsByTagName("link").length,l.html5Clone="<:nav></:nav>"!==d.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,b.appendChild(c),l.appendChecked=c.checked,a.innerHTML="<textarea>x</textarea>",l.noCloneChecked=!!a.cloneNode(!0).lastChild.defaultValue,b.appendChild(a),c=d.createElement("input"),c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),a.appendChild(c),l.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!!a.addEventListener,a[n.expando]=1,l.attributes=!a.getAttribute(n.expando)}();var da={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:l.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]};da.optgroup=da.option,da.tbody=da.tfoot=da.colgroup=da.caption=da.thead,da.th=da.td;function ea(a,b){var c,d,e=0,f="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,ea(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function fa(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}var ga=/<|&#?\w+;/,ha=/<tbody/i;function ia(a){Z.test(a.type)&&(a.defaultChecked=a.checked)}function ja(a,b,c,d,e){for(var f,g,h,i,j,k,m,o=a.length,p=ca(b),q=[],r=0;o>r;r++)if(g=a[r],g||0===g)if("object"===n.type(g))n.merge(q,g.nodeType?[g]:g);else if(ga.test(g)){i=i||p.appendChild(b.createElement("div")),j=($.exec(g)||["",""])[1].toLowerCase(),m=da[j]||da._default,i.innerHTML=m[1]+n.htmlPrefilter(g)+m[2],f=m[0];while(f--)i=i.lastChild;if(!l.leadingWhitespace&&aa.test(g)&&q.push(b.createTextNode(aa.exec(g)[0])),!l.tbody){g="table"!==j||ha.test(g)?"<table>"!==m[1]||ha.test(g)?0:i:i.firstChild,f=g&&g.childNodes.length;while(f--)n.nodeName(k=g.childNodes[f],"tbody")&&!k.childNodes.length&&g.removeChild(k)}n.merge(q,i.childNodes),i.textContent="";while(i.firstChild)i.removeChild(i.firstChild);i=p.lastChild}else q.push(b.createTextNode(g));i&&p.removeChild(i),l.appendChecked||n.grep(ea(q,"input"),ia),r=0;while(g=q[r++])if(d&&n.inArray(g,d)>-1)e&&e.push(g);else if(h=n.contains(g.ownerDocument,g),i=ea(p.appendChild(g),"script"),h&&fa(i),c){f=0;while(g=i[f++])_.test(g.type||"")&&c.push(g)}return i=null,p}!function(){var b,c,e=d.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b]=c in a)||(e.setAttribute(c,"t"),l[b]=e.attributes[c].expando===!1);e=null}();var ka=/^(?:input|select|textarea)$/i,la=/^key/,ma=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,na=/^(?:focusinfocus|focusoutblur)$/,oa=/^([^.]*)(?:\.(.+)|)/;function pa(){return!0}function qa(){return!1}function ra(){try{return d.activeElement}catch(a){}}function sa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)sa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=qa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return n().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=n.guid++)),a.each(function(){n.event.add(this,b,e,d,c)})}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return"undefined"==typeof n||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(G)||[""],h=b.length;while(h--)f=oa.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(G)||[""],j=b.length;while(j--)if(h=oa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,e,f){var g,h,i,j,l,m,o,p=[e||d],q=k.call(b,"type")?b.type:b,r=k.call(b,"namespace")?b.namespace.split("."):[];if(i=m=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!na.test(q+n.event.triggered)&&(q.indexOf(".")>-1&&(r=q.split("."),q=r.shift(),r.sort()),h=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=r.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:n.makeArray(c,[b]),l=n.event.special[q]||{},f||!l.trigger||l.trigger.apply(e,c)!==!1)){if(!f&&!l.noBubble&&!n.isWindow(e)){for(j=l.delegateType||q,na.test(j+q)||(i=i.parentNode);i;i=i.parentNode)p.push(i),m=i;m===(e.ownerDocument||d)&&p.push(m.defaultView||m.parentWindow||a)}o=0;while((i=p[o++])&&!b.isPropagationStopped())b.type=o>1?j:l.bindType||q,g=(n._data(i,"events")||{})[b.type]&&n._data(i,"handle"),g&&g.apply(i,c),g=h&&i[h],g&&g.apply&&M(i)&&(b.result=g.apply(i,c),b.result===!1&&b.preventDefault());if(b.type=q,!f&&!b.isDefaultPrevented()&&(!l._default||l._default.apply(p.pop(),c)===!1)&&M(e)&&h&&e[q]&&!n.isWindow(e)){m=e[h],m&&(e[h]=null),n.event.triggered=q;try{e[q]()}catch(s){}n.event.triggered=void 0,m&&(e[h]=m)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,d,f,g,h=[],i=e.call(arguments),j=(n._data(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())a.rnamespace&&!a.rnamespace.test(g.namespace)||(a.handleObj=g,a.data=g.data,d=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==d&&(a.result=d)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&("click"!==a.type||isNaN(a.button)||a.button<1))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>-1:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},fix:function(a){if(a[n.expando])return a;var b,c,e,f=a.type,g=a,h=this.fixHooks[f];h||(this.fixHooks[f]=h=ma.test(f)?this.mouseHooks:la.test(f)?this.keyHooks:{}),e=h.props?this.props.concat(h.props):this.props,a=new n.Event(g),b=e.length;while(b--)c=e[b],a[c]=g[c];return a.target||(a.target=g.srcElement||d),3===a.target.nodeType&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,h.filter?h.filter(a,g):a},props:"altKey bubbles cancelable ctrlKey currentTarget detail eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,e,f,g=b.button,h=b.fromElement;return null==a.pageX&&null!=b.clientX&&(e=a.target.ownerDocument||d,f=e.documentElement,c=e.body,a.pageX=b.clientX+(f&&f.scrollLeft||c&&c.scrollLeft||0)-(f&&f.clientLeft||c&&c.clientLeft||0),a.pageY=b.clientY+(f&&f.scrollTop||c&&c.scrollTop||0)-(f&&f.clientTop||c&&c.clientTop||0)),!a.relatedTarget&&h&&(a.relatedTarget=h===a.target?b.toElement:h),a.which||void 0===g||(a.which=1&g?1:2&g?3:4&g?2:0),a}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==ra()&&this.focus)try{return this.focus(),!1}catch(a){}},delegateType:"focusin"},blur:{trigger:function(){return this===ra()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return n.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):void 0},_default:function(a){return n.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c){var d=n.extend(new n.Event,c,{type:a,isSimulated:!0});n.event.trigger(d,null,b),d.isDefaultPrevented()&&c.preventDefault()}},n.removeEvent=d.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c)}:function(a,b,c){var d="on"+b;a.detachEvent&&("undefined"==typeof a[d]&&(a[d]=null),a.detachEvent(d,c))},n.Event=function(a,b){return this instanceof n.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?pa:qa):this.type=a,b&&n.extend(this,b),this.timeStamp=a&&a.timeStamp||n.now(),void(this[n.expando]=!0)):new n.Event(a,b)},n.Event.prototype={constructor:n.Event,isDefaultPrevented:qa,isPropagationStopped:qa,isImmediatePropagationStopped:qa,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=pa,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=pa,a&&!this.isSimulated&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=pa,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},n.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){n.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return e&&(e===d||n.contains(d,e))||(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),l.submit||(n.event.special.submit={setup:function(){return n.nodeName(this,"form")?!1:void n.event.add(this,"click._submit keypress._submit",function(a){var b=a.target,c=n.nodeName(b,"input")||n.nodeName(b,"button")?n.prop(b,"form"):void 0;c&&!n._data(c,"submit")&&(n.event.add(c,"submit._submit",function(a){a._submitBubble=!0}),n._data(c,"submit",!0))})},postDispatch:function(a){a._submitBubble&&(delete a._submitBubble,this.parentNode&&!a.isTrigger&&n.event.simulate("submit",this.parentNode,a))},teardown:function(){return n.nodeName(this,"form")?!1:void n.event.remove(this,"._submit")}}),l.change||(n.event.special.change={setup:function(){return ka.test(this.nodeName)?("checkbox"!==this.type&&"radio"!==this.type||(n.event.add(this,"propertychange._change",function(a){"checked"===a.originalEvent.propertyName&&(this._justChanged=!0)}),n.event.add(this,"click._change",function(a){this._justChanged&&!a.isTrigger&&(this._justChanged=!1),n.event.simulate("change",this,a)})),!1):void n.event.add(this,"beforeactivate._change",function(a){var b=a.target;ka.test(b.nodeName)&&!n._data(b,"change")&&(n.event.add(b,"change._change",function(a){!this.parentNode||a.isSimulated||a.isTrigger||n.event.simulate("change",this.parentNode,a)}),n._data(b,"change",!0))})},handle:function(a){var b=a.target;return this!==b||a.isSimulated||a.isTrigger||"radio"!==b.type&&"checkbox"!==b.type?a.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return n.event.remove(this,"._change"),!ka.test(this.nodeName)}}),l.focusin||n.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){n.event.simulate(b,a.target,n.event.fix(a))};n.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=n._data(d,b);e||d.addEventListener(a,c,!0),n._data(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=n._data(d,b)-1;e?n._data(d,b,e):(d.removeEventListener(a,c,!0),n._removeData(d,b))}}}),n.fn.extend({on:function(a,b,c,d){return sa(this,a,b,c,d)},one:function(a,b,c,d){return sa(this,a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,n(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return b!==!1&&"function"!=typeof b||(c=b,b=void 0),c===!1&&(c=qa),this.each(function(){n.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){n.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?n.event.trigger(a,b,c,!0):void 0}});var ta=/ jQuery\d+="(?:null|\d+)"/g,ua=new RegExp("<(?:"+ba+")[\\s/>]","i"),va=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,wa=/<script|<style|<link/i,xa=/checked\s*(?:[^=]|=\s*.checked.)/i,ya=/^true\/(.*)/,za=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,Aa=ca(d),Ba=Aa.appendChild(d.createElement("div"));function Ca(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function Da(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function Ea(a){var b=ya.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Fa(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Ga(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(Da(b).text=a.text,Ea(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&Z.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}}function Ha(a,b,c,d){b=f.apply([],b);var e,g,h,i,j,k,m=0,o=a.length,p=o-1,q=b[0],r=n.isFunction(q);if(r||o>1&&"string"==typeof q&&!l.checkClone&&xa.test(q))return a.each(function(e){var f=a.eq(e);r&&(b[0]=q.call(this,e,f.html())),Ha(f,b,c,d)});if(o&&(k=ja(b,a[0].ownerDocument,!1,a,d),e=k.firstChild,1===k.childNodes.length&&(k=e),e||d)){for(i=n.map(ea(k,"script"),Da),h=i.length;o>m;m++)g=k,m!==p&&(g=n.clone(g,!0,!0),h&&n.merge(i,ea(g,"script"))),c.call(a[m],g,m);if(h)for(j=i[i.length-1].ownerDocument,n.map(i,Ea),m=0;h>m;m++)g=i[m],_.test(g.type||"")&&!n._data(g,"globalEval")&&n.contains(j,g)&&(g.src?n._evalUrl&&n._evalUrl(g.src):n.globalEval((g.text||g.textContent||g.innerHTML||"").replace(za,"")));k=e=null}return a}function Ia(a,b,c){for(var d,e=b?n.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||n.cleanData(ea(d)),d.parentNode&&(c&&n.contains(d.ownerDocument,d)&&fa(ea(d,"script")),d.parentNode.removeChild(d));return a}n.extend({htmlPrefilter:function(a){return a.replace(va,"<$1></$2>")},clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!ua.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(Ba.innerHTML=a.outerHTML,Ba.removeChild(f=Ba.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=ea(f),h=ea(a),g=0;null!=(e=h[g]);++g)d[g]&&Ga(e,d[g]);if(b)if(c)for(h=h||ea(a),d=d||ea(f),g=0;null!=(e=h[g]);g++)Fa(e,d[g]);else Fa(a,f);return d=ea(f,"script"),d.length>0&&fa(d,!i&&ea(a,"script")),d=h=e=null,f},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.attributes,m=n.event.special;null!=(d=a[h]);h++)if((b||M(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k||"undefined"==typeof d.removeAttribute?d[i]=void 0:d.removeAttribute(i),c.push(f))}}}),n.fn.extend({domManip:Ha,detach:function(a){return Ia(this,a,!0)},remove:function(a){return Ia(this,a)},text:function(a){return Y(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||d).createTextNode(a))},null,a,arguments.length)},append:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.appendChild(a)}})},prepend:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(ea(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return Y(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(ta,""):void 0;if("string"==typeof a&&!wa.test(a)&&(l.htmlSerialize||!ua.test(a))&&(l.leadingWhitespace||!aa.test(a))&&!da[($.exec(a)||["",""])[1].toLowerCase()]){a=n.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ea(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ha(this,arguments,function(b){var c=this.parentNode;n.inArray(this,a)<0&&(n.cleanData(ea(this)),c&&c.replaceChild(b,this))},a)}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],f=n(a),h=f.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(f[d])[b](c),g.apply(e,c.get());return this.pushStack(e)}});var Ja,Ka={HTML:"block",BODY:"block"};function La(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[0],"display");return c.detach(),d}function Ma(a){var b=d,c=Ka[a];return c||(c=La(a,b),"none"!==c&&c||(Ja=(Ja||n("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=(Ja[0].contentWindow||Ja[0].contentDocument).document,b.write(),b.close(),c=La(a,b),Ja.detach()),Ka[a]=c),c}var Na=/^margin/,Oa=new RegExp("^("+T+")(?!px)[a-z%]+$","i"),Pa=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e},Qa=d.documentElement;!function(){var b,c,e,f,g,h,i=d.createElement("div"),j=d.createElement("div");if(j.style){j.style.cssText="float:left;opacity:.5",l.opacity="0.5"===j.style.opacity,l.cssFloat=!!j.style.cssFloat,j.style.backgroundClip="content-box",j.cloneNode(!0).style.backgroundClip="",l.clearCloneStyle="content-box"===j.style.backgroundClip,i=d.createElement("div"),i.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",j.innerHTML="",i.appendChild(j),l.boxSizing=""===j.style.boxSizing||""===j.style.MozBoxSizing||""===j.style.WebkitBoxSizing,n.extend(l,{reliableHiddenOffsets:function(){return null==b&&k(),f},boxSizingReliable:function(){return null==b&&k(),e},pixelMarginRight:function(){return null==b&&k(),c},pixelPosition:function(){return null==b&&k(),b},reliableMarginRight:function(){return null==b&&k(),g},reliableMarginLeft:function(){return null==b&&k(),h}});function k(){var k,l,m=d.documentElement;m.appendChild(i),j.style.cssText="-webkit-box-sizing:border-box;box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",b=e=h=!1,c=g=!0,a.getComputedStyle&&(l=a.getComputedStyle(j),b="1%"!==(l||{}).top,h="2px"===(l||{}).marginLeft,e="4px"===(l||{width:"4px"}).width,j.style.marginRight="50%",c="4px"===(l||{marginRight:"4px"}).marginRight,k=j.appendChild(d.createElement("div")),k.style.cssText=j.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",k.style.marginRight=k.style.width="0",j.style.width="1px",g=!parseFloat((a.getComputedStyle(k)||{}).marginRight),j.removeChild(k)),j.style.display="none",f=0===j.getClientRects().length,f&&(j.style.display="",j.innerHTML="<table><tr><td></td><td>t</td></tr></table>",j.childNodes[0].style.borderCollapse="separate",k=j.getElementsByTagName("td"),k[0].style.cssText="margin:0;border:0;padding:0;display:none",f=0===k[0].offsetHeight,f&&(k[0].style.display="",k[1].style.display="none",f=0===k[0].offsetHeight)),m.removeChild(i)}}}();var Ra,Sa,Ta=/^(top|right|bottom|left)$/;a.getComputedStyle?(Ra=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)},Sa=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ra(a),g=c?c.getPropertyValue(b)||c[b]:void 0,""!==g&&void 0!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),c&&!l.pixelMarginRight()&&Oa.test(g)&&Na.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f),void 0===g?g:g+""}):Qa.currentStyle&&(Ra=function(a){return a.currentStyle},Sa=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ra(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Oa.test(g)&&!Ta.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function Ua(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Va=/alpha\([^)]*\)/i,Wa=/opacity\s*=\s*([^)]*)/i,Xa=/^(none|table(?!-c[ea]).+)/,Ya=new RegExp("^("+T+")(.*)$","i"),Za={position:"absolute",visibility:"hidden",display:"block"},$a={letterSpacing:"0",fontWeight:"400"},_a=["Webkit","O","Moz","ms"],ab=d.createElement("div").style;function bb(a){if(a in ab)return a;var b=a.charAt(0).toUpperCase()+a.slice(1),c=_a.length;while(c--)if(a=_a[c]+b,a in ab)return a}function cb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=n._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&W(d)&&(f[g]=n._data(d,"olddisplay",Ma(d.nodeName)))):(e=W(d),(c&&"none"!==c||!e)&&n._data(d,"olddisplay",e?c:n.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function db(a,b,c){var d=Ya.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function eb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=n.css(a,c+V[f],!0,e)),d?("content"===c&&(g-=n.css(a,"padding"+V[f],!0,e)),"margin"!==c&&(g-=n.css(a,"border"+V[f]+"Width",!0,e))):(g+=n.css(a,"padding"+V[f],!0,e),"padding"!==c&&(g+=n.css(a,"border"+V[f]+"Width",!0,e)));return g}function fb(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Ra(a),g=l.boxSizing&&"border-box"===n.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Sa(a,b,f),(0>e||null==e)&&(e=a.style[b]),Oa.test(e))return e;d=g&&(l.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+eb(a,b,c||(g?"border":"content"),d,f)+"px"}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Sa(a,"opacity");return""===c?"1":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":l.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=n.camelCase(b),i=a.style;if(b=n.cssProps[h]||(n.cssProps[h]=bb(h)||h),g=n.cssHooks[b]||n.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=U.exec(c))&&e[1]&&(c=X(a,b,e),f="number"),null!=c&&c===c&&("number"===f&&(c+=e&&e[3]||(n.cssNumber[h]?"":"px")),l.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=bb(h)||h),g=n.cssHooks[b]||n.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Sa(a,b,d)),"normal"===f&&b in $a&&(f=$a[b]),""===c||c?(e=parseFloat(f),c===!0||isFinite(e)?e||0:f):f}}),n.each(["height","width"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?Xa.test(n.css(a,"display"))&&0===a.offsetWidth?Pa(a,Za,function(){return fb(a,b,d)}):fb(a,b,d):void 0},set:function(a,c,d){var e=d&&Ra(a);return db(a,c,d?eb(a,b,d,l.boxSizing&&"border-box"===n.css(a,"boxSizing",!1,e),e):0)}}}),l.opacity||(n.cssHooks.opacity={get:function(a,b){return Wa.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=n.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===n.trim(f.replace(Va,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Va.test(f)?f.replace(Va,e):f+" "+e)}}),n.cssHooks.marginRight=Ua(l.reliableMarginRight,function(a,b){return b?Pa(a,{display:"inline-block"},Sa,[a,"marginRight"]):void 0}),n.cssHooks.marginLeft=Ua(l.reliableMarginLeft,function(a,b){return b?(parseFloat(Sa(a,"marginLeft"))||(n.contains(a.ownerDocument,a)?a.getBoundingClientRect().left-Pa(a,{
3 marginLeft:0},function(){return a.getBoundingClientRect().left}):0))+"px":void 0}),n.each({margin:"",padding:"",border:"Width"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+V[d]+b]=f[d]||f[d-2]||f[0];return e}},Na.test(a)||(n.cssHooks[a+b].set=db)}),n.fn.extend({css:function(a,b){return Y(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=Ra(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b)},a,b,arguments.length>1)},show:function(){return cb(this,!0)},hide:function(){return cb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){W(this)?n(this).show():n(this).hide()})}});function gb(a,b,c,d,e){return new gb.prototype.init(a,b,c,d,e)}n.Tween=gb,gb.prototype={constructor:gb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||n.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?"":"px")},cur:function(){var a=gb.propHooks[this.prop];return a&&a.get?a.get(this):gb.propHooks._default.get(this)},run:function(a){var b,c=gb.propHooks[this.prop];return this.options.duration?this.pos=b=n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):gb.propHooks._default.set(this),this}},gb.prototype.init.prototype=gb.prototype,gb.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=n.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[n.cssProps[a.prop]]&&!n.cssHooks[a.prop]?a.elem[a.prop]=a.now:n.style(a.elem,a.prop,a.now+a.unit)}}},gb.propHooks.scrollTop=gb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},n.fx=gb.prototype.init,n.fx.step={};var hb,ib,jb=/^(?:toggle|show|hide)$/,kb=/queueHooks$/;function lb(){return a.setTimeout(function(){hb=void 0}),hb=n.now()}function mb(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=V[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function nb(a,b,c){for(var d,e=(qb.tweeners[b]||[]).concat(qb.tweeners["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ob(a,b,c){var d,e,f,g,h,i,j,k,m=this,o={},p=a.style,q=a.nodeType&&W(a),r=n._data(a,"fxshow");c.queue||(h=n._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,m.always(function(){m.always(function(){h.unqueued--,n.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=n.css(a,"display"),k="none"===j?n._data(a,"olddisplay")||Ma(a.nodeName):j,"inline"===k&&"none"===n.css(a,"float")&&(l.inlineBlockNeedsLayout&&"inline"!==Ma(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",l.shrinkWrapBlocks()||m.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],jb.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||n.style(a,d)}else j=void 0;if(n.isEmptyObject(o))"inline"===("none"===j?Ma(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=n._data(a,"fxshow",{}),f&&(r.hidden=!q),q?n(a).show():m.done(function(){n(a).hide()}),m.done(function(){var b;n._removeData(a,"fxshow");for(b in o)n.style(a,b,o[b])});for(d in o)g=nb(q?r[d]:0,d,m),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function pb(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function qb(a,b,c){var d,e,f=0,g=qb.prefilters.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=hb||lb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{},easing:n.easing._default},c),originalProperties:b,originalOptions:c,startTime:hb||lb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for(pb(k,j.opts.specialEasing);g>f;f++)if(d=qb.prefilters[f].call(j,a,k,j.opts))return n.isFunction(d.stop)&&(n._queueHooks(j.elem,j.opts.queue).stop=n.proxy(d.stop,d)),d;return n.map(k,nb,j),n.isFunction(j.opts.start)&&j.opts.start.call(a,j),n.fx.timer(n.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}n.Animation=n.extend(qb,{tweeners:{"*":[function(a,b){var c=this.createTween(a,b);return X(c.elem,a,U.exec(b),c),c}]},tweener:function(a,b){n.isFunction(a)?(b=a,a=["*"]):a=a.match(G);for(var c,d=0,e=a.length;e>d;d++)c=a[d],qb.tweeners[c]=qb.tweeners[c]||[],qb.tweeners[c].unshift(b)},prefilters:[ob],prefilter:function(a,b){b?qb.prefilters.unshift(a):qb.prefilters.push(a)}}),n.speed=function(a,b,c){var d=a&&"object"==typeof a?n.extend({},a):{complete:c||!c&&b||n.isFunction(a)&&a,duration:a,easing:c&&b||b&&!n.isFunction(b)&&b};return d.duration=n.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in n.fx.speeds?n.fx.speeds[d.duration]:n.fx.speeds._default,null!=d.queue&&d.queue!==!0||(d.queue="fx"),d.old=d.complete,d.complete=function(){n.isFunction(d.old)&&d.old.call(this),d.queue&&n.dequeue(this,d.queue)},d},n.fn.extend({fadeTo:function(a,b,c,d){return this.filter(W).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=n.isEmptyObject(a),f=n.speed(b,c,d),g=function(){var b=qb(this,n.extend({},a),f);(e||n._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=n.timers,g=n._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&kb.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));!b&&c||n.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=n._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=n.timers,g=d?d.length:0;for(c.finish=!0,n.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),n.each(["toggle","show","hide"],function(a,b){var c=n.fn[b];n.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(mb(b,!0),a,d,e)}}),n.each({slideDown:mb("show"),slideUp:mb("hide"),slideToggle:mb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){n.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),n.timers=[],n.fx.tick=function(){var a,b=n.timers,c=0;for(hb=n.now();c<b.length;c++)a=b[c],a()||b[c]!==a||b.splice(c--,1);b.length||n.fx.stop(),hb=void 0},n.fx.timer=function(a){n.timers.push(a),a()?n.fx.start():n.timers.pop()},n.fx.interval=13,n.fx.start=function(){ib||(ib=a.setInterval(n.fx.tick,n.fx.interval))},n.fx.stop=function(){a.clearInterval(ib),ib=null},n.fx.speeds={slow:600,fast:200,_default:400},n.fn.delay=function(b,c){return b=n.fx?n.fx.speeds[b]||b:b,c=c||"fx",this.queue(c,function(c,d){var e=a.setTimeout(c,b);d.stop=function(){a.clearTimeout(e)}})},function(){var a,b=d.createElement("input"),c=d.createElement("div"),e=d.createElement("select"),f=e.appendChild(d.createElement("option"));c=d.createElement("div"),c.setAttribute("className","t"),c.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",a=c.getElementsByTagName("a")[0],b.setAttribute("type","checkbox"),c.appendChild(b),a=c.getElementsByTagName("a")[0],a.style.cssText="top:1px",l.getSetAttribute="t"!==c.className,l.style=/top/.test(a.getAttribute("style")),l.hrefNormalized="/a"===a.getAttribute("href"),l.checkOn=!!b.value,l.optSelected=f.selected,l.enctype=!!d.createElement("form").enctype,e.disabled=!0,l.optDisabled=!f.disabled,b=d.createElement("input"),b.setAttribute("value",""),l.input=""===b.getAttribute("value"),b.value="t",b.setAttribute("type","radio"),l.radioValue="t"===b.value}();var rb=/\r/g,sb=/[\x20\t\r\n\f]+/g;n.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=n.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,n(this).val()):a,null==e?e="":"number"==typeof e?e+="":n.isArray(e)&&(e=n.map(e,function(a){return null==a?"":a+""})),b=n.valHooks[this.type]||n.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=n.valHooks[e.type]||n.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(rb,""):null==c?"":c)}}}),n.extend({valHooks:{option:{get:function(a){var b=n.find.attr(a,"value");return null!=b?b:n.trim(n.text(a)).replace(sb," ")}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],(c.selected||i===e)&&(l.optDisabled?!c.disabled:null===c.getAttribute("disabled"))&&(!c.parentNode.disabled||!n.nodeName(c.parentNode,"optgroup"))){if(b=n(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=n.makeArray(b),g=e.length;while(g--)if(d=e[g],n.inArray(n.valHooks.option.get(d),f)>-1)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),n.each(["radio","checkbox"],function(){n.valHooks[this]={set:function(a,b){return n.isArray(b)?a.checked=n.inArray(n(a).val(),b)>-1:void 0}},l.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var tb,ub,vb=n.expr.attrHandle,wb=/^(?:checked|selected)$/i,xb=l.getSetAttribute,yb=l.input;n.fn.extend({attr:function(a,b){return Y(this,n.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){n.removeAttr(this,a)})}}),n.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),e=n.attrHooks[b]||(n.expr.match.bool.test(b)?ub:tb)),void 0!==c?null===c?void n.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=n.find.attr(a,b),null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!l.radioValue&&"radio"===b&&n.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(G);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)?yb&&xb||!wb.test(c)?a[d]=!1:a[n.camelCase("default-"+c)]=a[d]=!1:n.attr(a,c,""),a.removeAttribute(xb?c:d)}}),ub={set:function(a,b,c){return b===!1?n.removeAttr(a,c):yb&&xb||!wb.test(c)?a.setAttribute(!xb&&n.propFix[c]||c,c):a[n.camelCase("default-"+c)]=a[c]=!0,c}},n.each(n.expr.match.bool.source.match(/\w+/g),function(a,b){var c=vb[b]||n.find.attr;yb&&xb||!wb.test(b)?vb[b]=function(a,b,d){var e,f;return d||(f=vb[b],vb[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,vb[b]=f),e}:vb[b]=function(a,b,c){return c?void 0:a[n.camelCase("default-"+b)]?b.toLowerCase():null}}),yb&&xb||(n.attrHooks.value={set:function(a,b,c){return n.nodeName(a,"input")?void(a.defaultValue=b):tb&&tb.set(a,b,c)}}),xb||(tb={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},vb.id=vb.name=vb.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},n.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:tb.set},n.attrHooks.contenteditable={set:function(a,b,c){tb.set(a,""===b?!1:b,c)}},n.each(["width","height"],function(a,b){n.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),l.style||(n.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var zb=/^(?:input|select|textarea|button|object)$/i,Ab=/^(?:a|area)$/i;n.fn.extend({prop:function(a,b){return Y(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return a=n.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),n.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&n.isXMLDoc(a)||(b=n.propFix[b]||b,e=n.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=n.find.attr(a,"tabindex");return b?parseInt(b,10):zb.test(a.nodeName)||Ab.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),l.hrefNormalized||n.each(["href","src"],function(a,b){n.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),l.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),n.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){n.propFix[this.toLowerCase()]=this}),l.enctype||(n.propFix.enctype="encoding");var Bb=/[\t\r\n\f]/g;function Cb(a){return n.attr(a,"class")||""}n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,Cb(this)))});if("string"==typeof a&&a){b=a.match(G)||[];while(c=this[i++])if(e=Cb(c),d=1===c.nodeType&&(" "+e+" ").replace(Bb," ")){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=n.trim(d),e!==h&&n.attr(c,"class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,Cb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(G)||[];while(c=this[i++])if(e=Cb(c),d=1===c.nodeType&&(" "+e+" ").replace(Bb," ")){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=n.trim(d),e!==h&&n.attr(c,"class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):n.isFunction(a)?this.each(function(c){n(this).toggleClass(a.call(this,c,Cb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=n(this),f=a.match(G)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=Cb(this),b&&n._data(this,"__className__",b),n.attr(this,"class",b||a===!1?"":n._data(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+Cb(c)+" ").replace(Bb," ").indexOf(b)>-1)return!0;return!1}}),n.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){n.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),n.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Db=a.location,Eb=n.now(),Fb=/\?/,Gb=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;n.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=n.trim(b+"");return e&&!n.trim(e.replace(Gb,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():n.error("Invalid JSON: "+b)},n.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new a.DOMParser,c=d.parseFromString(b,"text/xml")):(c=new a.ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||n.error("Invalid XML: "+b),c};var Hb=/#.*$/,Ib=/([?&])_=[^&]*/,Jb=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Kb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Lb=/^(?:GET|HEAD)$/,Mb=/^\/\//,Nb=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Ob={},Pb={},Qb="*/".concat("*"),Rb=Db.href,Sb=Nb.exec(Rb.toLowerCase())||[];function Tb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(G)||[];if(n.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Ub(a,b,c,d){var e={},f=a===Pb;function g(h){var i;return e[h]=!0,n.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Vb(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&n.extend(!0,a,c),a}function Wb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Xb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}n.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Rb,type:"GET",isLocal:Kb.test(Sb[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Qb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":n.parseJSON,"text xml":n.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Vb(Vb(a,n.ajaxSettings),b):Vb(n.ajaxSettings,a)},ajaxPrefilter:Tb(Ob),ajaxTransport:Tb(Pb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var d,e,f,g,h,i,j,k,l=n.ajaxSetup({},c),m=l.context||l,o=l.context&&(m.nodeType||m.jquery)?n(m):n.event,p=n.Deferred(),q=n.Callbacks("once memory"),r=l.statusCode||{},s={},t={},u=0,v="canceled",w={readyState:0,getResponseHeader:function(a){var b;if(2===u){if(!k){k={};while(b=Jb.exec(g))k[b[1].toLowerCase()]=b[2]}b=k[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===u?g:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return u||(a=t[c]=t[c]||a,s[a]=b),this},overrideMimeType:function(a){return u||(l.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>u)for(b in a)r[b]=[r[b],a[b]];else w.always(a[w.status]);return this},abort:function(a){var b=a||v;return j&&j.abort(b),y(0,b),this}};if(p.promise(w).complete=q.add,w.success=w.done,w.error=w.fail,l.url=((b||l.url||Rb)+"").replace(Hb,"").replace(Mb,Sb[1]+"//"),l.type=c.method||c.type||l.method||l.type,l.dataTypes=n.trim(l.dataType||"*").toLowerCase().match(G)||[""],null==l.crossDomain&&(d=Nb.exec(l.url.toLowerCase()),l.crossDomain=!(!d||d[1]===Sb[1]&&d[2]===Sb[2]&&(d[3]||("http:"===d[1]?"80":"443"))===(Sb[3]||("http:"===Sb[1]?"80":"443")))),l.data&&l.processData&&"string"!=typeof l.data&&(l.data=n.param(l.data,l.traditional)),Ub(Ob,l,c,w),2===u)return w;i=n.event&&l.global,i&&0===n.active++&&n.event.trigger("ajaxStart"),l.type=l.type.toUpperCase(),l.hasContent=!Lb.test(l.type),f=l.url,l.hasContent||(l.data&&(f=l.url+=(Fb.test(f)?"&":"?")+l.data,delete l.data),l.cache===!1&&(l.url=Ib.test(f)?f.replace(Ib,"$1_="+Eb++):f+(Fb.test(f)?"&":"?")+"_="+Eb++)),l.ifModified&&(n.lastModified[f]&&w.setRequestHeader("If-Modified-Since",n.lastModified[f]),n.etag[f]&&w.setRequestHeader("If-None-Match",n.etag[f])),(l.data&&l.hasContent&&l.contentType!==!1||c.contentType)&&w.setRequestHeader("Content-Type",l.contentType),w.setRequestHeader("Accept",l.dataTypes[0]&&l.accepts[l.dataTypes[0]]?l.accepts[l.dataTypes[0]]+("*"!==l.dataTypes[0]?", "+Qb+"; q=0.01":""):l.accepts["*"]);for(e in l.headers)w.setRequestHeader(e,l.headers[e]);if(l.beforeSend&&(l.beforeSend.call(m,w,l)===!1||2===u))return w.abort();v="abort";for(e in{success:1,error:1,complete:1})w[e](l[e]);if(j=Ub(Pb,l,c,w)){if(w.readyState=1,i&&o.trigger("ajaxSend",[w,l]),2===u)return w;l.async&&l.timeout>0&&(h=a.setTimeout(function(){w.abort("timeout")},l.timeout));try{u=1,j.send(s,y)}catch(x){if(!(2>u))throw x;y(-1,x)}}else y(-1,"No Transport");function y(b,c,d,e){var k,s,t,v,x,y=c;2!==u&&(u=2,h&&a.clearTimeout(h),j=void 0,g=e||"",w.readyState=b>0?4:0,k=b>=200&&300>b||304===b,d&&(v=Wb(l,w,d)),v=Xb(l,v,w,k),k?(l.ifModified&&(x=w.getResponseHeader("Last-Modified"),x&&(n.lastModified[f]=x),x=w.getResponseHeader("etag"),x&&(n.etag[f]=x)),204===b||"HEAD"===l.type?y="nocontent":304===b?y="notmodified":(y=v.state,s=v.data,t=v.error,k=!t)):(t=y,!b&&y||(y="error",0>b&&(b=0))),w.status=b,w.statusText=(c||y)+"",k?p.resolveWith(m,[s,y,w]):p.rejectWith(m,[w,y,t]),w.statusCode(r),r=void 0,i&&o.trigger(k?"ajaxSuccess":"ajaxError",[w,l,k?s:t]),q.fireWith(m,[w,y]),i&&(o.trigger("ajaxComplete",[w,l]),--n.active||n.event.trigger("ajaxStop")))}return w},getJSON:function(a,b,c){return n.get(a,b,c,"json")},getScript:function(a,b){return n.get(a,void 0,b,"script")}}),n.each(["get","post"],function(a,b){n[b]=function(a,c,d,e){return n.isFunction(c)&&(e=e||d,d=c,c=void 0),n.ajax(n.extend({url:a,type:b,dataType:e,data:c,success:d},n.isPlainObject(a)&&a))}}),n._evalUrl=function(a){return n.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},n.fn.extend({wrapAll:function(a){if(n.isFunction(a))return this.each(function(b){n(this).wrapAll(a.call(this,b))});if(this[0]){var b=n(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return n.isFunction(a)?this.each(function(b){n(this).wrapInner(a.call(this,b))}):this.each(function(){var b=n(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=n.isFunction(a);return this.each(function(c){n(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){n.nodeName(this,"body")||n(this).replaceWith(this.childNodes)}).end()}});function Yb(a){return a.style&&a.style.display||n.css(a,"display")}function Zb(a){if(!n.contains(a.ownerDocument||d,a))return!0;while(a&&1===a.nodeType){if("none"===Yb(a)||"hidden"===a.type)return!0;a=a.parentNode}return!1}n.expr.filters.hidden=function(a){return l.reliableHiddenOffsets()?a.offsetWidth<=0&&a.offsetHeight<=0&&!a.getClientRects().length:Zb(a)},n.expr.filters.visible=function(a){return!n.expr.filters.hidden(a)};var $b=/%20/g,_b=/\[\]$/,ac=/\r?\n/g,bc=/^(?:submit|button|image|reset|file)$/i,cc=/^(?:input|select|textarea|keygen)/i;function dc(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||_b.test(a)?d(a,e):dc(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==n.type(b))d(a,b);else for(e in b)dc(a+"["+e+"]",b[e],c,d)}n.param=function(a,b){var c,d=[],e=function(a,b){b=n.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=n.ajaxSettings&&n.ajaxSettings.traditional),n.isArray(a)||a.jquery&&!n.isPlainObject(a))n.each(a,function(){e(this.name,this.value)});else for(c in a)dc(c,a[c],b,e);return d.join("&").replace($b,"+")},n.fn.extend({serialize:function(){return n.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=n.prop(this,"elements");return a?n.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!n(this).is(":disabled")&&cc.test(this.nodeName)&&!bc.test(a)&&(this.checked||!Z.test(a))}).map(function(a,b){var c=n(this).val();return null==c?null:n.isArray(c)?n.map(c,function(a){return{name:b.name,value:a.replace(ac,"\r\n")}}):{name:b.name,value:c.replace(ac,"\r\n")}}).get()}}),n.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return this.isLocal?ic():d.documentMode>8?hc():/^(get|post|head|put|delete|options)$/i.test(this.type)&&hc()||ic()}:hc;var ec=0,fc={},gc=n.ajaxSettings.xhr();a.attachEvent&&a.attachEvent("onunload",function(){for(var a in fc)fc[a](void 0,!0)}),l.cors=!!gc&&"withCredentials"in gc,gc=l.ajax=!!gc,gc&&n.ajaxTransport(function(b){if(!b.crossDomain||l.cors){var c;return{send:function(d,e){var f,g=b.xhr(),h=++ec;if(g.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(f in b.xhrFields)g[f]=b.xhrFields[f];b.mimeType&&g.overrideMimeType&&g.overrideMimeType(b.mimeType),b.crossDomain||d["X-Requested-With"]||(d["X-Requested-With"]="XMLHttpRequest");for(f in d)void 0!==d[f]&&g.setRequestHeader(f,d[f]+"");g.send(b.hasContent&&b.data||null),c=function(a,d){var f,i,j;if(c&&(d||4===g.readyState))if(delete fc[h],c=void 0,g.onreadystatechange=n.noop,d)4!==g.readyState&&g.abort();else{j={},f=g.status,"string"==typeof g.responseText&&(j.text=g.responseText);try{i=g.statusText}catch(k){i=""}f||!b.isLocal||b.crossDomain?1223===f&&(f=204):f=j.text?200:404}j&&e(f,i,j,g.getAllResponseHeaders())},b.async?4===g.readyState?a.setTimeout(c):g.onreadystatechange=fc[h]=c:c()},abort:function(){c&&c(void 0,!0)}}}});function hc(){try{return new a.XMLHttpRequest}catch(b){}}function ic(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}n.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return n.globalEval(a),a}}}),n.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),n.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=d.head||n("head")[0]||d.documentElement;return{send:function(e,f){b=d.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||f(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var jc=[],kc=/(=)\?(?=&|$)|\?\?/;n.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=jc.pop()||n.expando+"_"+Eb++;return this[a]=!0,a}}),n.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(kc.test(b.url)?"url":"string"==typeof b.data&&0===(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&kc.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=n.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(kc,"$1"+e):b.jsonp!==!1&&(b.url+=(Fb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||n.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){void 0===f?n(a).removeProp(e):a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,jc.push(e)),g&&n.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),n.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||d;var e=x.exec(a),f=!c&&[];return e?[b.createElement(e[1])]:(e=ja([a],b,f),f&&f.length&&n(f).remove(),n.merge([],e.childNodes))};var lc=n.fn.load;n.fn.load=function(a,b,c){if("string"!=typeof a&&lc)return lc.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>-1&&(d=n.trim(a.slice(h,a.length)),a=a.slice(0,h)),n.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&n.ajax({url:a,type:e||"GET",dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?n("<div>").append(n.parseHTML(a)).find(d):a)}).always(c&&function(a,b){g.each(function(){c.apply(this,f||[a.responseText,b,a])})}),this},n.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){n.fn[b]=function(a){return this.on(b,a)}}),n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};function mc(a){return n.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}n.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=n.css(a,"position"),l=n(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=n.css(a,"top"),i=n.css(a,"left"),j=("absolute"===k||"fixed"===k)&&n.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),n.isFunction(b)&&(b=b.call(a,c,n.extend({},h))),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},n.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){n.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,n.contains(b,e)?("undefined"!=typeof e.getBoundingClientRect&&(d=e.getBoundingClientRect()),c=mc(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===n.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],"html")||(c=a.offset()),c.top+=n.css(a[0],"borderTopWidth",!0),c.left+=n.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-n.css(d,"marginTop",!0),left:b.left-c.left-n.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&!n.nodeName(a,"html")&&"static"===n.css(a,"position"))a=a.offsetParent;return a||Qa})}}),n.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);n.fn[a]=function(d){return Y(this,function(a,d,e){var f=mc(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?n(f).scrollLeft():e,c?e:n(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),n.each(["top","left"],function(a,b){n.cssHooks[b]=Ua(l.pixelPosition,function(a,c){return c?(c=Sa(a,b),Oa.test(c)?n(a).position()[b]+"px":c):void 0})}),n.each({Height:"height",Width:"width"},function(a,b){n.each({
4 padding:"inner"+a,content:b,"":"outer"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return Y(this,function(b,c,d){var e;return n.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}}),n.fn.size=function(){return this.length},n.fn.andSelf=n.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return n});var nc=a.jQuery,oc=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=oc),b&&a.jQuery===n&&(a.jQuery=nc),n},b||(a.jQuery=a.$=n),n});
0 (The MIT License)
1
2 Copyright (c) 2007-2015 Ariel Flesler <aflesler@gmail.com>
3
4 Permission is hereby granted, free of charge, to any person obtaining
5 a copy of this software and associated documentation files (the
6 'Software'), to deal in the Software without restriction, including
7 without limitation the rights to use, copy, modify, merge, publish,
8 distribute, sublicense, and/or sell copies of the Software, and to
9 permit persons to whom the Software is furnished to do so, subject to
10 the following conditions:
11
12 The above copyright notice and this permission notice shall be
13 included in all copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
16 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
0 /**
1 * Copyright (c) 2007-2015 Ariel Flesler - aflesler<a>gmail<d>com | http://flesler.blogspot.com
2 * Licensed under MIT
3 * @author Ariel Flesler
4 * @version 2.1.2
5 */
6 ;(function(f){"use strict";"function"===typeof define&&define.amd?define(["jquery"],f):"undefined"!==typeof module&&module.exports?module.exports=f(require("jquery")):f(jQuery)})(function($){"use strict";function n(a){return!a.nodeName||-1!==$.inArray(a.nodeName.toLowerCase(),["iframe","#document","html","body"])}function h(a){return $.isFunction(a)||$.isPlainObject(a)?a:{top:a,left:a}}var p=$.scrollTo=function(a,d,b){return $(window).scrollTo(a,d,b)};p.defaults={axis:"xy",duration:0,limit:!0};$.fn.scrollTo=function(a,d,b){"object"=== typeof d&&(b=d,d=0);"function"===typeof b&&(b={onAfter:b});"max"===a&&(a=9E9);b=$.extend({},p.defaults,b);d=d||b.duration;var u=b.queue&&1<b.axis.length;u&&(d/=2);b.offset=h(b.offset);b.over=h(b.over);return this.each(function(){function k(a){var k=$.extend({},b,{queue:!0,duration:d,complete:a&&function(){a.call(q,e,b)}});r.animate(f,k)}if(null!==a){var l=n(this),q=l?this.contentWindow||window:this,r=$(q),e=a,f={},t;switch(typeof e){case "number":case "string":if(/^([+-]=?)?\d+(\.\d+)?(px|%)?$/.test(e)){e= h(e);break}e=l?$(e):$(e,q);case "object":if(e.length===0)return;if(e.is||e.style)t=(e=$(e)).offset()}var v=$.isFunction(b.offset)&&b.offset(q,e)||b.offset;$.each(b.axis.split(""),function(a,c){var d="x"===c?"Left":"Top",m=d.toLowerCase(),g="scroll"+d,h=r[g](),n=p.max(q,c);t?(f[g]=t[m]+(l?0:h-r.offset()[m]),b.margin&&(f[g]-=parseInt(e.css("margin"+d),10)||0,f[g]-=parseInt(e.css("border"+d+"Width"),10)||0),f[g]+=v[m]||0,b.over[m]&&(f[g]+=e["x"===c?"width":"height"]()*b.over[m])):(d=e[m],f[g]=d.slice&& "%"===d.slice(-1)?parseFloat(d)/100*n:d);b.limit&&/^\d+$/.test(f[g])&&(f[g]=0>=f[g]?0:Math.min(f[g],n));!a&&1<b.axis.length&&(h===f[g]?f={}:u&&(k(b.onAfterFirst),f={}))});k(b.onAfter)}})};p.max=function(a,d){var b="x"===d?"Width":"Height",h="scroll"+b;if(!n(a))return a[h]-$(a)[b.toLowerCase()]();var b="client"+b,k=a.ownerDocument||a.document,l=k.documentElement,k=k.body;return Math.max(l[h],k[h])-Math.min(l[b],k[b])};$.Tween.propHooks.scrollLeft=$.Tween.propHooks.scrollTop={get:function(a){return $(a.elem)[a.prop]()}, set:function(a){var d=this.get(a);if(a.options.interrupt&&a._last&&a._last!==d)return $(a.elem).stop();var b=Math.round(a.now);d!==b&&($(a.elem)[a.prop](b),a._last=this.get(a))}};return p});
0 {
1 "env": {
2 "node": true
3 },
4 "rules": {
5 "no-console": 0
6 }
7 }
00 #!/usr/bin/env node
11
2 var util = require("util");
3 var fs = require("fs");
4 var PEG = require("../lib/peg");
2 "use strict";
3
4 var fs = require("fs");
5 var path = require("path");
6 var peg = require("../lib/peg");
7 var objects = require("../lib/utils/objects");
58
69 /* Helpers */
710
811 function printVersion() {
9 util.puts("PEG.js " + PEG.VERSION);
12 console.log("PEG.js " + peg.VERSION);
1013 }
1114
1215 function printHelp() {
13 util.puts("Usage: pegjs [options] [--] [<input_file>] [<output_file>]");
14 util.puts("");
15 util.puts("Generates a parser from the PEG grammar specified in the <input_file> and");
16 util.puts("writes it to the <output_file>.");
17 util.puts("");
18 util.puts("If the <output_file> is omitted, its name is generated by changing the");
19 util.puts("<input_file> extension to \".js\". If both <input_file> and <output_file> are");
20 util.puts("omitted, standard input and output are used.");
21 util.puts("");
22 util.puts("Options:");
23 util.puts(" -e, --export-var <variable> name of the variable where the parser object");
24 util.puts(" will be stored (default: \"module.exports\")");
25 util.puts(" --cache make generated parser cache results");
26 util.puts(" --track-line-and-column make generated parser track line and column");
27 util.puts(" -v, --version print version information and exit");
28 util.puts(" -h, --help print help and exit");
16 console.log("Usage: pegjs [options] [--] [<input_file>]");
17 console.log("");
18 console.log("Options:");
19 console.log(" --allowed-start-rules <rules> comma-separated list of rules the generated");
20 console.log(" parser will be allowed to start parsing");
21 console.log(" from (default: the first rule in the");
22 console.log(" grammar)");
23 console.log(" --cache make generated parser cache results");
24 console.log(" -d, --dependency <dependency> use specified dependency (can be specified");
25 console.log(" multiple times)");
26 console.log(" -e, --export-var <variable> name of a global variable into which the");
27 console.log(" parser object is assigned to when no module");
28 console.log(" loader is detected");
29 console.log(" --extra-options <options> additional options (in JSON format) to pass");
30 console.log(" to peg.generate");
31 console.log(" --extra-options-file <file> file with additional options (in JSON");
32 console.log(" format) to pass to peg.generate");
33 console.log(" --format <format> format of the generated parser: amd,");
34 console.log(" commonjs, globals, umd (default: commonjs)");
35 console.log(" -h, --help print help and exit");
36 console.log(" -O, --optimize <goal> select optimization for speed or size");
37 console.log(" (default: speed)");
38 console.log(" -o, --output <file> output file");
39 console.log(" --plugin <plugin> use a specified plugin (can be specified");
40 console.log(" multiple times)");
41 console.log(" --trace enable tracing in generated parser");
42 console.log(" -v, --version print version information and exit");
2943 }
3044
3145 function exitSuccess() {
3751 }
3852
3953 function abort(message) {
40 util.error(message);
54 console.error(message);
4155 exitFailure();
4256 }
4357
58 function addExtraOptions(options, json) {
59 var extraOptions;
60
61 try {
62 extraOptions = JSON.parse(json);
63 } catch (e) {
64 if (!(e instanceof SyntaxError)) { throw e; }
65
66 abort("Error parsing JSON: " + e.message);
67 }
68 if (typeof extraOptions !== "object") {
69 abort("The JSON with extra options has to represent an object.");
70 }
71
72 for (var key in extraOptions) {
73 if (extraOptions.hasOwnProperty(key)) {
74 options[key] = extraOptions[key];
75 }
76 }
77 }
78
79 /*
80 * Extracted into a function just to silence JSHint complaining about creating
81 * functions in a loop.
82 */
83 function trim(s) {
84 return s.trim();
85 }
86
4487 /* Arguments */
4588
4689 var args = process.argv.slice(2); // Trim "node" and the script path.
4790
4891 function isOption(arg) {
49 return /^-/.test(arg);
92 return (/^-.+/).test(arg);
5093 }
5194
5295 function nextArg() {
63106
64107 /* Main */
65108
66 /* This makes the generated parser a CommonJS module by default. */
67 var exportVar = "module.exports";
109 var inputFile = null;
110 var outputFile = null;
111
68112 var options = {
69 cache: false,
70 trackLineAndColumn: false
113 cache: false,
114 dependencies: {},
115 exportVar: null,
116 format: "commonjs",
117 optimize: "speed",
118 output: "source",
119 plugins: [],
120 trace: false
71121 };
72122
73123 while (args.length > 0 && isOption(args[0])) {
74124 switch (args[0]) {
125 case "--allowed-start-rules":
126 nextArg();
127 if (args.length === 0) {
128 abort("Missing parameter of the -e/--allowed-start-rules option.");
129 }
130 options.allowedStartRules = args[0]
131 .split(",")
132 .map(trim);
133 break;
134
135 case "--cache":
136 options.cache = true;
137 break;
138
139 case "-d":
140 case "--dependency":
141 nextArg();
142 if (args.length === 0) {
143 abort("Missing parameter of the -d/--dependency option.");
144 }
145 if (args[0].indexOf(":") !== -1) {
146 var parts = args[0].split(":");
147 options.dependencies[parts[0]] = parts[1];
148 } else {
149 options.dependencies[args[0]] = args[0];
150 }
151 break;
152
75153 case "-e":
76154 case "--export-var":
77155 nextArg();
78156 if (args.length === 0) {
79157 abort("Missing parameter of the -e/--export-var option.");
80158 }
81 exportVar = args[0];
82 break;
83
84 case "--cache":
85 options.cache = true;
86 break;
87
88 case "--track-line-and-column":
89 options.trackLineAndColumn = true;
159 options.exportVar = args[0];
160 break;
161
162 case "--extra-options":
163 nextArg();
164 if (args.length === 0) {
165 abort("Missing parameter of the --extra-options option.");
166 }
167 addExtraOptions(options, args[0]);
168 break;
169
170 case "--extra-options-file":
171 nextArg();
172 if (args.length === 0) {
173 abort("Missing parameter of the --extra-options-file option.");
174 }
175 try {
176 var json = fs.readFileSync(args[0]);
177 } catch(e) {
178 abort("Can't read from file \"" + args[0] + "\".");
179 }
180 addExtraOptions(options, json);
181 break;
182
183 case "--format":
184 nextArg();
185 if (args.length === 0) {
186 abort("Missing parameter of the --format option.");
187 }
188 if (args[0] !== "amd" && args[0] !== "commonjs" && args[0] !== "globals" && args[0] !== "umd") {
189 abort("Module format must be one of \"amd\", \"commonjs\", \"globals\", and \"umd\".");
190 }
191 options.format = args[0];
192 break;
193
194 case "-h":
195 case "--help":
196 printHelp();
197 exitSuccess();
198 break;
199
200 case "-O":
201 case "--optimize":
202 nextArg();
203 if (args.length === 0) {
204 abort("Missing parameter of the -O/--optimize option.");
205 }
206 if (args[0] !== "speed" && args[0] !== "size") {
207 abort("Optimization goal must be either \"speed\" or \"size\".");
208 }
209 options.optimize = args[0];
210 break;
211
212 case "-o":
213 case "--output":
214 nextArg();
215 if (args.length === 0) {
216 abort("Missing parameter of the -o/--output option.");
217 }
218 outputFile = args[0];
219 break;
220
221 case "--plugin":
222 nextArg();
223 if (args.length === 0) {
224 abort("Missing parameter of the --plugin option.");
225 }
226 var id = /^(\.\/|\.\.\/)/.test(args[0]) ? path.resolve(args[0]) : args[0];
227 var mod;
228 try {
229 mod = require(id);
230 } catch (e) {
231 if (e.code !== "MODULE_NOT_FOUND") { throw e; }
232
233 abort("Can't load module \"" + id + "\".");
234 }
235 options.plugins.push(mod);
236 break;
237
238 case "--trace":
239 options.trace = true;
90240 break;
91241
92242 case "-v":
95245 exitSuccess();
96246 break;
97247
98 case "-h":
99 case "--help":
100 printHelp();
101 exitSuccess();
102 break;
103
104248 case "--":
105249 nextArg();
106250 break;
111255 nextArg();
112256 }
113257
258 if (objects.keys(options.dependencies).length > 0) {
259 if (options.format !== "amd" && options.format !== "commonjs" && options.format !== "umd") {
260 abort("Can't use the -d/--dependency option with the \"" + options.format + "\" module format.");
261 }
262 }
263
264 if (options.exportVar !== null) {
265 if (options.format !== "globals" && options.format !== "umd") {
266 abort("Can't use the -e/--export-var option with the \"" + options.format + "\" module format.");
267 }
268 }
269
270 var inputStream;
271 var outputStream;
272
114273 switch (args.length) {
115274 case 0:
116 process.stdin.resume();
117 var inputStream = process.stdin;
118 var outputStream = process.stdout;
275 inputFile = "-";
119276 break;
120277
121278 case 1:
122 case 2:
123 var inputFile = args[0];
124 var inputStream = fs.createReadStream(inputFile);
125 inputStream.on("error", function() {
126 abort("Can't read from file \"" + inputFile + "\".");
127 });
128
129 var outputFile = args.length == 1
130 ? args[0].replace(/\.[^.]*$/, ".js")
131 : args[1];
132 var outputStream = fs.createWriteStream(outputFile);
133 outputStream.on("error", function() {
134 abort("Can't write to file \"" + outputFile + "\".");
135 });
136
279 inputFile = args[0];
137280 break;
138281
139282 default:
140283 abort("Too many arguments.");
141284 }
142285
286 if (outputFile === null) {
287 if (inputFile === "-") {
288 outputFile = "-";
289 } else {
290 outputFile = inputFile.substr(0, inputFile.length - path.extname(inputFile).length) + ".js";
291 }
292 }
293
294 if (inputFile === "-") {
295 process.stdin.resume();
296 inputStream = process.stdin;
297 inputStream.on("error", function() {
298 abort("Can't read from file \"" + inputFile + "\".");
299 });
300 } else {
301 inputStream = fs.createReadStream(inputFile);
302 }
303
304 if (outputFile === "-") {
305 outputStream = process.stdout;
306 } else {
307 outputStream = fs.createWriteStream(outputFile);
308 outputStream.on("error", function() {
309 abort("Can't write to file \"" + outputFile + "\".");
310 });
311 }
312
143313 readStream(inputStream, function(input) {
314 var source;
315
144316 try {
145 var parser = PEG.buildParser(input, options);
317 source = peg.generate(input, options);
146318 } catch (e) {
147 if (e.line !== undefined && e.column !== undefined) {
148 abort(e.line + ":" + e.column + ": " + e.message);
319 if (e.location !== undefined) {
320 abort(e.location.start.line + ":" + e.location.start.column + ": " + e.message);
149321 } else {
150322 abort(e.message);
151323 }
152324 }
153325
154 outputStream.write(exportVar + " = " + parser.toSource() + ";\n");
326 outputStream.write(source);
155327 if (outputStream !== process.stdout) {
156328 outputStream.end();
157329 }
00 /*
1 * Classic example grammar, which recognizes simple arithmetic expressions like
2 * "2*(3+4)". The parser generated from this grammar then computes their value.
1 * Simple Arithmetics Grammar
2 * ==========================
3 *
4 * Accepts expressions like "2 * (3 + 4)" and computes their value.
35 */
46
5 start
6 = additive
7 Expression
8 = head:Term tail:(_ ("+" / "-") _ Term)* {
9 var result = head, i;
710
8 additive
9 = left:multiplicative "+" right:additive { return left + right; }
10 / multiplicative
11 for (i = 0; i < tail.length; i++) {
12 if (tail[i][1] === "+") { result += tail[i][3]; }
13 if (tail[i][1] === "-") { result -= tail[i][3]; }
14 }
1115
12 multiplicative
13 = left:primary "*" right:multiplicative { return left * right; }
14 / primary
16 return result;
17 }
1518
16 primary
17 = integer
18 / "(" additive:additive ")" { return additive; }
19 Term
20 = head:Factor tail:(_ ("*" / "/") _ Factor)* {
21 var result = head, i;
1922
20 integer "integer"
21 = digits:[0-9]+ { return parseInt(digits.join(""), 10); }
23 for (i = 0; i < tail.length; i++) {
24 if (tail[i][1] === "*") { result *= tail[i][3]; }
25 if (tail[i][1] === "/") { result /= tail[i][3]; }
26 }
27
28 return result;
29 }
30
31 Factor
32 = "(" _ expr:Expression _ ")" { return expr; }
33 / Integer
34
35 Integer "integer"
36 = [0-9]+ { return parseInt(text(), 10); }
37
38 _ "whitespace"
39 = [ \t\n\r]*
00 /*
1 * CSS parser based on the grammar described at http://www.w3.org/TR/CSS2/grammar.html.
1 * CSS Grammar
2 * ===========
23 *
3 * The parser builds a tree representing the parsed CSS, composed of basic
4 * JavaScript values, arrays and objects (basically JSON). It can be easily
5 * used by various CSS processors, transformers, etc.
4 * Based on grammar from CSS 2.1 specification [1] (including the errata [2]).
5 * Generated parser builds a syntax tree composed of nested JavaScript objects,
6 * vaguely inspired by CSS DOM [3]. The CSS DOM itself wasn't used as it is not
7 * expressive enough (e.g. selectors are reflected as text, not structured
8 * objects) and somewhat cumbersome.
69 *
7 * Note that the parser does not handle errors in CSS according to the
8 * specification -- many errors which it should recover from (e.g. malformed
9 * declarations or unexpected end of stylesheet) are simply fatal. This is a
10 * result of straightforward rewrite of the CSS grammar to PEG.js and it should
11 * be fixed sometimes.
10 * Limitations:
11 *
12 * * Many errors which should be recovered from according to the specification
13 * (e.g. malformed declarations or unexpected end of stylesheet) are fatal.
14 * This is a result of straightforward rewrite of the CSS grammar to PEG.js.
15 *
16 * [1] http://www.w3.org/TR/2011/REC-CSS2-20110607
17 * [2] http://www.w3.org/Style/css2-updates/REC-CSS2-20110607-errata.html
18 * [3] http://www.w3.org/TR/DOM-Level-2-Style/css.html
1219 */
1320
14 /* ===== Syntactical Elements ===== */
21 {
22 function extractOptional(optional, index) {
23 return optional ? optional[index] : null;
24 }
25
26 function extractList(list, index) {
27 var result = [], i;
28
29 for (i = 0; i < list.length; i++) {
30 if (list[i][index] !== null) {
31 result.push(list[i][index]);
32 }
33 }
34
35 return result;
36 }
37
38 function buildList(head, tail, index) {
39 return (head !== null ? [head] : []).concat(extractList(tail, index));
40 }
41
42 function buildExpression(head, tail) {
43 var result = head, i;
44
45 for (i = 0; i < tail.length; i++) {
46 result = {
47 type: "Expression",
48 operator: tail[i][0],
49 left: result,
50 right: tail[i][1]
51 };
52 }
53
54 return result;
55 }
56 }
1557
1658 start
1759 = stylesheet:stylesheet comment* { return stylesheet; }
60
61 /* ----- G.1 Grammar ----- */
1862
1963 stylesheet
2064 = charset:(CHARSET_SYM STRING ";")? (S / CDO / CDC)*
2165 imports:(import (CDO S* / CDC S*)*)*
22 rules:((ruleset / media / page) (CDO S* / CDC S*)*)* {
23 var importsConverted = [];
24 for (var i = 0; i < imports.length; i++) {
25 importsConverted.push(imports[i][0]);
26 }
27
28 var rulesConverted = [];
29 for (i = 0; i < rules.length; i++) {
30 rulesConverted.push(rules[i][0]);
31 }
32
33 return {
34 type: "stylesheet",
35 charset: charset !== "" ? charset[1] : null,
36 imports: importsConverted,
37 rules: rulesConverted
66 rules:((ruleset / media / page) (CDO S* / CDC S*)*)*
67 {
68 return {
69 type: "StyleSheet",
70 charset: extractOptional(charset, 1),
71 imports: extractList(imports, 0),
72 rules: extractList(rules, 0)
3873 };
3974 }
4075
4176 import
4277 = IMPORT_SYM S* href:(STRING / URI) S* media:media_list? ";" S* {
4378 return {
44 type: "import_rule",
79 type: "ImportRule",
4580 href: href,
46 media: media !== "" ? media : []
81 media: media !== null ? media : []
4782 };
4883 }
4984
5085 media
5186 = MEDIA_SYM S* media:media_list "{" S* rules:ruleset* "}" S* {
5287 return {
53 type: "media_rule",
88 type: "MediaRule",
5489 media: media,
5590 rules: rules
5691 };
5792 }
5893
5994 media_list
60 = head:medium tail:("," S* medium)* {
61 var result = [head];
62 for (var i = 0; i < tail.length; i++) {
63 result.push(tail[i][2]);
64 }
65 return result;
66 }
95 = head:medium tail:("," S* medium)* { return buildList(head, tail, 2); }
6796
6897 medium
69 = ident:IDENT S* { return ident; }
98 = name:IDENT S* { return name; }
7099
71100 page
72 = PAGE_SYM S* qualifier:pseudo_page?
101 = PAGE_SYM S* selector:pseudo_page?
73102 "{" S*
74 declarationsHead:declaration?
75 declarationsTail:(";" S* declaration?)*
76 "}" S* {
77 var declarations = declarationsHead !== "" ? [declarationsHead] : [];
78 for (var i = 0; i < declarationsTail.length; i++) {
79 if (declarationsTail[i][2] !== "") {
80 declarations.push(declarationsTail[i][2]);
81 }
82 }
83
84 return {
85 type: "page_rule",
86 qualifier: qualifier !== "" ? qualifier : null,
87 declarations: declarations
103 declarationsFirst:declaration?
104 declarationsRest:(";" S* declaration?)*
105 "}" S*
106 {
107 return {
108 type: "PageRule",
109 selector: selector,
110 declarations: buildList(declarationsFirst, declarationsRest, 2)
88111 };
89112 }
90113
91114 pseudo_page
92 = ":" ident:IDENT S* { return ident; }
115 = ":" value:IDENT S* { return { type: "PseudoSelector", value: value }; }
93116
94117 operator
95118 = "/" S* { return "/"; }
99122 = "+" S* { return "+"; }
100123 / ">" S* { return ">"; }
101124
102 unary_operator
103 = "+"
104 / "-"
105
106125 property
107 = ident:IDENT S* { return ident; }
126 = name:IDENT S* { return name; }
108127
109128 ruleset
110 = selectorsHead:selector
111 selectorsTail:("," S* selector)*
129 = selectorsFirst:selector
130 selectorsRest:("," S* selector)*
112131 "{" S*
113 declarationsHead:declaration?
114 declarationsTail:(";" S* declaration?)*
115 "}" S* {
116 var selectors = [selectorsHead];
117 for (var i = 0; i < selectorsTail.length; i++) {
118 selectors.push(selectorsTail[i][2]);
119 }
120
121 var declarations = declarationsHead !== "" ? [declarationsHead] : [];
122 for (i = 0; i < declarationsTail.length; i++) {
123 if (declarationsTail[i][2] !== "") {
124 declarations.push(declarationsTail[i][2]);
125 }
126 }
127
128 return {
129 type: "ruleset",
130 selectors: selectors,
131 declarations: declarations
132 declarationsFirst:declaration?
133 declarationsRest:(";" S* declaration?)*
134 "}" S*
135 {
136 return {
137 type: "RuleSet",
138 selectors: buildList(selectorsFirst, selectorsRest, 2),
139 declarations: buildList(declarationsFirst, declarationsRest, 2)
132140 };
133141 }
134142
135143 selector
136144 = left:simple_selector S* combinator:combinator right:selector {
137145 return {
138 type: "selector",
146 type: "Selector",
139147 combinator: combinator,
140148 left: left,
141149 right: right
142150 };
143151 }
144 / left:simple_selector S* right:selector {
145 return {
146 type: "selector",
152 / left:simple_selector S+ right:selector {
153 return {
154 type: "Selector",
147155 combinator: " ",
148156 left: left,
149157 right: right
152160 / selector:simple_selector S* { return selector; }
153161
154162 simple_selector
155 = element:element_name
156 qualifiers:(
157 id:HASH { return { type: "ID selector", id: id.substr(1) }; }
158 / class
159 / attrib
160 / pseudo
161 )* {
162 return {
163 type: "simple_selector",
163 = element:element_name qualifiers:(id / class / attrib / pseudo)* {
164 return {
165 type: "SimpleSelector",
164166 element: element,
165167 qualifiers: qualifiers
166168 };
167169 }
168 / qualifiers:(
169 id:HASH { return { type: "ID selector", id: id.substr(1) }; }
170 / class
171 / attrib
172 / pseudo
173 )+ {
174 return {
175 type: "simple_selector",
170 / qualifiers:(id / class / attrib / pseudo)+ {
171 return {
172 type: "SimpleSelector",
176173 element: "*",
177174 qualifiers: qualifiers
178175 };
179176 }
180177
178 id
179 = id:HASH { return { type: "IDSelector", id: id }; }
180
181181 class
182 = "." class_:IDENT { return { type: "class_selector", "class": class_ }; }
182 = "." class_:IDENT { return { type: "ClassSelector", "class": class_ }; }
183183
184184 element_name
185 = IDENT / '*'
185 = IDENT
186 / "*"
186187
187188 attrib
188189 = "[" S*
189190 attribute:IDENT S*
190 operatorAndValue:(
191 ('=' / INCLUDES / DASHMATCH) S*
192 (IDENT / STRING) S*
193 )?
194 "]" {
195 return {
196 type: "attribute_selector",
191 operatorAndValue:(("=" / INCLUDES / DASHMATCH) S* (IDENT / STRING) S*)?
192 "]"
193 {
194 return {
195 type: "AttributeSelector",
197196 attribute: attribute,
198 operator: operatorAndValue !== "" ? operatorAndValue[0] : null,
199 value: operatorAndValue !== "" ? operatorAndValue[2] : null
197 operator: extractOptional(operatorAndValue, 0),
198 value: extractOptional(operatorAndValue, 2)
200199 };
201200 }
202201
205204 value:(
206205 name:FUNCTION S* params:(IDENT S*)? ")" {
207206 return {
208 type: "function",
207 type: "Function",
209208 name: name,
210 params: params !== "" ? [params[0]] : []
209 params: params !== null ? [params[0]] : []
211210 };
212211 }
213212 / IDENT
214 ) {
215 /*
216 * The returned object has somewhat vague property names and values because
217 * the rule matches both pseudo-classes and pseudo-elements (they look the
218 * same at the syntactic level).
219 */
220 return {
221 type: "pseudo_selector",
222 value: value
223 };
224 }
213 )
214 { return { type: "PseudoSelector", value: value }; }
225215
226216 declaration
227 = property:property ":" S* expression:expr important:prio? {
228 return {
229 type: "declaration",
230 property: property,
231 expression: expression,
232 important: important !== "" ? true : false
217 = name:property ':' S* value:expr prio:prio? {
218 return {
219 type: "Declaration",
220 name: name,
221 value: value,
222 important: prio !== null
233223 };
234224 }
235225
237227 = IMPORTANT_SYM S*
238228
239229 expr
240 = head:term tail:(operator? term)* {
241 var result = head;
242 for (var i = 0; i < tail.length; i++) {
243 result = {
244 type: "expression",
245 operator: tail[i][0],
246 left: result,
247 right: tail[i][1]
248 };
249 }
250 return result;
251 }
230 = head:term tail:(operator? term)* { return buildExpression(head, tail); }
252231
253232 term
254 = operator:unary_operator?
255 value:(
256 EMS S*
257 / EXS S*
258 / LENGTH S*
259 / ANGLE S*
260 / TIME S*
261 / FREQ S*
262 / PERCENTAGE S*
263 / NUMBER S*
264 ) { return { type: "value", value: operator + value[0] }; }
265 / value:URI S* { return { type: "uri", value: value }; }
233 = quantity:(PERCENTAGE / LENGTH / EMS / EXS / ANGLE / TIME / FREQ / NUMBER)
234 S*
235 {
236 return {
237 type: "Quantity",
238 value: quantity.value,
239 unit: quantity.unit
240 };
241 }
242 / value:STRING S* { return { type: "String", value: value }; }
243 / value:URI S* { return { type: "URI", value: value }; }
266244 / function
267245 / hexcolor
268 / value:STRING S* { return { type: "string", value: value }; }
269 / value:IDENT S* { return { type: "ident", value: value }; }
246 / value:IDENT S* { return { type: "Ident", value: value }; }
270247
271248 function
272249 = name:FUNCTION S* params:expr ")" S* {
273 return {
274 type: "function",
275 name: name,
276 params: params
277 };
250 return { type: "Function", name: name, params: params };
278251 }
279252
280253 hexcolor
281 = value:HASH S* { return { type: "hexcolor", value: value}; }
282
283 /* ===== Lexical Elements ===== */
254 = value:HASH S* { return { type: "Hexcolor", value: value }; }
255
256 /* ----- G.2 Lexical scanner ----- */
284257
285258 /* Macros */
286259
287260 h
288 = [0-9a-fA-F]
261 = [0-9a-f]i
289262
290263 nonascii
291 = [\x80-\xFF]
264 = [\x80-\uFFFF]
292265
293266 unicode
294 = "\\" h1:h h2:h? h3:h? h4:h? h5:h? h6:h? ("\r\n" / [ \t\r\n\f])? {
295 return String.fromCharCode(parseInt("0x" + h1 + h2 + h3 + h4 + h5 + h6));
267 = "\\" digits:$(h h? h? h? h? h?) ("\r\n" / [ \t\r\n\f])? {
268 return String.fromCharCode(parseInt(digits, 16));
296269 }
297270
298271 escape
299272 = unicode
300 / "\\" char_:[^\r\n\f0-9a-fA-F] { return char_; }
273 / "\\" ch:[^\r\n\f0-9a-f]i { return ch; }
301274
302275 nmstart
303 = [_a-zA-Z]
276 = [_a-z]i
304277 / nonascii
305278 / escape
306279
307280 nmchar
308 = [_a-zA-Z0-9-]
281 = [_a-z0-9-]i
309282 / nonascii
310283 / escape
311284
312 integer
313 = digits:[0-9]+ { return parseInt(digits.join("")); }
314
315 float
316 = before:[0-9]* "." after:[0-9]+ {
317 return parseFloat(before.join("") + "." + after.join(""));
318 }
319
320285 string1
321 = '"' chars:([^\n\r\f\\"] / "\\" nl:nl { return nl } / escape)* '"' {
286 = '"' chars:([^\n\r\f\\"] / "\\" nl:nl { return ""; } / escape)* '"' {
322287 return chars.join("");
323288 }
324289
325290 string2
326 = "'" chars:([^\n\r\f\\'] / "\\" nl:nl { return nl } / escape)* "'" {
291 = "'" chars:([^\n\r\f\\'] / "\\" nl:nl { return ""; } / escape)* "'" {
327292 return chars.join("");
328293 }
329294
331296 = "/*" [^*]* "*"+ ([^/*] [^*]* "*"+)* "/"
332297
333298 ident
334 = dash:"-"? nmstart:nmstart nmchars:nmchar* {
335 return dash + nmstart + nmchars.join("");
299 = prefix:$"-"? start:nmstart chars:nmchar* {
300 return prefix + start + chars.join("");
336301 }
337302
338303 name
339 = nmchars:nmchar+ { return nmchars.join(""); }
304 = chars:nmchar+ { return chars.join(""); }
340305
341306 num
342 = float
343 / integer
307 = [+-]? ([0-9]+ / [0-9]* "." [0-9]+) ("e" [+-]? [0-9]+)? {
308 return parseFloat(text());
309 }
344310
345311 string
346312 = string1
347313 / string2
348314
349315 url
350 = chars:([!#$%&*-~] / nonascii / escape)* { return chars.join(""); }
316 = chars:([!#$%&*-\[\]-~] / nonascii / escape)* { return chars.join(""); }
351317
352318 s
353319 = [ \t\r\n\f]+
361327 / "\r"
362328 / "\f"
363329
364 A
365 = [aA]
366 / "\\" "0"? "0"? "0"? "0"? "41" ("\r\n" / [ \t\r\n\f])? { return "A"; }
367 / "\\" "0"? "0"? "0"? "0"? "61" ("\r\n" / [ \t\r\n\f])? { return "a"; }
368
369 C
370 = [cC]
371 / "\\" "0"? "0"? "0"? "0"? "43" ("\r\n" / [ \t\r\n\f])? { return "C"; }
372 / "\\" "0"? "0"? "0"? "0"? "63" ("\r\n" / [ \t\r\n\f])? { return "c"; }
373
374 D
375 = [dD]
376 / "\\" "0"? "0"? "0"? "0"? "44" ("\r\n" / [ \t\r\n\f])? { return "D"; }
377 / "\\" "0"? "0"? "0"? "0"? "64" ("\r\n" / [ \t\r\n\f])? { return "d"; }
378
379 E
380 = [eE]
381 / "\\" "0"? "0"? "0"? "0"? "45" ("\r\n" / [ \t\r\n\f])? { return "E"; }
382 / "\\" "0"? "0"? "0"? "0"? "65" ("\r\n" / [ \t\r\n\f])? { return "e"; }
383
384 G
385 = [gG]
386 / "\\" "0"? "0"? "0"? "0"? "47" ("\r\n" / [ \t\r\n\f])? { return "G"; }
387 / "\\" "0"? "0"? "0"? "0"? "67" ("\r\n" / [ \t\r\n\f])? { return "g"; }
388 / "\\" char_:[gG] { return char_; }
389
390 H
391 = h:[hH]
392 / "\\" "0"? "0"? "0"? "0"? "48" ("\r\n" / [ \t\r\n\f])? { return "H"; }
393 / "\\" "0"? "0"? "0"? "0"? "68" ("\r\n" / [ \t\r\n\f])? { return "h"; }
394 / "\\" char_:[hH] { return char_; }
395
396 I
397 = i:[iI]
398 / "\\" "0"? "0"? "0"? "0"? "49" ("\r\n" / [ \t\r\n\f])? { return "I"; }
399 / "\\" "0"? "0"? "0"? "0"? "69" ("\r\n" / [ \t\r\n\f])? { return "i"; }
400 / "\\" char_:[iI] { return char_; }
401
402 K
403 = [kK]
404 / "\\" "0"? "0"? "0"? "0"? "4" [bB] ("\r\n" / [ \t\r\n\f])? { return "K"; }
405 / "\\" "0"? "0"? "0"? "0"? "6" [bB] ("\r\n" / [ \t\r\n\f])? { return "k"; }
406 / "\\" char_:[kK] { return char_; }
407
408 L
409 = [lL]
410 / "\\" "0"? "0"? "0"? "0"? "4" [cC] ("\r\n" / [ \t\r\n\f])? { return "L"; }
411 / "\\" "0"? "0"? "0"? "0"? "6" [cC] ("\r\n" / [ \t\r\n\f])? { return "l"; }
412 / "\\" char_:[lL] { return char_; }
413
414 M
415 = [mM]
416 / "\\" "0"? "0"? "0"? "0"? "4" [dD] ("\r\n" / [ \t\r\n\f])? { return "M"; }
417 / "\\" "0"? "0"? "0"? "0"? "6" [dD] ("\r\n" / [ \t\r\n\f])? { return "m"; }
418 / "\\" char_:[mM] { return char_; }
419
420 N
421 = [nN]
422 / "\\" "0"? "0"? "0"? "0"? "4" [eE] ("\r\n" / [ \t\r\n\f])? { return "N"; }
423 / "\\" "0"? "0"? "0"? "0"? "6" [eE] ("\r\n" / [ \t\r\n\f])? { return "n"; }
424 / "\\" char_:[nN] { return char_; }
425
426 O
427 = [oO]
428 / "\\" "0"? "0"? "0"? "0"? "4" [fF] ("\r\n" / [ \t\r\n\f])? { return "O"; }
429 / "\\" "0"? "0"? "0"? "0"? "6" [fF] ("\r\n" / [ \t\r\n\f])? { return "o"; }
430 / "\\" char_:[oO] { return char_; }
431
432 P
433 = [pP]
434 / "\\" "0"? "0"? "0"? "0"? "50" ("\r\n" / [ \t\r\n\f])? { return "P"; }
435 / "\\" "0"? "0"? "0"? "0"? "70" ("\r\n" / [ \t\r\n\f])? { return "p"; }
436 / "\\" char_:[pP] { return char_; }
437
438 R
439 = [rR]
440 / "\\" "0"? "0"? "0"? "0"? "52" ("\r\n" / [ \t\r\n\f])? { return "R"; }
441 / "\\" "0"? "0"? "0"? "0"? "72" ("\r\n" / [ \t\r\n\f])? { return "r"; }
442 / "\\" char_:[rR] { return char_; }
443
444 S_
445 = [sS]
446 / "\\" "0"? "0"? "0"? "0"? "53" ("\r\n" / [ \t\r\n\f])? { return "S"; }
447 / "\\" "0"? "0"? "0"? "0"? "73" ("\r\n" / [ \t\r\n\f])? { return "s"; }
448 / "\\" char_:[sS] { return char_; }
449
450 T
451 = [tT]
452 / "\\" "0"? "0"? "0"? "0"? "54" ("\r\n" / [ \t\r\n\f])? { return "T"; }
453 / "\\" "0"? "0"? "0"? "0"? "74" ("\r\n" / [ \t\r\n\f])? { return "t"; }
454 / "\\" char_:[tT] { return char_; }
455
456 U
457 = [uU]
458 / "\\" "0"? "0"? "0"? "0"? "55" ("\r\n" / [ \t\r\n\f])? { return "U"; }
459 / "\\" "0"? "0"? "0"? "0"? "75" ("\r\n" / [ \t\r\n\f])? { return "u"; }
460 / "\\" char_:[uU] { return char_; }
461
462 X
463 = [xX]
464 / "\\" "0"? "0"? "0"? "0"? "58" ("\r\n" / [ \t\r\n\f])? { return "X"; }
465 / "\\" "0"? "0"? "0"? "0"? "78" ("\r\n" / [ \t\r\n\f])? { return "x"; }
466 / "\\" char_:[xX] { return char_; }
467
468 Z
469 = [zZ]
470 / "\\" "0"? "0"? "0"? "0"? "5" [aA] ("\r\n" / [ \t\r\n\f])? { return "Z"; }
471 / "\\" "0"? "0"? "0"? "0"? "7" [aA] ("\r\n" / [ \t\r\n\f])? { return "z"; }
472 / "\\" char_:[zZ] { return char_; }
330 A = "a"i / "\\" "0"? "0"? "0"? "0"? [\x41\x61] ("\r\n" / [ \t\r\n\f])? { return "a"; }
331 C = "c"i / "\\" "0"? "0"? "0"? "0"? [\x43\x63] ("\r\n" / [ \t\r\n\f])? { return "c"; }
332 D = "d"i / "\\" "0"? "0"? "0"? "0"? [\x44\x64] ("\r\n" / [ \t\r\n\f])? { return "d"; }
333 E = "e"i / "\\" "0"? "0"? "0"? "0"? [\x45\x65] ("\r\n" / [ \t\r\n\f])? { return "e"; }
334 G = "g"i / "\\" "0"? "0"? "0"? "0"? [\x47\x67] ("\r\n" / [ \t\r\n\f])? / "\\g"i { return "g"; }
335 H = "h"i / "\\" "0"? "0"? "0"? "0"? [\x48\x68] ("\r\n" / [ \t\r\n\f])? / "\\h"i { return "h"; }
336 I = "i"i / "\\" "0"? "0"? "0"? "0"? [\x49\x69] ("\r\n" / [ \t\r\n\f])? / "\\i"i { return "i"; }
337 K = "k"i / "\\" "0"? "0"? "0"? "0"? [\x4b\x6b] ("\r\n" / [ \t\r\n\f])? / "\\k"i { return "k"; }
338 L = "l"i / "\\" "0"? "0"? "0"? "0"? [\x4c\x6c] ("\r\n" / [ \t\r\n\f])? / "\\l"i { return "l"; }
339 M = "m"i / "\\" "0"? "0"? "0"? "0"? [\x4d\x6d] ("\r\n" / [ \t\r\n\f])? / "\\m"i { return "m"; }
340 N = "n"i / "\\" "0"? "0"? "0"? "0"? [\x4e\x6e] ("\r\n" / [ \t\r\n\f])? / "\\n"i { return "n"; }
341 O = "o"i / "\\" "0"? "0"? "0"? "0"? [\x4f\x6f] ("\r\n" / [ \t\r\n\f])? / "\\o"i { return "o"; }
342 P = "p"i / "\\" "0"? "0"? "0"? "0"? [\x50\x70] ("\r\n" / [ \t\r\n\f])? / "\\p"i { return "p"; }
343 R = "r"i / "\\" "0"? "0"? "0"? "0"? [\x52\x72] ("\r\n" / [ \t\r\n\f])? / "\\r"i { return "r"; }
344 S_ = "s"i / "\\" "0"? "0"? "0"? "0"? [\x53\x73] ("\r\n" / [ \t\r\n\f])? / "\\s"i { return "s"; }
345 T = "t"i / "\\" "0"? "0"? "0"? "0"? [\x54\x74] ("\r\n" / [ \t\r\n\f])? / "\\t"i { return "t"; }
346 U = "u"i / "\\" "0"? "0"? "0"? "0"? [\x55\x75] ("\r\n" / [ \t\r\n\f])? / "\\u"i { return "u"; }
347 X = "x"i / "\\" "0"? "0"? "0"? "0"? [\x58\x78] ("\r\n" / [ \t\r\n\f])? / "\\x"i { return "x"; }
348 Z = "z"i / "\\" "0"? "0"? "0"? "0"? [\x5a\x7a] ("\r\n" / [ \t\r\n\f])? / "\\z"i { return "z"; }
473349
474350 /* Tokens */
475351
509385 CHARSET_SYM "@charset"
510386 = comment* "@charset "
511387
512 /* Note: We replace "w" with "s" here to avoid infinite recursion. */
388 /* We use |s| instead of |w| here to avoid infinite recursion. */
513389 IMPORTANT_SYM "!important"
514 = comment* "!" (s / comment)* I M P O R T A N T { return "!important"; }
390 = comment* "!" (s / comment)* I M P O R T A N T
515391
516392 EMS "length"
517 = comment* num:num e:E m:M { return num + e + m; }
393 = comment* value:num E M { return { value: value, unit: "em" }; }
518394
519395 EXS "length"
520 = comment* num:num e:E x:X { return num + e + x; }
396 = comment* value:num E X { return { value: value, unit: "ex" }; }
521397
522398 LENGTH "length"
523 = comment* num:num unit:(P X / C M / M M / I N / P T / P C) {
524 return num + unit.join("");
525 }
399 = comment* value:num P X { return { value: value, unit: "px" }; }
400 / comment* value:num C M { return { value: value, unit: "cm" }; }
401 / comment* value:num M M { return { value: value, unit: "mm" }; }
402 / comment* value:num I N { return { value: value, unit: "in" }; }
403 / comment* value:num P T { return { value: value, unit: "pt" }; }
404 / comment* value:num P C { return { value: value, unit: "pc" }; }
526405
527406 ANGLE "angle"
528 = comment* num:num unit:(D E G / R A D / G R A D) {
529 return num + unit.join("");
530 }
407 = comment* value:num D E G { return { value: value, unit: "deg" }; }
408 / comment* value:num R A D { return { value: value, unit: "rad" }; }
409 / comment* value:num G R A D { return { value: value, unit: "grad" }; }
531410
532411 TIME "time"
533 = comment* num:num unit:(m:M s:S_ { return m + s; } / S_) {
534 return num + unit;
535 }
412 = comment* value:num M S_ { return { value: value, unit: "ms" }; }
413 / comment* value:num S_ { return { value: value, unit: "s" }; }
536414
537415 FREQ "frequency"
538 = comment* num:num unit:(H Z / K H Z) { return num + unit.join(""); }
539
540 DIMENSION "dimension"
541 = comment* num:num unit:ident { return num + unit; }
416 = comment* value:num H Z { return { value: value, unit: "hz" }; }
417 / comment* value:num K H Z { return { value: value, unit: "kh" }; }
542418
543419 PERCENTAGE "percentage"
544 = comment* num:num "%" { return num + "%"; }
420 = comment* value:num "%" { return { value: value, unit: "%" }; }
545421
546422 NUMBER "number"
547 = comment* num:num { return num; }
423 = comment* value:num { return { value: value, unit: null }; }
548424
549425 URI "uri"
550 = comment* U R L "(" w value:(string / url) w ")" { return value; }
426 = comment* U R L "("i w url:string w ")" { return url; }
427 / comment* U R L "("i w url:url w ")" { return url; }
551428
552429 FUNCTION "function"
553430 = comment* name:ident "(" { return name; }
00 /*
1 * JavaScript parser based on the grammar described in ECMA-262, 5th ed.
2 * (http://www.ecma-international.org/publications/standards/Ecma-262.htm)
1 * JavaScript Grammar
2 * ==================
33 *
4 * The parser builds a tree representing the parsed JavaScript, composed of
5 * basic JavaScript values, arrays and objects (basically JSON). It can be
6 * easily used by various JavaScript processors, transformers, etc.
7 *
8 * Intentional deviations from ECMA-262, 5th ed.:
9 *
10 * * The specification does not consider |FunctionDeclaration| and
11 * |FunctionExpression| as statements, but JavaScript implementations do and
12 * so are we. This syntax is actually used in the wild (e.g. by jQuery).
4 * Based on grammar from ECMA-262, 5.1 Edition [1]. Generated parser builds a
5 * syntax tree compatible with Mozilla SpiderMonkey Parser API [2]. Properties
6 * and node types reflecting features not present in ECMA-262 are not included.
137 *
148 * Limitations:
159 *
16 * * Non-BMP characters are completely ignored to avoid surrogate
17 * pair handling (JavaScript strings in most implementations are AFAIK
18 * encoded in UTF-16, though this is not required by the specification --
19 * see ECMA-262, 5th ed., 4.3.16).
10 * * Non-BMP characters are completely ignored to avoid surrogate pair
11 * handling.
2012 *
2113 * * One can create identifiers containing illegal characters using Unicode
2214 * escape sequences. For example, "abcd\u0020efgh" is not a valid
2315 * identifier, but it is accepted by the parser.
2416 *
25 * * Strict mode is not recognized. That means that within strict mode code,
17 * * Strict mode is not recognized. This means that within strict mode code,
2618 * "implements", "interface", "let", "package", "private", "protected",
2719 * "public", "static" and "yield" can be used as names. Many other
28 * restrictions and exceptions from ECMA-262, 5th ed., Annex C are also not
29 * applied.
20 * restrictions and exceptions from Annex C are also not applied.
3021 *
31 * * The parser does not handle regular expression literal syntax (basically,
32 * it treats anything between "/"'s as an opaque character sequence and also
33 * does not recognize invalid flags properly).
22 * All the limitations could be resolved, but the costs would likely outweigh
23 * the benefits.
3424 *
35 * * The parser doesn't report any early errors except syntax errors (see
36 * ECMA-262, 5th ed., 16).
25 * Many thanks to inimino [3] for his grammar [4] which helped me to solve some
26 * problems (such as automatic semicolon insertion) and also served to double
27 * check that I converted the original grammar correctly.
3728 *
38 * At least some of these limitations should be fixed sometimes.
39 *
40 * Many thanks to inimino (http://inimino.org/~inimino/blog/) for his ES5 PEG
41 * (http://boshi.inimino.org/3box/asof/1270029991384/PEG/ECMAScript_unified.peg),
42 * which helped me to solve some problems (such as automatic semicolon
43 * insertion) and also served to double check that I converted the original
44 * grammar correctly.
29 * [1] http://www.ecma-international.org/publications/standards/Ecma-262.htm
30 * [2] https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API
31 * [3] http://inimino.org/~inimino/blog/
32 * [4] http://boshi.inimino.org/3box/asof/1270029991384/PEG/ECMAScript_unified.peg
4533 */
4634
47 start
35 {
36 var TYPES_TO_PROPERTY_NAMES = {
37 CallExpression: "callee",
38 MemberExpression: "object",
39 };
40
41 function filledArray(count, value) {
42 var result = new Array(count), i;
43
44 for (i = 0; i < count; i++) {
45 result[i] = value;
46 }
47
48 return result;
49 }
50
51 function extractOptional(optional, index) {
52 return optional ? optional[index] : null;
53 }
54
55 function extractList(list, index) {
56 var result = new Array(list.length), i;
57
58 for (i = 0; i < list.length; i++) {
59 result[i] = list[i][index];
60 }
61
62 return result;
63 }
64
65 function buildList(head, tail, index) {
66 return [head].concat(extractList(tail, index));
67 }
68
69 function buildTree(head, tail, builder) {
70 var result = head, i;
71
72 for (i = 0; i < tail.length; i++) {
73 result = builder(result, tail[i]);
74 }
75
76 return result;
77 }
78
79 function buildBinaryExpression(head, tail) {
80 return buildTree(head, tail, function(result, element) {
81 return {
82 type: "BinaryExpression",
83 operator: element[1],
84 left: result,
85 right: element[3]
86 };
87 });
88 }
89
90 function buildLogicalExpression(head, tail) {
91 return buildTree(head, tail, function(result, element) {
92 return {
93 type: "LogicalExpression",
94 operator: element[1],
95 left: result,
96 right: element[3]
97 };
98 });
99 }
100
101 function optionalList(value) {
102 return value !== null ? value : [];
103 }
104 }
105
106 Start
48107 = __ program:Program __ { return program; }
49108
50 /* ===== A.1 Lexical Grammar ===== */
109 /* ----- A.1 Lexical Grammar ----- */
51110
52111 SourceCharacter
53112 = .
54113
55114 WhiteSpace "whitespace"
56 = [\t\v\f \u00A0\uFEFF]
115 = "\t"
116 / "\v"
117 / "\f"
118 / " "
119 / "\u00A0"
120 / "\uFEFF"
57121 / Zs
58122
59123 LineTerminator
63127 = "\n"
64128 / "\r\n"
65129 / "\r"
66 / "\u2028" // line separator
67 / "\u2029" // paragraph separator
130 / "\u2028"
131 / "\u2029"
68132
69133 Comment "comment"
70134 = MultiLineComment
79143 SingleLineComment
80144 = "//" (!LineTerminator SourceCharacter)*
81145
82 Identifier "identifier"
146 Identifier
83147 = !ReservedWord name:IdentifierName { return name; }
84148
85149 IdentifierName "identifier"
86 = start:IdentifierStart parts:IdentifierPart* {
87 return start + parts.join("");
150 = head:IdentifierStart tail:IdentifierPart* {
151 return {
152 type: "Identifier",
153 name: head + tail.join("")
154 };
88155 }
89156
90157 IdentifierStart
98165 / UnicodeCombiningMark
99166 / UnicodeDigit
100167 / UnicodeConnectorPunctuation
101 / "\u200C" { return "\u200C"; } // zero-width non-joiner
102 / "\u200D" { return "\u200D"; } // zero-width joiner
168 / "\u200C"
169 / "\u200D"
103170
104171 UnicodeLetter
105172 = Lu
126193 / BooleanLiteral
127194
128195 Keyword
129 = (
130 "break"
131 / "case"
132 / "catch"
133 / "continue"
134 / "debugger"
135 / "default"
136 / "delete"
137 / "do"
138 / "else"
139 / "finally"
140 / "for"
141 / "function"
142 / "if"
143 / "instanceof"
144 / "in"
145 / "new"
146 / "return"
147 / "switch"
148 / "this"
149 / "throw"
150 / "try"
151 / "typeof"
152 / "var"
153 / "void"
154 / "while"
155 / "with"
156 )
157 !IdentifierPart
196 = BreakToken
197 / CaseToken
198 / CatchToken
199 / ContinueToken
200 / DebuggerToken
201 / DefaultToken
202 / DeleteToken
203 / DoToken
204 / ElseToken
205 / FinallyToken
206 / ForToken
207 / FunctionToken
208 / IfToken
209 / InstanceofToken
210 / InToken
211 / NewToken
212 / ReturnToken
213 / SwitchToken
214 / ThisToken
215 / ThrowToken
216 / TryToken
217 / TypeofToken
218 / VarToken
219 / VoidToken
220 / WhileToken
221 / WithToken
158222
159223 FutureReservedWord
160 = (
161 "class"
162 / "const"
163 / "enum"
164 / "export"
165 / "extends"
166 / "import"
167 / "super"
168 )
169 !IdentifierPart
170
171 /*
172 * This rule contains an error in the specification: |RegularExpressionLiteral|
173 * is missing.
174 */
224 = ClassToken
225 / ConstToken
226 / EnumToken
227 / ExportToken
228 / ExtendsToken
229 / ImportToken
230 / SuperToken
231
175232 Literal
176233 = NullLiteral
177234 / BooleanLiteral
178 / value:NumericLiteral {
179 return {
180 type: "NumericLiteral",
181 value: value
182 };
183 }
184 / value:StringLiteral {
185 return {
186 type: "StringLiteral",
187 value: value
188 };
189 }
235 / NumericLiteral
236 / StringLiteral
190237 / RegularExpressionLiteral
191238
192239 NullLiteral
193 = NullToken { return { type: "NullLiteral" }; }
240 = NullToken { return { type: "Literal", value: null }; }
194241
195242 BooleanLiteral
196 = TrueToken { return { type: "BooleanLiteral", value: true }; }
197 / FalseToken { return { type: "BooleanLiteral", value: false }; }
198
243 = TrueToken { return { type: "Literal", value: true }; }
244 / FalseToken { return { type: "Literal", value: false }; }
245
246 /*
247 * The "!(IdentifierStart / DecimalDigit)" predicate is not part of the official
248 * grammar, it comes from text in section 7.8.3.
249 */
199250 NumericLiteral "number"
200 = literal:(HexIntegerLiteral / DecimalLiteral) !IdentifierStart {
251 = literal:HexIntegerLiteral !(IdentifierStart / DecimalDigit) {
201252 return literal;
202253 }
254 / literal:DecimalLiteral !(IdentifierStart / DecimalDigit) {
255 return literal;
256 }
203257
204258 DecimalLiteral
205 = before:DecimalIntegerLiteral
206 "."
207 after:DecimalDigits?
208 exponent:ExponentPart? {
209 return parseFloat(before + "." + after + exponent);
210 }
211 / "." after:DecimalDigits exponent:ExponentPart? {
212 return parseFloat("." + after + exponent);
213 }
214 / before:DecimalIntegerLiteral exponent:ExponentPart? {
215 return parseFloat(before + exponent);
259 = DecimalIntegerLiteral "." DecimalDigit* ExponentPart? {
260 return { type: "Literal", value: parseFloat(text()) };
261 }
262 / "." DecimalDigit+ ExponentPart? {
263 return { type: "Literal", value: parseFloat(text()) };
264 }
265 / DecimalIntegerLiteral ExponentPart? {
266 return { type: "Literal", value: parseFloat(text()) };
216267 }
217268
218269 DecimalIntegerLiteral
219 = "0" / digit:NonZeroDigit digits:DecimalDigits? { return digit + digits; }
220
221 DecimalDigits
222 = digits:DecimalDigit+ { return digits.join(""); }
270 = "0"
271 / NonZeroDigit DecimalDigit*
223272
224273 DecimalDigit
225274 = [0-9]
228277 = [1-9]
229278
230279 ExponentPart
231 = indicator:ExponentIndicator integer:SignedInteger {
232 return indicator + integer;
233 }
280 = ExponentIndicator SignedInteger
234281
235282 ExponentIndicator
236 = [eE]
283 = "e"i
237284
238285 SignedInteger
239 = sign:[-+]? digits:DecimalDigits { return sign + digits; }
286 = [+-]? DecimalDigit+
240287
241288 HexIntegerLiteral
242 = "0" [xX] digits:HexDigit+ { return parseInt("0x" + digits.join("")); }
289 = "0x"i digits:$HexDigit+ {
290 return { type: "Literal", value: parseInt(digits, 16) };
291 }
243292
244293 HexDigit
245 = [0-9a-fA-F]
294 = [0-9a-f]i
246295
247296 StringLiteral "string"
248 = parts:('"' DoubleStringCharacters? '"' / "'" SingleStringCharacters? "'") {
249 return parts[1];
250 }
251
252 DoubleStringCharacters
253 = chars:DoubleStringCharacter+ { return chars.join(""); }
254
255 SingleStringCharacters
256 = chars:SingleStringCharacter+ { return chars.join(""); }
297 = '"' chars:DoubleStringCharacter* '"' {
298 return { type: "Literal", value: chars.join("") };
299 }
300 / "'" chars:SingleStringCharacter* "'" {
301 return { type: "Literal", value: chars.join("") };
302 }
257303
258304 DoubleStringCharacter
259 = !('"' / "\\" / LineTerminator) char_:SourceCharacter { return char_; }
260 / "\\" sequence:EscapeSequence { return sequence; }
305 = !('"' / "\\" / LineTerminator) SourceCharacter { return text(); }
306 / "\\" sequence:EscapeSequence { return sequence; }
261307 / LineContinuation
262308
263309 SingleStringCharacter
264 = !("'" / "\\" / LineTerminator) char_:SourceCharacter { return char_; }
265 / "\\" sequence:EscapeSequence { return sequence; }
310 = !("'" / "\\" / LineTerminator) SourceCharacter { return text(); }
311 / "\\" sequence:EscapeSequence { return sequence; }
266312 / LineContinuation
267313
268314 LineContinuation
269 = "\\" sequence:LineTerminatorSequence { return sequence; }
315 = "\\" LineTerminatorSequence { return ""; }
270316
271317 EscapeSequence
272318 = CharacterEscapeSequence
279325 / NonEscapeCharacter
280326
281327 SingleEscapeCharacter
282 = char_:['"\\bfnrtv] {
283 return char_
284 .replace("b", "\b")
285 .replace("f", "\f")
286 .replace("n", "\n")
287 .replace("r", "\r")
288 .replace("t", "\t")
289 .replace("v", "\x0B") // IE does not recognize "\v".
290 }
328 = "'"
329 / '"'
330 / "\\"
331 / "b" { return "\b"; }
332 / "f" { return "\f"; }
333 / "n" { return "\n"; }
334 / "r" { return "\r"; }
335 / "t" { return "\t"; }
336 / "v" { return "\x0B"; } // IE does not recognize "\v".
291337
292338 NonEscapeCharacter
293 = (!EscapeCharacter / LineTerminator) char_:SourceCharacter { return char_; }
339 = !(EscapeCharacter / LineTerminator) SourceCharacter { return text(); }
294340
295341 EscapeCharacter
296342 = SingleEscapeCharacter
299345 / "u"
300346
301347 HexEscapeSequence
302 = "x" h1:HexDigit h2:HexDigit {
303 return String.fromCharCode(parseInt("0x" + h1 + h2));
348 = "x" digits:$(HexDigit HexDigit) {
349 return String.fromCharCode(parseInt(digits, 16));
304350 }
305351
306352 UnicodeEscapeSequence
307 = "u" h1:HexDigit h2:HexDigit h3:HexDigit h4:HexDigit {
308 return String.fromCharCode(parseInt("0x" + h1 + h2 + h3 + h4));
353 = "u" digits:$(HexDigit HexDigit HexDigit HexDigit) {
354 return String.fromCharCode(parseInt(digits, 16));
309355 }
310356
311357 RegularExpressionLiteral "regular expression"
312 = "/" body:RegularExpressionBody "/" flags:RegularExpressionFlags {
313 return {
314 type: "RegularExpressionLiteral",
315 body: body,
316 flags: flags
317 };
358 = "/" pattern:$RegularExpressionBody "/" flags:$RegularExpressionFlags {
359 var value;
360
361 try {
362 value = new RegExp(pattern, flags);
363 } catch (e) {
364 error(e.message);
365 }
366
367 return { type: "Literal", value: value };
318368 }
319369
320370 RegularExpressionBody
321 = char_:RegularExpressionFirstChar chars:RegularExpressionChars {
322 return char_ + chars;
323 }
324
325 RegularExpressionChars
326 = chars:RegularExpressionChar* { return chars.join(""); }
371 = RegularExpressionFirstChar RegularExpressionChar*
327372
328373 RegularExpressionFirstChar
329 = ![*\\/[] char_:RegularExpressionNonTerminator { return char_; }
374 = ![*\\/[] RegularExpressionNonTerminator
330375 / RegularExpressionBackslashSequence
331376 / RegularExpressionClass
332377
333378 RegularExpressionChar
334 = ![\\/[] char_:RegularExpressionNonTerminator { return char_; }
379 = ![\\/[] RegularExpressionNonTerminator
335380 / RegularExpressionBackslashSequence
336381 / RegularExpressionClass
337382
338 /*
339 * This rule contains an error in the specification: "NonTerminator" instead of
340 * "RegularExpressionNonTerminator".
341 */
342383 RegularExpressionBackslashSequence
343 = "\\" char_:RegularExpressionNonTerminator { return "\\" + char_; }
384 = "\\" RegularExpressionNonTerminator
344385
345386 RegularExpressionNonTerminator
346 = !LineTerminator char_:SourceCharacter { return char_; }
387 = !LineTerminator SourceCharacter
347388
348389 RegularExpressionClass
349 = "[" chars:RegularExpressionClassChars "]" { return "[" + chars + "]"; }
350
351 RegularExpressionClassChars
352 = chars:RegularExpressionClassChar* { return chars.join(""); }
390 = "[" RegularExpressionClassChar* "]"
353391
354392 RegularExpressionClassChar
355 = ![\]\\] char_:RegularExpressionNonTerminator { return char_; }
393 = ![\]\\] RegularExpressionNonTerminator
356394 / RegularExpressionBackslashSequence
357395
358396 RegularExpressionFlags
359 = parts:IdentifierPart* { return parts.join(""); }
360
361 /* Tokens */
362
363 BreakToken = "break" !IdentifierPart
364 CaseToken = "case" !IdentifierPart
365 CatchToken = "catch" !IdentifierPart
366 ContinueToken = "continue" !IdentifierPart
367 DebuggerToken = "debugger" !IdentifierPart
368 DefaultToken = "default" !IdentifierPart
369 DeleteToken = "delete" !IdentifierPart { return "delete"; }
370 DoToken = "do" !IdentifierPart
371 ElseToken = "else" !IdentifierPart
372 FalseToken = "false" !IdentifierPart
373 FinallyToken = "finally" !IdentifierPart
374 ForToken = "for" !IdentifierPart
375 FunctionToken = "function" !IdentifierPart
376 GetToken = "get" !IdentifierPart
377 IfToken = "if" !IdentifierPart
378 InstanceofToken = "instanceof" !IdentifierPart { return "instanceof"; }
379 InToken = "in" !IdentifierPart { return "in"; }
380 NewToken = "new" !IdentifierPart
381 NullToken = "null" !IdentifierPart
382 ReturnToken = "return" !IdentifierPart
383 SetToken = "set" !IdentifierPart
384 SwitchToken = "switch" !IdentifierPart
385 ThisToken = "this" !IdentifierPart
386 ThrowToken = "throw" !IdentifierPart
387 TrueToken = "true" !IdentifierPart
388 TryToken = "try" !IdentifierPart
389 TypeofToken = "typeof" !IdentifierPart { return "typeof"; }
390 VarToken = "var" !IdentifierPart
391 VoidToken = "void" !IdentifierPart { return "void"; }
392 WhileToken = "while" !IdentifierPart
393 WithToken = "with" !IdentifierPart
397 = IdentifierPart*
394398
395399 /*
396400 * Unicode Character Categories
397401 *
398 * Source: http://www.fileformat.info/info/unicode/category/index.htm
402 * Extracted from the following Unicode Character Database file:
403 *
404 * http://www.unicode.org/Public/8.0.0/ucd/extracted/DerivedGeneralCategory.txt
405 *
406 * Unix magic used:
407 *
408 * grep "; $CATEGORY" DerivedGeneralCategory.txt | # Filter characters
409 * cut -f1 -d " " | # Extract code points
410 * grep -v '[0-9a-fA-F]\{5\}' | # Exclude non-BMP characters
411 * sed -e 's/\.\./-/' | # Adjust formatting
412 * sed -e 's/\([0-9a-fA-F]\{4\}\)/\\u\1/g' | # Adjust formatting
413 * tr -d '\n' # Join lines
414 *
415 * ECMA-262 allows using Unicode 3.0 or later, version 8.0.0 was the latest one
416 * at the time of writing.
417 *
418 * Non-BMP characters are completely ignored to avoid surrogate pair handling
419 * (detecting surrogate pairs isn't possible with a simple character class and
420 * other methods would degrade performance). I don't consider it a big deal as
421 * even parsers in JavaScript engines of common browsers seem to ignore them.
399422 */
400423
401 /*
402 * Non-BMP characters are completely ignored to avoid surrogate pair handling
403 * (JavaScript strings in most implementations are encoded in UTF-16, though
404 * this is not required by the specification -- see ECMA-262, 5th ed., 4.3.16).
405 *
406 * If you ever need to correctly recognize all the characters, please feel free
407 * to implement that and send a patch.
408 */
409
410424 // Letter, Lowercase
411 Ll = [\u0061\u0062\u0063\u0064\u0065\u0066\u0067\u0068\u0069\u006A\u006B\u006C\u006D\u006E\u006F\u0070\u0071\u0072\u0073\u0074\u0075\u0076\u0077\u0078\u0079\u007A\u00AA\u00B5\u00BA\u00DF\u00E0\u00E1\u00E2\u00E3\u00E4\u00E5\u00E6\u00E7\u00E8\u00E9\u00EA\u00EB\u00EC\u00ED\u00EE\u00EF\u00F0\u00F1\u00F2\u00F3\u00F4\u00F5\u00F6\u00F8\u00F9\u00FA\u00FB\u00FC\u00FD\u00FE\u00FF\u0101\u0103\u0105\u0107\u0109\u010B\u010D\u010F\u0111\u0113\u0115\u0117\u0119\u011B\u011D\u011F\u0121\u0123\u0125\u0127\u0129\u012B\u012D\u012F\u0131\u0133\u0135\u0137\u0138\u013A\u013C\u013E\u0140\u0142\u0144\u0146\u0148\u0149\u014B\u014D\u014F\u0151\u0153\u0155\u0157\u0159\u015B\u015D\u015F\u0161\u0163\u0165\u0167\u0169\u016B\u016D\u016F\u0171\u0173\u0175\u0177\u017A\u017C\u017E\u017F\u0180\u0183\u0185\u0188\u018C\u018D\u0192\u0195\u0199\u019A\u019B\u019E\u01A1\u01A3\u01A5\u01A8\u01AA\u01AB\u01AD\u01B0\u01B4\u01B6\u01B9\u01BA\u01BD\u01BE\u01BF\u01C6\u01C9\u01CC\u01CE\u01D0\u01D2\u01D4\u01D6\u01D8\u01DA\u01DC\u01DD\u01DF\u01E1\u01E3\u01E5\u01E7\u01E9\u01EB\u01ED\u01EF\u01F0\u01F3\u01F5\u01F9\u01FB\u01FD\u01FF\u0201\u0203\u0205\u0207\u0209\u020B\u020D\u020F\u0211\u0213\u0215\u0217\u0219\u021B\u021D\u021F\u0221\u0223\u0225\u0227\u0229\u022B\u022D\u022F\u0231\u0233\u0234\u0235\u0236\u0237\u0238\u0239\u023C\u023F\u0240\u0242\u0247\u0249\u024B\u024D\u024F\u0250\u0251\u0252\u0253\u0254\u0255\u0256\u0257\u0258\u0259\u025A\u025B\u025C\u025D\u025E\u025F\u0260\u0261\u0262\u0263\u0264\u0265\u0266\u0267\u0268\u0269\u026A\u026B\u026C\u026D\u026E\u026F\u0270\u0271\u0272\u0273\u0274\u0275\u0276\u0277\u0278\u0279\u027A\u027B\u027C\u027D\u027E\u027F\u0280\u0281\u0282\u0283\u0284\u0285\u0286\u0287\u0288\u0289\u028A\u028B\u028C\u028D\u028E\u028F\u0290\u0291\u0292\u0293\u0295\u0296\u0297\u0298\u0299\u029A\u029B\u029C\u029D\u029E\u029F\u02A0\u02A1\u02A2\u02A3\u02A4\u02A5\u02A6\u02A7\u02A8\u02A9\u02AA\u02AB\u02AC\u02AD\u02AE\u02AF\u0371\u0373\u0377\u037B\u037C\u037D\u0390\u03AC\u03AD\u03AE\u03AF\u03B0\u03B1\u03B2\u03B3\u03B4\u03B5\u03B6\u03B7\u03B8\u03B9\u03BA\u03BB\u03BC\u03BD\u03BE\u03BF\u03C0\u03C1\u03C2\u03C3\u03C4\u03C5\u03C6\u03C7\u03C8\u03C9\u03CA\u03CB\u03CC\u03CD\u03CE\u03D0\u03D1\u03D5\u03D6\u03D7\u03D9\u03DB\u03DD\u03DF\u03E1\u03E3\u03E5\u03E7\u03E9\u03EB\u03ED\u03EF\u03F0\u03F1\u03F2\u03F3\u03F5\u03F8\u03FB\u03FC\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043A\u043B\u043C\u043D\u043E\u043F\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044A\u044B\u044C\u044D\u044E\u044F\u0450\u0451\u0452\u0453\u0454\u0455\u0456\u0457\u0458\u0459\u045A\u045B\u045C\u045D\u045E\u045F\u0461\u0463\u0465\u0467\u0469\u046B\u046D\u046F\u0471\u0473\u0475\u0477\u0479\u047B\u047D\u047F\u0481\u048B\u048D\u048F\u0491\u0493\u0495\u0497\u0499\u049B\u049D\u049F\u04A1\u04A3\u04A5\u04A7\u04A9\u04AB\u04AD\u04AF\u04B1\u04B3\u04B5\u04B7\u04B9\u04BB\u04BD\u04BF\u04C2\u04C4\u04C6\u04C8\u04CA\u04CC\u04CE\u04CF\u04D1\u04D3\u04D5\u04D7\u04D9\u04DB\u04DD\u04DF\u04E1\u04E3\u04E5\u04E7\u04E9\u04EB\u04ED\u04EF\u04F1\u04F3\u04F5\u04F7\u04F9\u04FB\u04FD\u04FF\u0501\u0503\u0505\u0507\u0509\u050B\u050D\u050F\u0511\u0513\u0515\u0517\u0519\u051B\u051D\u051F\u0521\u0523\u0561\u0562\u0563\u0564\u0565\u0566\u0567\u0568\u0569\u056A\u056B\u056C\u056D\u056E\u056F\u0570\u0571\u0572\u0573\u0574\u0575\u0576\u0577\u0578\u0579\u057A\u057B\u057C\u057D\u057E\u057F\u0580\u0581\u0582\u0583\u0584\u0585\u0586\u0587\u1D00\u1D01\u1D02\u1D03\u1D04\u1D05\u1D06\u1D07\u1D08\u1D09\u1D0A\u1D0B\u1D0C\u1D0D\u1D0E\u1D0F\u1D10\u1D11\u1D12\u1D13\u1D14\u1D15\u1D16\u1D17\u1D18\u1D19\u1D1A\u1D1B\u1D1C\u1D1D\u1D1E\u1D1F\u1D20\u1D21\u1D22\u1D23\u1D24\u1D25\u1D26\u1D27\u1D28\u1D29\u1D2A\u1D2B\u1D62\u1D63\u1D64\u1D65\u1D66\u1D67\u1D68\u1D69\u1D6A\u1D6B\u1D6C\u1D6D\u1D6E\u1D6F\u1D70\u1D71\u1D72\u1D73\u1D74\u1D75\u1D76\u1D77\u1D79\u1D7A\u1D7B\u1D7C\u1D7D\u1D7E\u1D7F\u1D80\u1D81\u1D82\u1D83\u1D84\u1D85\u1D86\u1D87\u1D88\u1D89\u1D8A\u1D8B\u1D8C\u1D8D\u1D8E\u1D8F\u1D90\u1D91\u1D92\u1D93\u1D94\u1D95\u1D96\u1D97\u1D98\u1D99\u1D9A\u1E01\u1E03\u1E05\u1E07\u1E09\u1E0B\u1E0D\u1E0F\u1E11\u1E13\u1E15\u1E17\u1E19\u1E1B\u1E1D\u1E1F\u1E21\u1E23\u1E25\u1E27\u1E29\u1E2B\u1E2D\u1E2F\u1E31\u1E33\u1E35\u1E37\u1E39\u1E3B\u1E3D\u1E3F\u1E41\u1E43\u1E45\u1E47\u1E49\u1E4B\u1E4D\u1E4F\u1E51\u1E53\u1E55\u1E57\u1E59\u1E5B\u1E5D\u1E5F\u1E61\u1E63\u1E65\u1E67\u1E69\u1E6B\u1E6D\u1E6F\u1E71\u1E73\u1E75\u1E77\u1E79\u1E7B\u1E7D\u1E7F\u1E81\u1E83\u1E85\u1E87\u1E89\u1E8B\u1E8D\u1E8F\u1E91\u1E93\u1E95\u1E96\u1E97\u1E98\u1E99\u1E9A\u1E9B\u1E9C\u1E9D\u1E9F\u1EA1\u1EA3\u1EA5\u1EA7\u1EA9\u1EAB\u1EAD\u1EAF\u1EB1\u1EB3\u1EB5\u1EB7\u1EB9\u1EBB\u1EBD\u1EBF\u1EC1\u1EC3\u1EC5\u1EC7\u1EC9\u1ECB\u1ECD\u1ECF\u1ED1\u1ED3\u1ED5\u1ED7\u1ED9\u1EDB\u1EDD\u1EDF\u1EE1\u1EE3\u1EE5\u1EE7\u1EE9\u1EEB\u1EED\u1EEF\u1EF1\u1EF3\u1EF5\u1EF7\u1EF9\u1EFB\u1EFD\u1EFF\u1F00\u1F01\u1F02\u1F03\u1F04\u1F05\u1F06\u1F07\u1F10\u1F11\u1F12\u1F13\u1F14\u1F15\u1F20\u1F21\u1F22\u1F23\u1F24\u1F25\u1F26\u1F27\u1F30\u1F31\u1F32\u1F33\u1F34\u1F35\u1F36\u1F37\u1F40\u1F41\u1F42\u1F43\u1F44\u1F45\u1F50\u1F51\u1F52\u1F53\u1F54\u1F55\u1F56\u1F57\u1F60\u1F61\u1F62\u1F63\u1F64\u1F65\u1F66\u1F67\u1F70\u1F71\u1F72\u1F73\u1F74\u1F75\u1F76\u1F77\u1F78\u1F79\u1F7A\u1F7B\u1F7C\u1F7D\u1F80\u1F81\u1F82\u1F83\u1F84\u1F85\u1F86\u1F87\u1F90\u1F91\u1F92\u1F93\u1F94\u1F95\u1F96\u1F97\u1FA0\u1FA1\u1FA2\u1FA3\u1FA4\u1FA5\u1FA6\u1FA7\u1FB0\u1FB1\u1FB2\u1FB3\u1FB4\u1FB6\u1FB7\u1FBE\u1FC2\u1FC3\u1FC4\u1FC6\u1FC7\u1FD0\u1FD1\u1FD2\u1FD3\u1FD6\u1FD7\u1FE0\u1FE1\u1FE2\u1FE3\u1FE4\u1FE5\u1FE6\u1FE7\u1FF2\u1FF3\u1FF4\u1FF6\u1FF7\u2071\u207F\u210A\u210E\u210F\u2113\u212F\u2134\u2139\u213C\u213D\u2146\u2147\u2148\u2149\u214E\u2184\u2C30\u2C31\u2C32\u2C33\u2C34\u2C35\u2C36\u2C37\u2C38\u2C39\u2C3A\u2C3B\u2C3C\u2C3D\u2C3E\u2C3F\u2C40\u2C41\u2C42\u2C43\u2C44\u2C45\u2C46\u2C47\u2C48\u2C49\u2C4A\u2C4B\u2C4C\u2C4D\u2C4E\u2C4F\u2C50\u2C51\u2C52\u2C53\u2C54\u2C55\u2C56\u2C57\u2C58\u2C59\u2C5A\u2C5B\u2C5C\u2C5D\u2C5E\u2C61\u2C65\u2C66\u2C68\u2C6A\u2C6C\u2C71\u2C73\u2C74\u2C76\u2C77\u2C78\u2C79\u2C7A\u2C7B\u2C7C\u2C81\u2C83\u2C85\u2C87\u2C89\u2C8B\u2C8D\u2C8F\u2C91\u2C93\u2C95\u2C97\u2C99\u2C9B\u2C9D\u2C9F\u2CA1\u2CA3\u2CA5\u2CA7\u2CA9\u2CAB\u2CAD\u2CAF\u2CB1\u2CB3\u2CB5\u2CB7\u2CB9\u2CBB\u2CBD\u2CBF\u2CC1\u2CC3\u2CC5\u2CC7\u2CC9\u2CCB\u2CCD\u2CCF\u2CD1\u2CD3\u2CD5\u2CD7\u2CD9\u2CDB\u2CDD\u2CDF\u2CE1\u2CE3\u2CE4\u2D00\u2D01\u2D02\u2D03\u2D04\u2D05\u2D06\u2D07\u2D08\u2D09\u2D0A\u2D0B\u2D0C\u2D0D\u2D0E\u2D0F\u2D10\u2D11\u2D12\u2D13\u2D14\u2D15\u2D16\u2D17\u2D18\u2D19\u2D1A\u2D1B\u2D1C\u2D1D\u2D1E\u2D1F\u2D20\u2D21\u2D22\u2D23\u2D24\u2D25\uA641\uA643\uA645\uA647\uA649\uA64B\uA64D\uA64F\uA651\uA653\uA655\uA657\uA659\uA65B\uA65D\uA65F\uA663\uA665\uA667\uA669\uA66B\uA66D\uA681\uA683\uA685\uA687\uA689\uA68B\uA68D\uA68F\uA691\uA693\uA695\uA697\uA723\uA725\uA727\uA729\uA72B\uA72D\uA72F\uA730\uA731\uA733\uA735\uA737\uA739\uA73B\uA73D\uA73F\uA741\uA743\uA745\uA747\uA749\uA74B\uA74D\uA74F\uA751\uA753\uA755\uA757\uA759\uA75B\uA75D\uA75F\uA761\uA763\uA765\uA767\uA769\uA76B\uA76D\uA76F\uA771\uA772\uA773\uA774\uA775\uA776\uA777\uA778\uA77A\uA77C\uA77F\uA781\uA783\uA785\uA787\uA78C\uFB00\uFB01\uFB02\uFB03\uFB04\uFB05\uFB06\uFB13\uFB14\uFB15\uFB16\uFB17\uFF41\uFF42\uFF43\uFF44\uFF45\uFF46\uFF47\uFF48\uFF49\uFF4A\uFF4B\uFF4C\uFF4D\uFF4E\uFF4F\uFF50\uFF51\uFF52\uFF53\uFF54\uFF55\uFF56\uFF57\uFF58\uFF59\uFF5A]
425 Ll = [\u0061-\u007A\u00B5\u00DF-\u00F6\u00F8-\u00FF\u0101\u0103\u0105\u0107\u0109\u010B\u010D\u010F\u0111\u0113\u0115\u0117\u0119\u011B\u011D\u011F\u0121\u0123\u0125\u0127\u0129\u012B\u012D\u012F\u0131\u0133\u0135\u0137-\u0138\u013A\u013C\u013E\u0140\u0142\u0144\u0146\u0148-\u0149\u014B\u014D\u014F\u0151\u0153\u0155\u0157\u0159\u015B\u015D\u015F\u0161\u0163\u0165\u0167\u0169\u016B\u016D\u016F\u0171\u0173\u0175\u0177\u017A\u017C\u017E-\u0180\u0183\u0185\u0188\u018C-\u018D\u0192\u0195\u0199-\u019B\u019E\u01A1\u01A3\u01A5\u01A8\u01AA-\u01AB\u01AD\u01B0\u01B4\u01B6\u01B9-\u01BA\u01BD-\u01BF\u01C6\u01C9\u01CC\u01CE\u01D0\u01D2\u01D4\u01D6\u01D8\u01DA\u01DC-\u01DD\u01DF\u01E1\u01E3\u01E5\u01E7\u01E9\u01EB\u01ED\u01EF-\u01F0\u01F3\u01F5\u01F9\u01FB\u01FD\u01FF\u0201\u0203\u0205\u0207\u0209\u020B\u020D\u020F\u0211\u0213\u0215\u0217\u0219\u021B\u021D\u021F\u0221\u0223\u0225\u0227\u0229\u022B\u022D\u022F\u0231\u0233-\u0239\u023C\u023F-\u0240\u0242\u0247\u0249\u024B\u024D\u024F-\u0293\u0295-\u02AF\u0371\u0373\u0377\u037B-\u037D\u0390\u03AC-\u03CE\u03D0-\u03D1\u03D5-\u03D7\u03D9\u03DB\u03DD\u03DF\u03E1\u03E3\u03E5\u03E7\u03E9\u03EB\u03ED\u03EF-\u03F3\u03F5\u03F8\u03FB-\u03FC\u0430-\u045F\u0461\u0463\u0465\u0467\u0469\u046B\u046D\u046F\u0471\u0473\u0475\u0477\u0479\u047B\u047D\u047F\u0481\u048B\u048D\u048F\u0491\u0493\u0495\u0497\u0499\u049B\u049D\u049F\u04A1\u04A3\u04A5\u04A7\u04A9\u04AB\u04AD\u04AF\u04B1\u04B3\u04B5\u04B7\u04B9\u04BB\u04BD\u04BF\u04C2\u04C4\u04C6\u04C8\u04CA\u04CC\u04CE-\u04CF\u04D1\u04D3\u04D5\u04D7\u04D9\u04DB\u04DD\u04DF\u04E1\u04E3\u04E5\u04E7\u04E9\u04EB\u04ED\u04EF\u04F1\u04F3\u04F5\u04F7\u04F9\u04FB\u04FD\u04FF\u0501\u0503\u0505\u0507\u0509\u050B\u050D\u050F\u0511\u0513\u0515\u0517\u0519\u051B\u051D\u051F\u0521\u0523\u0525\u0527\u0529\u052B\u052D\u052F\u0561-\u0587\u13F8-\u13FD\u1D00-\u1D2B\u1D6B-\u1D77\u1D79-\u1D9A\u1E01\u1E03\u1E05\u1E07\u1E09\u1E0B\u1E0D\u1E0F\u1E11\u1E13\u1E15\u1E17\u1E19\u1E1B\u1E1D\u1E1F\u1E21\u1E23\u1E25\u1E27\u1E29\u1E2B\u1E2D\u1E2F\u1E31\u1E33\u1E35\u1E37\u1E39\u1E3B\u1E3D\u1E3F\u1E41\u1E43\u1E45\u1E47\u1E49\u1E4B\u1E4D\u1E4F\u1E51\u1E53\u1E55\u1E57\u1E59\u1E5B\u1E5D\u1E5F\u1E61\u1E63\u1E65\u1E67\u1E69\u1E6B\u1E6D\u1E6F\u1E71\u1E73\u1E75\u1E77\u1E79\u1E7B\u1E7D\u1E7F\u1E81\u1E83\u1E85\u1E87\u1E89\u1E8B\u1E8D\u1E8F\u1E91\u1E93\u1E95-\u1E9D\u1E9F\u1EA1\u1EA3\u1EA5\u1EA7\u1EA9\u1EAB\u1EAD\u1EAF\u1EB1\u1EB3\u1EB5\u1EB7\u1EB9\u1EBB\u1EBD\u1EBF\u1EC1\u1EC3\u1EC5\u1EC7\u1EC9\u1ECB\u1ECD\u1ECF\u1ED1\u1ED3\u1ED5\u1ED7\u1ED9\u1EDB\u1EDD\u1EDF\u1EE1\u1EE3\u1EE5\u1EE7\u1EE9\u1EEB\u1EED\u1EEF\u1EF1\u1EF3\u1EF5\u1EF7\u1EF9\u1EFB\u1EFD\u1EFF-\u1F07\u1F10-\u1F15\u1F20-\u1F27\u1F30-\u1F37\u1F40-\u1F45\u1F50-\u1F57\u1F60-\u1F67\u1F70-\u1F7D\u1F80-\u1F87\u1F90-\u1F97\u1FA0-\u1FA7\u1FB0-\u1FB4\u1FB6-\u1FB7\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FC7\u1FD0-\u1FD3\u1FD6-\u1FD7\u1FE0-\u1FE7\u1FF2-\u1FF4\u1FF6-\u1FF7\u210A\u210E-\u210F\u2113\u212F\u2134\u2139\u213C-\u213D\u2146-\u2149\u214E\u2184\u2C30-\u2C5E\u2C61\u2C65-\u2C66\u2C68\u2C6A\u2C6C\u2C71\u2C73-\u2C74\u2C76-\u2C7B\u2C81\u2C83\u2C85\u2C87\u2C89\u2C8B\u2C8D\u2C8F\u2C91\u2C93\u2C95\u2C97\u2C99\u2C9B\u2C9D\u2C9F\u2CA1\u2CA3\u2CA5\u2CA7\u2CA9\u2CAB\u2CAD\u2CAF\u2CB1\u2CB3\u2CB5\u2CB7\u2CB9\u2CBB\u2CBD\u2CBF\u2CC1\u2CC3\u2CC5\u2CC7\u2CC9\u2CCB\u2CCD\u2CCF\u2CD1\u2CD3\u2CD5\u2CD7\u2CD9\u2CDB\u2CDD\u2CDF\u2CE1\u2CE3-\u2CE4\u2CEC\u2CEE\u2CF3\u2D00-\u2D25\u2D27\u2D2D\uA641\uA643\uA645\uA647\uA649\uA64B\uA64D\uA64F\uA651\uA653\uA655\uA657\uA659\uA65B\uA65D\uA65F\uA661\uA663\uA665\uA667\uA669\uA66B\uA66D\uA681\uA683\uA685\uA687\uA689\uA68B\uA68D\uA68F\uA691\uA693\uA695\uA697\uA699\uA69B\uA723\uA725\uA727\uA729\uA72B\uA72D\uA72F-\uA731\uA733\uA735\uA737\uA739\uA73B\uA73D\uA73F\uA741\uA743\uA745\uA747\uA749\uA74B\uA74D\uA74F\uA751\uA753\uA755\uA757\uA759\uA75B\uA75D\uA75F\uA761\uA763\uA765\uA767\uA769\uA76B\uA76D\uA76F\uA771-\uA778\uA77A\uA77C\uA77F\uA781\uA783\uA785\uA787\uA78C\uA78E\uA791\uA793-\uA795\uA797\uA799\uA79B\uA79D\uA79F\uA7A1\uA7A3\uA7A5\uA7A7\uA7A9\uA7B5\uA7B7\uA7FA\uAB30-\uAB5A\uAB60-\uAB65\uAB70-\uABBF\uFB00-\uFB06\uFB13-\uFB17\uFF41-\uFF5A]
412426
413427 // Letter, Modifier
414 Lm = [\u02B0\u02B1\u02B2\u02B3\u02B4\u02B5\u02B6\u02B7\u02B8\u02B9\u02BA\u02BB\u02BC\u02BD\u02BE\u02BF\u02C0\u02C1\u02C6\u02C7\u02C8\u02C9\u02CA\u02CB\u02CC\u02CD\u02CE\u02CF\u02D0\u02D1\u02E0\u02E1\u02E2\u02E3\u02E4\u02EC\u02EE\u0374\u037A\u0559\u0640\u06E5\u06E6\u07F4\u07F5\u07FA\u0971\u0E46\u0EC6\u10FC\u17D7\u1843\u1C78\u1C79\u1C7A\u1C7B\u1C7C\u1C7D\u1D2C\u1D2D\u1D2E\u1D2F\u1D30\u1D31\u1D32\u1D33\u1D34\u1D35\u1D36\u1D37\u1D38\u1D39\u1D3A\u1D3B\u1D3C\u1D3D\u1D3E\u1D3F\u1D40\u1D41\u1D42\u1D43\u1D44\u1D45\u1D46\u1D47\u1D48\u1D49\u1D4A\u1D4B\u1D4C\u1D4D\u1D4E\u1D4F\u1D50\u1D51\u1D52\u1D53\u1D54\u1D55\u1D56\u1D57\u1D58\u1D59\u1D5A\u1D5B\u1D5C\u1D5D\u1D5E\u1D5F\u1D60\u1D61\u1D78\u1D9B\u1D9C\u1D9D\u1D9E\u1D9F\u1DA0\u1DA1\u1DA2\u1DA3\u1DA4\u1DA5\u1DA6\u1DA7\u1DA8\u1DA9\u1DAA\u1DAB\u1DAC\u1DAD\u1DAE\u1DAF\u1DB0\u1DB1\u1DB2\u1DB3\u1DB4\u1DB5\u1DB6\u1DB7\u1DB8\u1DB9\u1DBA\u1DBB\u1DBC\u1DBD\u1DBE\u1DBF\u2090\u2091\u2092\u2093\u2094\u2C7D\u2D6F\u2E2F\u3005\u3031\u3032\u3033\u3034\u3035\u303B\u309D\u309E\u30FC\u30FD\u30FE\uA015\uA60C\uA67F\uA717\uA718\uA719\uA71A\uA71B\uA71C\uA71D\uA71E\uA71F\uA770\uA788\uFF70\uFF9E\uFF9F]
428 Lm = [\u02B0-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0374\u037A\u0559\u0640\u06E5-\u06E6\u07F4-\u07F5\u07FA\u081A\u0824\u0828\u0971\u0E46\u0EC6\u10FC\u17D7\u1843\u1AA7\u1C78-\u1C7D\u1D2C-\u1D6A\u1D78\u1D9B-\u1DBF\u2071\u207F\u2090-\u209C\u2C7C-\u2C7D\u2D6F\u2E2F\u3005\u3031-\u3035\u303B\u309D-\u309E\u30FC-\u30FE\uA015\uA4F8-\uA4FD\uA60C\uA67F\uA69C-\uA69D\uA717-\uA71F\uA770\uA788\uA7F8-\uA7F9\uA9CF\uA9E6\uAA70\uAADD\uAAF3-\uAAF4\uAB5C-\uAB5F\uFF70\uFF9E-\uFF9F]
415429
416430 // Letter, Other
417 Lo = [\u01BB\u01C0\u01C1\u01C2\u01C3\u0294\u05D0\u05D1\u05D2\u05D3\u05D4\u05D5\u05D6\u05D7\u05D8\u05D9\u05DA\u05DB\u05DC\u05DD\u05DE\u05DF\u05E0\u05E1\u05E2\u05E3\u05E4\u05E5\u05E6\u05E7\u05E8\u05E9\u05EA\u05F0\u05F1\u05F2\u0621\u0622\u0623\u0624\u0625\u0626\u0627\u0628\u0629\u062A\u062B\u062C\u062D\u062E\u062F\u0630\u0631\u0632\u0633\u0634\u0635\u0636\u0637\u0638\u0639\u063A\u063B\u063C\u063D\u063E\u063F\u0641\u0642\u0643\u0644\u0645\u0646\u0647\u0648\u0649\u064A\u066E\u066F\u0671\u0672\u0673\u0674\u0675\u0676\u0677\u0678\u0679\u067A\u067B\u067C\u067D\u067E\u067F\u0680\u0681\u0682\u0683\u0684\u0685\u0686\u0687\u0688\u0689\u068A\u068B\u068C\u068D\u068E\u068F\u0690\u0691\u0692\u0693\u0694\u0695\u0696\u0697\u0698\u0699\u069A\u069B\u069C\u069D\u069E\u069F\u06A0\u06A1\u06A2\u06A3\u06A4\u06A5\u06A6\u06A7\u06A8\u06A9\u06AA\u06AB\u06AC\u06AD\u06AE\u06AF\u06B0\u06B1\u06B2\u06B3\u06B4\u06B5\u06B6\u06B7\u06B8\u06B9\u06BA\u06BB\u06BC\u06BD\u06BE\u06BF\u06C0\u06C1\u06C2\u06C3\u06C4\u06C5\u06C6\u06C7\u06C8\u06C9\u06CA\u06CB\u06CC\u06CD\u06CE\u06CF\u06D0\u06D1\u06D2\u06D3\u06D5\u06EE\u06EF\u06FA\u06FB\u06FC\u06FF\u0710\u0712\u0713\u0714\u0715\u0716\u0717\u0718\u0719\u071A\u071B\u071C\u071D\u071E\u071F\u0720\u0721\u0722\u0723\u0724\u0725\u0726\u0727\u0728\u0729\u072A\u072B\u072C\u072D\u072E\u072F\u074D\u074E\u074F\u0750\u0751\u0752\u0753\u0754\u0755\u0756\u0757\u0758\u0759\u075A\u075B\u075C\u075D\u075E\u075F\u0760\u0761\u0762\u0763\u0764\u0765\u0766\u0767\u0768\u0769\u076A\u076B\u076C\u076D\u076E\u076F\u0770\u0771\u0772\u0773\u0774\u0775\u0776\u0777\u0778\u0779\u077A\u077B\u077C\u077D\u077E\u077F\u0780\u0781\u0782\u0783\u0784\u0785\u0786\u0787\u0788\u0789\u078A\u078B\u078C\u078D\u078E\u078F\u0790\u0791\u0792\u0793\u0794\u0795\u0796\u0797\u0798\u0799\u079A\u079B\u079C\u079D\u079E\u079F\u07A0\u07A1\u07A2\u07A3\u07A4\u07A5\u07B1\u07CA\u07CB\u07CC\u07CD\u07CE\u07CF\u07D0\u07D1\u07D2\u07D3\u07D4\u07D5\u07D6\u07D7\u07D8\u07D9\u07DA\u07DB\u07DC\u07DD\u07DE\u07DF\u07E0\u07E1\u07E2\u07E3\u07E4\u07E5\u07E6\u07E7\u07E8\u07E9\u07EA\u0904\u0905\u0906\u0907\u0908\u0909\u090A\u090B\u090C\u090D\u090E\u090F\u0910\u0911\u0912\u0913\u0914\u0915\u0916\u0917\u0918\u0919\u091A\u091B\u091C\u091D\u091E\u091F\u0920\u0921\u0922\u0923\u0924\u0925\u0926\u0927\u0928\u0929\u092A\u092B\u092C\u092D\u092E\u092F\u0930\u0931\u0932\u0933\u0934\u0935\u0936\u0937\u0938\u0939\u093D\u0950\u0958\u0959\u095A\u095B\u095C\u095D\u095E\u095F\u0960\u0961\u0972\u097B\u097C\u097D\u097E\u097F\u0985\u0986\u0987\u0988\u0989\u098A\u098B\u098C\u098F\u0990\u0993\u0994\u0995\u0996\u0997\u0998\u0999\u099A\u099B\u099C\u099D\u099E\u099F\u09A0\u09A1\u09A2\u09A3\u09A4\u09A5\u09A6\u09A7\u09A8\u09AA\u09AB\u09AC\u09AD\u09AE\u09AF\u09B0\u09B2\u09B6\u09B7\u09B8\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF\u09E0\u09E1\u09F0\u09F1\u0A05\u0A06\u0A07\u0A08\u0A09\u0A0A\u0A0F\u0A10\u0A13\u0A14\u0A15\u0A16\u0A17\u0A18\u0A19\u0A1A\u0A1B\u0A1C\u0A1D\u0A1E\u0A1F\u0A20\u0A21\u0A22\u0A23\u0A24\u0A25\u0A26\u0A27\u0A28\u0A2A\u0A2B\u0A2C\u0A2D\u0A2E\u0A2F\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59\u0A5A\u0A5B\u0A5C\u0A5E\u0A72\u0A73\u0A74\u0A85\u0A86\u0A87\u0A88\u0A89\u0A8A\u0A8B\u0A8C\u0A8D\u0A8F\u0A90\u0A91\u0A93\u0A94\u0A95\u0A96\u0A97\u0A98\u0A99\u0A9A\u0A9B\u0A9C\u0A9D\u0A9E\u0A9F\u0AA0\u0AA1\u0AA2\u0AA3\u0AA4\u0AA5\u0AA6\u0AA7\u0AA8\u0AAA\u0AAB\u0AAC\u0AAD\u0AAE\u0AAF\u0AB0\u0AB2\u0AB3\u0AB5\u0AB6\u0AB7\u0AB8\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05\u0B06\u0B07\u0B08\u0B09\u0B0A\u0B0B\u0B0C\u0B0F\u0B10\u0B13\u0B14\u0B15\u0B16\u0B17\u0B18\u0B19\u0B1A\u0B1B\u0B1C\u0B1D\u0B1E\u0B1F\u0B20\u0B21\u0B22\u0B23\u0B24\u0B25\u0B26\u0B27\u0B28\u0B2A\u0B2B\u0B2C\u0B2D\u0B2E\u0B2F\u0B30\u0B32\u0B33\u0B35\u0B36\u0B37\u0B38\u0B39\u0B3D\u0B5C\u0B5D\u0B5F\u0B60\u0B61\u0B71\u0B83\u0B85\u0B86\u0B87\u0B88\u0B89\u0B8A\u0B8E\u0B8F\u0B90\u0B92\u0B93\u0B94\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8\u0BA9\u0BAA\u0BAE\u0BAF\u0BB0\u0BB1\u0BB2\u0BB3\u0BB4\u0BB5\u0BB6\u0BB7\u0BB8\u0BB9\u0BD0\u0C05\u0C06\u0C07\u0C08\u0C09\u0C0A\u0C0B\u0C0C\u0C0E\u0C0F\u0C10\u0C12\u0C13\u0C14\u0C15\u0C16\u0C17\u0C18\u0C19\u0C1A\u0C1B\u0C1C\u0C1D\u0C1E\u0C1F\u0C20\u0C21\u0C22\u0C23\u0C24\u0C25\u0C26\u0C27\u0C28\u0C2A\u0C2B\u0C2C\u0C2D\u0C2E\u0C2F\u0C30\u0C31\u0C32\u0C33\u0C35\u0C36\u0C37\u0C38\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85\u0C86\u0C87\u0C88\u0C89\u0C8A\u0C8B\u0C8C\u0C8E\u0C8F\u0C90\u0C92\u0C93\u0C94\u0C95\u0C96\u0C97\u0C98\u0C99\u0C9A\u0C9B\u0C9C\u0C9D\u0C9E\u0C9F\u0CA0\u0CA1\u0CA2\u0CA3\u0CA4\u0CA5\u0CA6\u0CA7\u0CA8\u0CAA\u0CAB\u0CAC\u0CAD\u0CAE\u0CAF\u0CB0\u0CB1\u0CB2\u0CB3\u0CB5\u0CB6\u0CB7\u0CB8\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0D05\u0D06\u0D07\u0D08\u0D09\u0D0A\u0D0B\u0D0C\u0D0E\u0D0F\u0D10\u0D12\u0D13\u0D14\u0D15\u0D16\u0D17\u0D18\u0D19\u0D1A\u0D1B\u0D1C\u0D1D\u0D1E\u0D1F\u0D20\u0D21\u0D22\u0D23\u0D24\u0D25\u0D26\u0D27\u0D28\u0D2A\u0D2B\u0D2C\u0D2D\u0D2E\u0D2F\u0D30\u0D31\u0D32\u0D33\u0D34\u0D35\u0D36\u0D37\u0D38\u0D39\u0D3D\u0D60\u0D61\u0D7A\u0D7B\u0D7C\u0D7D\u0D7E\u0D7F\u0D85\u0D86\u0D87\u0D88\u0D89\u0D8A\u0D8B\u0D8C\u0D8D\u0D8E\u0D8F\u0D90\u0D91\u0D92\u0D93\u0D94\u0D95\u0D96\u0D9A\u0D9B\u0D9C\u0D9D\u0D9E\u0D9F\u0DA0\u0DA1\u0DA2\u0DA3\u0DA4\u0DA5\u0DA6\u0DA7\u0DA8\u0DA9\u0DAA\u0DAB\u0DAC\u0DAD\u0DAE\u0DAF\u0DB0\u0DB1\u0DB3\u0DB4\u0DB5\u0DB6\u0DB7\u0DB8\u0DB9\u0DBA\u0DBB\u0DBD\u0DC0\u0DC1\u0DC2\u0DC3\u0DC4\u0DC5\u0DC6\u0E01\u0E02\u0E03\u0E04\u0E05\u0E06\u0E07\u0E08\u0E09\u0E0A\u0E0B\u0E0C\u0E0D\u0E0E\u0E0F\u0E10\u0E11\u0E12\u0E13\u0E14\u0E15\u0E16\u0E17\u0E18\u0E19\u0E1A\u0E1B\u0E1C\u0E1D\u0E1E\u0E1F\u0E20\u0E21\u0E22\u0E23\u0E24\u0E25\u0E26\u0E27\u0E28\u0E29\u0E2A\u0E2B\u0E2C\u0E2D\u0E2E\u0E2F\u0E30\u0E32\u0E33\u0E40\u0E41\u0E42\u0E43\u0E44\u0E45\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94\u0E95\u0E96\u0E97\u0E99\u0E9A\u0E9B\u0E9C\u0E9D\u0E9E\u0E9F\u0EA1\u0EA2\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD\u0EAE\u0EAF\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0\u0EC1\u0EC2\u0EC3\u0EC4\u0EDC\u0EDD\u0F00\u0F40\u0F41\u0F42\u0F43\u0F44\u0F45\u0F46\u0F47\u0F49\u0F4A\u0F4B\u0F4C\u0F4D\u0F4E\u0F4F\u0F50\u0F51\u0F52\u0F53\u0F54\u0F55\u0F56\u0F57\u0F58\u0F59\u0F5A\u0F5B\u0F5C\u0F5D\u0F5E\u0F5F\u0F60\u0F61\u0F62\u0F63\u0F64\u0F65\u0F66\u0F67\u0F68\u0F69\u0F6A\u0F6B\u0F6C\u0F88\u0F89\u0F8A\u0F8B\u1000\u1001\u1002\u1003\u1004\u1005\u1006\u1007\u1008\u1009\u100A\u100B\u100C\u100D\u100E\u100F\u1010\u1011\u1012\u1013\u1014\u1015\u1016\u1017\u1018\u1019\u101A\u101B\u101C\u101D\u101E\u101F\u1020\u1021\u1022\u1023\u1024\u1025\u1026\u1027\u1028\u1029\u102A\u103F\u1050\u1051\u1052\u1053\u1054\u1055\u105A\u105B\u105C\u105D\u1061\u1065\u1066\u106E\u106F\u1070\u1075\u1076\u1077\u1078\u1079\u107A\u107B\u107C\u107D\u107E\u107F\u1080\u1081\u108E\u10D0\u10D1\u10D2\u10D3\u10D4\u10D5\u10D6\u10D7\u10D8\u10D9\u10DA\u10DB\u10DC\u10DD\u10DE\u10DF\u10E0\u10E1\u10E2\u10E3\u10E4\u10E5\u10E6\u10E7\u10E8\u10E9\u10EA\u10EB\u10EC\u10ED\u10EE\u10EF\u10F0\u10F1\u10F2\u10F3\u10F4\u10F5\u10F6\u10F7\u10F8\u10F9\u10FA\u1100\u1101\u1102\u1103\u1104\u1105\u1106\u1107\u1108\u1109\u110A\u110B\u110C\u110D\u110E\u110F\u1110\u1111\u1112\u1113\u1114\u1115\u1116\u1117\u1118\u1119\u111A\u111B\u111C\u111D\u111E\u111F\u1120\u1121\u1122\u1123\u1124\u1125\u1126\u1127\u1128\u1129\u112A\u112B\u112C\u112D\u112E\u112F\u1130\u1131\u1132\u1133\u1134\u1135\u1136\u1137\u1138\u1139\u113A\u113B\u113C\u113D\u113E\u113F\u1140\u1141\u1142\u1143\u1144\u1145\u1146\u1147\u1148\u1149\u114A\u114B\u114C\u114D\u114E\u114F\u1150\u1151\u1152\u1153\u1154\u1155\u1156\u1157\u1158\u1159\u115F\u1160\u1161\u1162\u1163\u1164\u1165\u1166\u1167\u1168\u1169\u116A\u116B\u116C\u116D\u116E\u116F\u1170\u1171\u1172\u1173\u1174\u1175\u1176\u1177\u1178\u1179\u117A\u117B\u117C\u117D\u117E\u117F\u1180\u1181\u1182\u1183\u1184\u1185\u1186\u1187\u1188\u1189\u118A\u118B\u118C\u118D\u118E\u118F\u1190\u1191\u1192\u1193\u1194\u1195\u1196\u1197\u1198\u1199\u119A\u119B\u119C\u119D\u119E\u119F\u11A0\u11A1\u11A2\u11A8\u11A9\u11AA\u11AB\u11AC\u11AD\u11AE\u11AF\u11B0\u11B1\u11B2\u11B3\u11B4\u11B5\u11B6\u11B7\u11B8\u11B9\u11BA\u11BB\u11BC\u11BD\u11BE\u11BF\u11C0\u11C1\u11C2\u11C3\u11C4\u11C5\u11C6\u11C7\u11C8\u11C9\u11CA\u11CB\u11CC\u11CD\u11CE\u11CF\u11D0\u11D1\u11D2\u11D3\u11D4\u11D5\u11D6\u11D7\u11D8\u11D9\u11DA\u11DB\u11DC\u11DD\u11DE\u11DF\u11E0\u11E1\u11E2\u11E3\u11E4\u11E5\u11E6\u11E7\u11E8\u11E9\u11EA\u11EB\u11EC\u11ED\u11EE\u11EF\u11F0\u11F1\u11F2\u11F3\u11F4\u11F5\u11F6\u11F7\u11F8\u11F9\u1200\u1201\u1202\u1203\u1204\u1205\u1206\u1207\u1208\u1209\u120A\u120B\u120C\u120D\u120E\u120F\u1210\u1211\u1212\u1213\u1214\u1215\u1216\u1217\u1218\u1219\u121A\u121B\u121C\u121D\u121E\u121F\u1220\u1221\u1222\u1223\u1224\u1225\u1226\u1227\u1228\u1229\u122A\u122B\u122C\u122D\u122E\u122F\u1230\u1231\u1232\u1233\u1234\u1235\u1236\u1237\u1238\u1239\u123A\u123B\u123C\u123D\u123E\u123F\u1240\u1241\u1242\u1243\u1244\u1245\u1246\u1247\u1248\u124A\u124B\u124C\u124D\u1250\u1251\u1252\u1253\u1254\u1255\u1256\u1258\u125A\u125B\u125C\u125D\u1260\u1261\u1262\u1263\u1264\u1265\u1266\u1267\u1268\u1269\u126A\u126B\u126C\u126D\u126E\u126F\u1270\u1271\u1272\u1273\u1274\u1275\u1276\u1277\u1278\u1279\u127A\u127B\u127C\u127D\u127E\u127F\u1280\u1281\u1282\u1283\u1284\u1285\u1286\u1287\u1288\u128A\u128B\u128C\u128D\u1290\u1291\u1292\u1293\u1294\u1295\u1296\u1297\u1298\u1299\u129A\u129B\u129C\u129D\u129E\u129F\u12A0\u12A1\u12A2\u12A3\u12A4\u12A5\u12A6\u12A7\u12A8\u12A9\u12AA\u12AB\u12AC\u12AD\u12AE\u12AF\u12B0\u12B2\u12B3\u12B4\u12B5\u12B8\u12B9\u12BA\u12BB\u12BC\u12BD\u12BE\u12C0\u12C2\u12C3\u12C4\u12C5\u12C8\u12C9\u12CA\u12CB\u12CC\u12CD\u12CE\u12CF\u12D0\u12D1\u12D2\u12D3\u12D4\u12D5\u12D6\u12D8\u12D9\u12DA\u12DB\u12DC\u12DD\u12DE\u12DF\u12E0\u12E1\u12E2\u12E3\u12E4\u12E5\u12E6\u12E7\u12E8\u12E9\u12EA\u12EB\u12EC\u12ED\u12EE\u12EF\u12F0\u12F1\u12F2\u12F3\u12F4\u12F5\u12F6\u12F7\u12F8\u12F9\u12FA\u12FB\u12FC\u12FD\u12FE\u12FF\u1300\u1301\u1302\u1303\u1304\u1305\u1306\u1307\u1308\u1309\u130A\u130B\u130C\u130D\u130E\u130F\u1310\u1312\u1313\u1314\u1315\u1318\u1319\u131A\u131B\u131C\u131D\u131E\u131F\u1320\u1321\u1322\u1323\u1324\u1325\u1326\u1327\u1328\u1329\u132A\u132B\u132C\u132D\u132E\u132F\u1330\u1331\u1332\u1333\u1334\u1335\u1336\u1337\u1338\u1339\u133A\u133B\u133C\u133D\u133E\u133F\u1340\u1341\u1342\u1343\u1344\u1345\u1346\u1347\u1348\u1349\u134A\u134B\u134C\u134D\u134E\u134F\u1350\u1351\u1352\u1353\u1354\u1355\u1356\u1357\u1358\u1359\u135A\u1380\u1381\u1382\u1383\u1384\u1385\u1386\u1387\u1388\u1389\u138A\u138B\u138C\u138D\u138E\u138F\u13A0\u13A1\u13A2\u13A3\u13A4\u13A5\u13A6\u13A7\u13A8\u13A9\u13AA\u13AB\u13AC\u13AD\u13AE\u13AF\u13B0\u13B1\u13B2\u13B3\u13B4\u13B5\u13B6\u13B7\u13B8\u13B9\u13BA\u13BB\u13BC\u13BD\u13BE\u13BF\u13C0\u13C1\u13C2\u13C3\u13C4\u13C5\u13C6\u13C7\u13C8\u13C9\u13CA\u13CB\u13CC\u13CD\u13CE\u13CF\u13D0\u13D1\u13D2\u13D3\u13D4\u13D5\u13D6\u13D7\u13D8\u13D9\u13DA\u13DB\u13DC\u13DD\u13DE\u13DF\u13E0\u13E1\u13E2\u13E3\u13E4\u13E5\u13E6\u13E7\u13E8\u13E9\u13EA\u13EB\u13EC\u13ED\u13EE\u13EF\u13F0\u13F1\u13F2\u13F3\u13F4\u1401\u1402\u1403\u1404\u1405\u1406\u1407\u1408\u1409\u140A\u140B\u140C\u140D\u140E\u140F\u1410\u1411\u1412\u1413\u1414\u1415\u1416\u1417\u1418\u1419\u141A\u141B\u141C\u141D\u141E\u141F\u1420\u1421\u1422\u1423\u1424\u1425\u1426\u1427\u1428\u1429\u142A\u142B\u142C\u142D\u142E\u142F\u1430\u1431\u1432\u1433\u1434\u1435\u1436\u1437\u1438\u1439\u143A\u143B\u143C\u143D\u143E\u143F\u1440\u1441\u1442\u1443\u1444\u1445\u1446\u1447\u1448\u1449\u144A\u144B\u144C\u144D\u144E\u144F\u1450\u1451\u1452\u1453\u1454\u1455\u1456\u1457\u1458\u1459\u145A\u145B\u145C\u145D\u145E\u145F\u1460\u1461\u1462\u1463\u1464\u1465\u1466\u1467\u1468\u1469\u146A\u146B\u146C\u146D\u146E\u146F\u1470\u1471\u1472\u1473\u1474\u1475\u1476\u1477\u1478\u1479\u147A\u147B\u147C\u147D\u147E\u147F\u1480\u1481\u1482\u1483\u1484\u1485\u1486\u1487\u1488\u1489\u148A\u148B\u148C\u148D\u148E\u148F\u1490\u1491\u1492\u1493\u1494\u1495\u1496\u1497\u1498\u1499\u149A\u149B\u149C\u149D\u149E\u149F\u14A0\u14A1\u14A2\u14A3\u14A4\u14A5\u14A6\u14A7\u14A8\u14A9\u14AA\u14AB\u14AC\u14AD\u14AE\u14AF\u14B0\u14B1\u14B2\u14B3\u14B4\u14B5\u14B6\u14B7\u14B8\u14B9\u14BA\u14BB\u14BC\u14BD\u14BE\u14BF\u14C0\u14C1\u14C2\u14C3\u14C4\u14C5\u14C6\u14C7\u14C8\u14C9\u14CA\u14CB\u14CC\u14CD\u14CE\u14CF\u14D0\u14D1\u14D2\u14D3\u14D4\u14D5\u14D6\u14D7\u14D8\u14D9\u14DA\u14DB\u14DC\u14DD\u14DE\u14DF\u14E0\u14E1\u14E2\u14E3\u14E4\u14E5\u14E6\u14E7\u14E8\u14E9\u14EA\u14EB\u14EC\u14ED\u14EE\u14EF\u14F0\u14F1\u14F2\u14F3\u14F4\u14F5\u14F6\u14F7\u14F8\u14F9\u14FA\u14FB\u14FC\u14FD\u14FE\u14FF\u1500\u1501\u1502\u1503\u1504\u1505\u1506\u1507\u1508\u1509\u150A\u150B\u150C\u150D\u150E\u150F\u1510\u1511\u1512\u1513\u1514\u1515\u1516\u1517\u1518\u1519\u151A\u151B\u151C\u151D\u151E\u151F\u1520\u1521\u1522\u1523\u1524\u1525\u1526\u1527\u1528\u1529\u152A\u152B\u152C\u152D\u152E\u152F\u1530\u1531\u1532\u1533\u1534\u1535\u1536\u1537\u1538\u1539\u153A\u153B\u153C\u153D\u153E\u153F\u1540\u1541\u1542\u1543\u1544\u1545\u1546\u1547\u1548\u1549\u154A\u154B\u154C\u154D\u154E\u154F\u1550\u1551\u1552\u1553\u1554\u1555\u1556\u1557\u1558\u1559\u155A\u155B\u155C\u155D\u155E\u155F\u1560\u1561\u1562\u1563\u1564\u1565\u1566\u1567\u1568\u1569\u156A\u156B\u156C\u156D\u156E\u156F\u1570\u1571\u1572\u1573\u1574\u1575\u1576\u1577\u1578\u1579\u157A\u157B\u157C\u157D\u157E\u157F\u1580\u1581\u1582\u1583\u1584\u1585\u1586\u1587\u1588\u1589\u158A\u158B\u158C\u158D\u158E\u158F\u1590\u1591\u1592\u1593\u1594\u1595\u1596\u1597\u1598\u1599\u159A\u159B\u159C\u159D\u159E\u159F\u15A0\u15A1\u15A2\u15A3\u15A4\u15A5\u15A6\u15A7\u15A8\u15A9\u15AA\u15AB\u15AC\u15AD\u15AE\u15AF\u15B0\u15B1\u15B2\u15B3\u15B4\u15B5\u15B6\u15B7\u15B8\u15B9\u15BA\u15BB\u15BC\u15BD\u15BE\u15BF\u15C0\u15C1\u15C2\u15C3\u15C4\u15C5\u15C6\u15C7\u15C8\u15C9\u15CA\u15CB\u15CC\u15CD\u15CE\u15CF\u15D0\u15D1\u15D2\u15D3\u15D4\u15D5\u15D6\u15D7\u15D8\u15D9\u15DA\u15DB\u15DC\u15DD\u15DE\u15DF\u15E0\u15E1\u15E2\u15E3\u15E4\u15E5\u15E6\u15E7\u15E8\u15E9\u15EA\u15EB\u15EC\u15ED\u15EE\u15EF\u15F0\u15F1\u15F2\u15F3\u15F4\u15F5\u15F6\u15F7\u15F8\u15F9\u15FA\u15FB\u15FC\u15FD\u15FE\u15FF\u1600\u1601\u1602\u1603\u1604\u1605\u1606\u1607\u1608\u1609\u160A\u160B\u160C\u160D\u160E\u160F\u1610\u1611\u1612\u1613\u1614\u1615\u1616\u1617\u1618\u1619\u161A\u161B\u161C\u161D\u161E\u161F\u1620\u1621\u1622\u1623\u1624\u1625\u1626\u1627\u1628\u1629\u162A\u162B\u162C\u162D\u162E\u162F\u1630\u1631\u1632\u1633\u1634\u1635\u1636\u1637\u1638\u1639\u163A\u163B\u163C\u163D\u163E\u163F\u1640\u1641\u1642\u1643\u1644\u1645\u1646\u1647\u1648\u1649\u164A\u164B\u164C\u164D\u164E\u164F\u1650\u1651\u1652\u1653\u1654\u1655\u1656\u1657\u1658\u1659\u165A\u165B\u165C\u165D\u165E\u165F\u1660\u1661\u1662\u1663\u1664\u1665\u1666\u1667\u1668\u1669\u166A\u166B\u166C\u166F\u1670\u1671\u1672\u1673\u1674\u1675\u1676\u1681\u1682\u1683\u1684\u1685\u1686\u1687\u1688\u1689\u168A\u168B\u168C\u168D\u168E\u168F\u1690\u1691\u1692\u1693\u1694\u1695\u1696\u1697\u1698\u1699\u169A\u16A0\u16A1\u16A2\u16A3\u16A4\u16A5\u16A6\u16A7\u16A8\u16A9\u16AA\u16AB\u16AC\u16AD\u16AE\u16AF\u16B0\u16B1\u16B2\u16B3\u16B4\u16B5\u16B6\u16B7\u16B8\u16B9\u16BA\u16BB\u16BC\u16BD\u16BE\u16BF\u16C0\u16C1\u16C2\u16C3\u16C4\u16C5\u16C6\u16C7\u16C8\u16C9\u16CA\u16CB\u16CC\u16CD\u16CE\u16CF\u16D0\u16D1\u16D2\u16D3\u16D4\u16D5\u16D6\u16D7\u16D8\u16D9\u16DA\u16DB\u16DC\u16DD\u16DE\u16DF\u16E0\u16E1\u16E2\u16E3\u16E4\u16E5\u16E6\u16E7\u16E8\u16E9\u16EA\u1700\u1701\u1702\u1703\u1704\u1705\u1706\u1707\u1708\u1709\u170A\u170B\u170C\u170E\u170F\u1710\u1711\u1720\u1721\u1722\u1723\u1724\u1725\u1726\u1727\u1728\u1729\u172A\u172B\u172C\u172D\u172E\u172F\u1730\u1731\u1740\u1741\u1742\u1743\u1744\u1745\u1746\u1747\u1748\u1749\u174A\u174B\u174C\u174D\u174E\u174F\u1750\u1751\u1760\u1761\u1762\u1763\u1764\u1765\u1766\u1767\u1768\u1769\u176A\u176B\u176C\u176E\u176F\u1770\u1780\u1781\u1782\u1783\u1784\u1785\u1786\u1787\u1788\u1789\u178A\u178B\u178C\u178D\u178E\u178F\u1790\u1791\u1792\u1793\u1794\u1795\u1796\u1797\u1798\u1799\u179A\u179B\u179C\u179D\u179E\u179F\u17A0\u17A1\u17A2\u17A3\u17A4\u17A5\u17A6\u17A7\u17A8\u17A9\u17AA\u17AB\u17AC\u17AD\u17AE\u17AF\u17B0\u17B1\u17B2\u17B3\u17DC\u1820\u1821\u1822\u1823\u1824\u1825\u1826\u1827\u1828\u1829\u182A\u182B\u182C\u182D\u182E\u182F\u1830\u1831\u1832\u1833\u1834\u1835\u1836\u1837\u1838\u1839\u183A\u183B\u183C\u183D\u183E\u183F\u1840\u1841\u1842\u1844\u1845\u1846\u1847\u1848\u1849\u184A\u184B\u184C\u184D\u184E\u184F\u1850\u1851\u1852\u1853\u1854\u1855\u1856\u1857\u1858\u1859\u185A\u185B\u185C\u185D\u185E\u185F\u1860\u1861\u1862\u1863\u1864\u1865\u1866\u1867\u1868\u1869\u186A\u186B\u186C\u186D\u186E\u186F\u1870\u1871\u1872\u1873\u1874\u1875\u1876\u1877\u1880\u1881\u1882\u1883\u1884\u1885\u1886\u1887\u1888\u1889\u188A\u188B\u188C\u188D\u188E\u188F\u1890\u1891\u1892\u1893\u1894\u1895\u1896\u1897\u1898\u1899\u189A\u189B\u189C\u189D\u189E\u189F\u18A0\u18A1\u18A2\u18A3\u18A4\u18A5\u18A6\u18A7\u18A8\u18AA\u1900\u1901\u1902\u1903\u1904\u1905\u1906\u1907\u1908\u1909\u190A\u190B\u190C\u190D\u190E\u190F\u1910\u1911\u1912\u1913\u1914\u1915\u1916\u1917\u1918\u1919\u191A\u191B\u191C\u1950\u1951\u1952\u1953\u1954\u1955\u1956\u1957\u1958\u1959\u195A\u195B\u195C\u195D\u195E\u195F\u1960\u1961\u1962\u1963\u1964\u1965\u1966\u1967\u1968\u1969\u196A\u196B\u196C\u196D\u1970\u1971\u1972\u1973\u1974\u1980\u1981\u1982\u1983\u1984\u1985\u1986\u1987\u1988\u1989\u198A\u198B\u198C\u198D\u198E\u198F\u1990\u1991\u1992\u1993\u1994\u1995\u1996\u1997\u1998\u1999\u199A\u199B\u199C\u199D\u199E\u199F\u19A0\u19A1\u19A2\u19A3\u19A4\u19A5\u19A6\u19A7\u19A8\u19A9\u19C1\u19C2\u19C3\u19C4\u19C5\u19C6\u19C7\u1A00\u1A01\u1A02\u1A03\u1A04\u1A05\u1A06\u1A07\u1A08\u1A09\u1A0A\u1A0B\u1A0C\u1A0D\u1A0E\u1A0F\u1A10\u1A11\u1A12\u1A13\u1A14\u1A15\u1A16\u1B05\u1B06\u1B07\u1B08\u1B09\u1B0A\u1B0B\u1B0C\u1B0D\u1B0E\u1B0F\u1B10\u1B11\u1B12\u1B13\u1B14\u1B15\u1B16\u1B17\u1B18\u1B19\u1B1A\u1B1B\u1B1C\u1B1D\u1B1E\u1B1F\u1B20\u1B21\u1B22\u1B23\u1B24\u1B25\u1B26\u1B27\u1B28\u1B29\u1B2A\u1B2B\u1B2C\u1B2D\u1B2E\u1B2F\u1B30\u1B31\u1B32\u1B33\u1B45\u1B46\u1B47\u1B48\u1B49\u1B4A\u1B4B\u1B83\u1B84\u1B85\u1B86\u1B87\u1B88\u1B89\u1B8A\u1B8B\u1B8C\u1B8D\u1B8E\u1B8F\u1B90\u1B91\u1B92\u1B93\u1B94\u1B95\u1B96\u1B97\u1B98\u1B99\u1B9A\u1B9B\u1B9C\u1B9D\u1B9E\u1B9F\u1BA0\u1BAE\u1BAF\u1C00\u1C01\u1C02\u1C03\u1C04\u1C05\u1C06\u1C07\u1C08\u1C09\u1C0A\u1C0B\u1C0C\u1C0D\u1C0E\u1C0F\u1C10\u1C11\u1C12\u1C13\u1C14\u1C15\u1C16\u1C17\u1C18\u1C19\u1C1A\u1C1B\u1C1C\u1C1D\u1C1E\u1C1F\u1C20\u1C21\u1C22\u1C23\u1C4D\u1C4E\u1C4F\u1C5A\u1C5B\u1C5C\u1C5D\u1C5E\u1C5F\u1C60\u1C61\u1C62\u1C63\u1C64\u1C65\u1C66\u1C67\u1C68\u1C69\u1C6A\u1C6B\u1C6C\u1C6D\u1C6E\u1C6F\u1C70\u1C71\u1C72\u1C73\u1C74\u1C75\u1C76\u1C77\u2135\u2136\u2137\u2138\u2D30\u2D31\u2D32\u2D33\u2D34\u2D35\u2D36\u2D37\u2D38\u2D39\u2D3A\u2D3B\u2D3C\u2D3D\u2D3E\u2D3F\u2D40\u2D41\u2D42\u2D43\u2D44\u2D45\u2D46\u2D47\u2D48\u2D49\u2D4A\u2D4B\u2D4C\u2D4D\u2D4E\u2D4F\u2D50\u2D51\u2D52\u2D53\u2D54\u2D55\u2D56\u2D57\u2D58\u2D59\u2D5A\u2D5B\u2D5C\u2D5D\u2D5E\u2D5F\u2D60\u2D61\u2D62\u2D63\u2D64\u2D65\u2D80\u2D81\u2D82\u2D83\u2D84\u2D85\u2D86\u2D87\u2D88\u2D89\u2D8A\u2D8B\u2D8C\u2D8D\u2D8E\u2D8F\u2D90\u2D91\u2D92\u2D93\u2D94\u2D95\u2D96\u2DA0\u2DA1\u2DA2\u2DA3\u2DA4\u2DA5\u2DA6\u2DA8\u2DA9\u2DAA\u2DAB\u2DAC\u2DAD\u2DAE\u2DB0\u2DB1\u2DB2\u2DB3\u2DB4\u2DB5\u2DB6\u2DB8\u2DB9\u2DBA\u2DBB\u2DBC\u2DBD\u2DBE\u2DC0\u2DC1\u2DC2\u2DC3\u2DC4\u2DC5\u2DC6\u2DC8\u2DC9\u2DCA\u2DCB\u2DCC\u2DCD\u2DCE\u2DD0\u2DD1\u2DD2\u2DD3\u2DD4\u2DD5\u2DD6\u2DD8\u2DD9\u2DDA\u2DDB\u2DDC\u2DDD\u2DDE\u3006\u303C\u3041\u3042\u3043\u3044\u3045\u3046\u3047\u3048\u3049\u304A\u304B\u304C\u304D\u304E\u304F\u3050\u3051\u3052\u3053\u3054\u3055\u3056\u3057\u3058\u3059\u305A\u305B\u305C\u305D\u305E\u305F\u3060\u3061\u3062\u3063\u3064\u3065\u3066\u3067\u3068\u3069\u306A\u306B\u306C\u306D\u306E\u306F\u3070\u3071\u3072\u3073\u3074\u3075\u3076\u3077\u3078\u3079\u307A\u307B\u307C\u307D\u307E\u307F\u3080\u3081\u3082\u3083\u3084\u3085\u3086\u3087\u3088\u3089\u308A\u308B\u308C\u308D\u308E\u308F\u3090\u3091\u3092\u3093\u3094\u3095\u3096\u309F\u30A1\u30A2\u30A3\u30A4\u30A5\u30A6\u30A7\u30A8\u30A9\u30AA\u30AB\u30AC\u30AD\u30AE\u30AF\u30B0\u30B1\u30B2\u30B3\u30B4\u30B5\u30B6\u30B7\u30B8\u30B9\u30BA\u30BB\u30BC\u30BD\u30BE\u30BF\u30C0\u30C1\u30C2\u30C3\u30C4\u30C5\u30C6\u30C7\u30C8\u30C9\u30CA\u30CB\u30CC\u30CD\u30CE\u30CF\u30D0\u30D1\u30D2\u30D3\u30D4\u30D5\u30D6\u30D7\u30D8\u30D9\u30DA\u30DB\u30DC\u30DD\u30DE\u30DF\u30E0\u30E1\u30E2\u30E3\u30E4\u30E5\u30E6\u30E7\u30E8\u30E9\u30EA\u30EB\u30EC\u30ED\u30EE\u30EF\u30F0\u30F1\u30F2\u30F3\u30F4\u30F5\u30F6\u30F7\u30F8\u30F9\u30FA\u30FF\u3105\u3106\u3107\u3108\u3109\u310A\u310B\u310C\u310D\u310E\u310F\u3110\u3111\u3112\u3113\u3114\u3115\u3116\u3117\u3118\u3119\u311A\u311B\u311C\u311D\u311E\u311F\u3120\u3121\u3122\u3123\u3124\u3125\u3126\u3127\u3128\u3129\u312A\u312B\u312C\u312D\u3131\u3132\u3133\u3134\u3135\u3136\u3137\u3138\u3139\u313A\u313B\u313C\u313D\u313E\u313F\u3140\u3141\u3142\u3143\u3144\u3145\u3146\u3147\u3148\u3149\u314A\u314B\u314C\u314D\u314E\u314F\u3150\u3151\u3152\u3153\u3154\u3155\u3156\u3157\u3158\u3159\u315A\u315B\u315C\u315D\u315E\u315F\u3160\u3161\u3162\u3163\u3164\u3165\u3166\u3167\u3168\u3169\u316A\u316B\u316C\u316D\u316E\u316F\u3170\u3171\u3172\u3173\u3174\u3175\u3176\u3177\u3178\u3179\u317A\u317B\u317C\u317D\u317E\u317F\u3180\u3181\u3182\u3183\u3184\u3185\u3186\u3187\u3188\u3189\u318A\u318B\u318C\u318D\u318E\u31A0\u31A1\u31A2\u31A3\u31A4\u31A5\u31A6\u31A7\u31A8\u31A9\u31AA\u31AB\u31AC\u31AD\u31AE\u31AF\u31B0\u31B1\u31B2\u31B3\u31B4\u31B5\u31B6\u31B7\u31F0\u31F1\u31F2\u31F3\u31F4\u31F5\u31F6\u31F7\u31F8\u31F9\u31FA\u31FB\u31FC\u31FD\u31FE\u31FF\u3400\u4DB5\u4E00\u9FC3\uA000\uA001\uA002\uA003\uA004\uA005\uA006\uA007\uA008\uA009\uA00A\uA00B\uA00C\uA00D\uA00E\uA00F\uA010\uA011\uA012\uA013\uA014\uA016\uA017\uA018\uA019\uA01A\uA01B\uA01C\uA01D\uA01E\uA01F\uA020\uA021\uA022\uA023\uA024\uA025\uA026\uA027\uA028\uA029\uA02A\uA02B\uA02C\uA02D\uA02E\uA02F\uA030\uA031\uA032\uA033\uA034\uA035\uA036\uA037\uA038\uA039\uA03A\uA03B\uA03C\uA03D\uA03E\uA03F\uA040\uA041\uA042\uA043\uA044\uA045\uA046\uA047\uA048\uA049\uA04A\uA04B\uA04C\uA04D\uA04E\uA04F\uA050\uA051\uA052\uA053\uA054\uA055\uA056\uA057\uA058\uA059\uA05A\uA05B\uA05C\uA05D\uA05E\uA05F\uA060\uA061\uA062\uA063\uA064\uA065\uA066\uA067\uA068\uA069\uA06A\uA06B\uA06C\uA06D\uA06E\uA06F\uA070\uA071\uA072\uA073\uA074\uA075\uA076\uA077\uA078\uA079\uA07A\uA07B\uA07C\uA07D\uA07E\uA07F\uA080\uA081\uA082\uA083\uA084\uA085\uA086\uA087\uA088\uA089\uA08A\uA08B\uA08C\uA08D\uA08E\uA08F\uA090\uA091\uA092\uA093\uA094\uA095\uA096\uA097\uA098\uA099\uA09A\uA09B\uA09C\uA09D\uA09E\uA09F\uA0A0\uA0A1\uA0A2\uA0A3\uA0A4\uA0A5\uA0A6\uA0A7\uA0A8\uA0A9\uA0AA\uA0AB\uA0AC\uA0AD\uA0AE\uA0AF\uA0B0\uA0B1\uA0B2\uA0B3\uA0B4\uA0B5\uA0B6\uA0B7\uA0B8\uA0B9\uA0BA\uA0BB\uA0BC\uA0BD\uA0BE\uA0BF\uA0C0\uA0C1\uA0C2\uA0C3\uA0C4\uA0C5\uA0C6\uA0C7\uA0C8\uA0C9\uA0CA\uA0CB\uA0CC\uA0CD\uA0CE\uA0CF\uA0D0\uA0D1\uA0D2\uA0D3\uA0D4\uA0D5\uA0D6\uA0D7\uA0D8\uA0D9\uA0DA\uA0DB\uA0DC\uA0DD\uA0DE\uA0DF\uA0E0\uA0E1\uA0E2\uA0E3\uA0E4\uA0E5\uA0E6\uA0E7\uA0E8\uA0E9\uA0EA\uA0EB\uA0EC\uA0ED\uA0EE\uA0EF\uA0F0\uA0F1\uA0F2\uA0F3\uA0F4\uA0F5\uA0F6\uA0F7\uA0F8\uA0F9\uA0FA\uA0FB\uA0FC\uA0FD\uA0FE\uA0FF\uA100\uA101\uA102\uA103\uA104\uA105\uA106\uA107\uA108\uA109\uA10A\uA10B\uA10C\uA10D\uA10E\uA10F\uA110\uA111\uA112\uA113\uA114\uA115\uA116\uA117\uA118\uA119\uA11A\uA11B\uA11C\uA11D\uA11E\uA11F\uA120\uA121\uA122\uA123\uA124\uA125\uA126\uA127\uA128\uA129\uA12A\uA12B\uA12C\uA12D\uA12E\uA12F\uA130\uA131\uA132\uA133\uA134\uA135\uA136\uA137\uA138\uA139\uA13A\uA13B\uA13C\uA13D\uA13E\uA13F\uA140\uA141\uA142\uA143\uA144\uA145\uA146\uA147\uA148\uA149\uA14A\uA14B\uA14C\uA14D\uA14E\uA14F\uA150\uA151\uA152\uA153\uA154\uA155\uA156\uA157\uA158\uA159\uA15A\uA15B\uA15C\uA15D\uA15E\uA15F\uA160\uA161\uA162\uA163\uA164\uA165\uA166\uA167\uA168\uA169\uA16A\uA16B\uA16C\uA16D\uA16E\uA16F\uA170\uA171\uA172\uA173\uA174\uA175\uA176\uA177\uA178\uA179\uA17A\uA17B\uA17C\uA17D\uA17E\uA17F\uA180\uA181\uA182\uA183\uA184\uA185\uA186\uA187\uA188\uA189\uA18A\uA18B\uA18C\uA18D\uA18E\uA18F\uA190\uA191\uA192\uA193\uA194\uA195\uA196\uA197\uA198\uA199\uA19A\uA19B\uA19C\uA19D\uA19E\uA19F\uA1A0\uA1A1\uA1A2\uA1A3\uA1A4\uA1A5\uA1A6\uA1A7\uA1A8\uA1A9\uA1AA\uA1AB\uA1AC\uA1AD\uA1AE\uA1AF\uA1B0\uA1B1\uA1B2\uA1B3\uA1B4\uA1B5\uA1B6\uA1B7\uA1B8\uA1B9\uA1BA\uA1BB\uA1BC\uA1BD\uA1BE\uA1BF\uA1C0\uA1C1\uA1C2\uA1C3\uA1C4\uA1C5\uA1C6\uA1C7\uA1C8\uA1C9\uA1CA\uA1CB\uA1CC\uA1CD\uA1CE\uA1CF\uA1D0\uA1D1\uA1D2\uA1D3\uA1D4\uA1D5\uA1D6\uA1D7\uA1D8\uA1D9\uA1DA\uA1DB\uA1DC\uA1DD\uA1DE\uA1DF\uA1E0\uA1E1\uA1E2\uA1E3\uA1E4\uA1E5\uA1E6\uA1E7\uA1E8\uA1E9\uA1EA\uA1EB\uA1EC\uA1ED\uA1EE\uA1EF\uA1F0\uA1F1\uA1F2\uA1F3\uA1F4\uA1F5\uA1F6\uA1F7\uA1F8\uA1F9\uA1FA\uA1FB\uA1FC\uA1FD\uA1FE\uA1FF\uA200\uA201\uA202\uA203\uA204\uA205\uA206\uA207\uA208\uA209\uA20A\uA20B\uA20C\uA20D\uA20E\uA20F\uA210\uA211\uA212\uA213\uA214\uA215\uA216\uA217\uA218\uA219\uA21A\uA21B\uA21C\uA21D\uA21E\uA21F\uA220\uA221\uA222\uA223\uA224\uA225\uA226\uA227\uA228\uA229\uA22A\uA22B\uA22C\uA22D\uA22E\uA22F\uA230\uA231\uA232\uA233\uA234\uA235\uA236\uA237\uA238\uA239\uA23A\uA23B\uA23C\uA23D\uA23E\uA23F\uA240\uA241\uA242\uA243\uA244\uA245\uA246\uA247\uA248\uA249\uA24A\uA24B\uA24C\uA24D\uA24E\uA24F\uA250\uA251\uA252\uA253\uA254\uA255\uA256\uA257\uA258\uA259\uA25A\uA25B\uA25C\uA25D\uA25E\uA25F\uA260\uA261\uA262\uA263\uA264\uA265\uA266\uA267\uA268\uA269\uA26A\uA26B\uA26C\uA26D\uA26E\uA26F\uA270\uA271\uA272\uA273\uA274\uA275\uA276\uA277\uA278\uA279\uA27A\uA27B\uA27C\uA27D\uA27E\uA27F\uA280\uA281\uA282\uA283\uA284\uA285\uA286\uA287\uA288\uA289\uA28A\uA28B\uA28C\uA28D\uA28E\uA28F\uA290\uA291\uA292\uA293\uA294\uA295\uA296\uA297\uA298\uA299\uA29A\uA29B\uA29C\uA29D\uA29E\uA29F\uA2A0\uA2A1\uA2A2\uA2A3\uA2A4\uA2A5\uA2A6\uA2A7\uA2A8\uA2A9\uA2AA\uA2AB\uA2AC\uA2AD\uA2AE\uA2AF\uA2B0\uA2B1\uA2B2\uA2B3\uA2B4\uA2B5\uA2B6\uA2B7\uA2B8\uA2B9\uA2BA\uA2BB\uA2BC\uA2BD\uA2BE\uA2BF\uA2C0\uA2C1\uA2C2\uA2C3\uA2C4\uA2C5\uA2C6\uA2C7\uA2C8\uA2C9\uA2CA\uA2CB\uA2CC\uA2CD\uA2CE\uA2CF\uA2D0\uA2D1\uA2D2\uA2D3\uA2D4\uA2D5\uA2D6\uA2D7\uA2D8\uA2D9\uA2DA\uA2DB\uA2DC\uA2DD\uA2DE\uA2DF\uA2E0\uA2E1\uA2E2\uA2E3\uA2E4\uA2E5\uA2E6\uA2E7\uA2E8\uA2E9\uA2EA\uA2EB\uA2EC\uA2ED\uA2EE\uA2EF\uA2F0\uA2F1\uA2F2\uA2F3\uA2F4\uA2F5\uA2F6\uA2F7\uA2F8\uA2F9\uA2FA\uA2FB\uA2FC\uA2FD\uA2FE\uA2FF\uA300\uA301\uA302\uA303\uA304\uA305\uA306\uA307\uA308\uA309\uA30A\uA30B\uA30C\uA30D\uA30E\uA30F\uA310\uA311\uA312\uA313\uA314\uA315\uA316\uA317\uA318\uA319\uA31A\uA31B\uA31C\uA31D\uA31E\uA31F\uA320\uA321\uA322\uA323\uA324\uA325\uA326\uA327\uA328\uA329\uA32A\uA32B\uA32C\uA32D\uA32E\uA32F\uA330\uA331\uA332\uA333\uA334\uA335\uA336\uA337\uA338\uA339\uA33A\uA33B\uA33C\uA33D\uA33E\uA33F\uA340\uA341\uA342\uA343\uA344\uA345\uA346\uA347\uA348\uA349\uA34A\uA34B\uA34C\uA34D\uA34E\uA34F\uA350\uA351\uA352\uA353\uA354\uA355\uA356\uA357\uA358\uA359\uA35A\uA35B\uA35C\uA35D\uA35E\uA35F\uA360\uA361\uA362\uA363\uA364\uA365\uA366\uA367\uA368\uA369\uA36A\uA36B\uA36C\uA36D\uA36E\uA36F\uA370\uA371\uA372\uA373\uA374\uA375\uA376\uA377\uA378\uA379\uA37A\uA37B\uA37C\uA37D\uA37E\uA37F\uA380\uA381\uA382\uA383\uA384\uA385\uA386\uA387\uA388\uA389\uA38A\uA38B\uA38C\uA38D\uA38E\uA38F\uA390\uA391\uA392\uA393\uA394\uA395\uA396\uA397\uA398\uA399\uA39A\uA39B\uA39C\uA39D\uA39E\uA39F\uA3A0\uA3A1\uA3A2\uA3A3\uA3A4\uA3A5\uA3A6\uA3A7\uA3A8\uA3A9\uA3AA\uA3AB\uA3AC\uA3AD\uA3AE\uA3AF\uA3B0\uA3B1\uA3B2\uA3B3\uA3B4\uA3B5\uA3B6\uA3B7\uA3B8\uA3B9\uA3BA\uA3BB\uA3BC\uA3BD\uA3BE\uA3BF\uA3C0\uA3C1\uA3C2\uA3C3\uA3C4\uA3C5\uA3C6\uA3C7\uA3C8\uA3C9\uA3CA\uA3CB\uA3CC\uA3CD\uA3CE\uA3CF\uA3D0\uA3D1\uA3D2\uA3D3\uA3D4\uA3D5\uA3D6\uA3D7\uA3D8\uA3D9\uA3DA\uA3DB\uA3DC\uA3DD\uA3DE\uA3DF\uA3E0\uA3E1\uA3E2\uA3E3\uA3E4\uA3E5\uA3E6\uA3E7\uA3E8\uA3E9\uA3EA\uA3EB\uA3EC\uA3ED\uA3EE\uA3EF\uA3F0\uA3F1\uA3F2\uA3F3\uA3F4\uA3F5\uA3F6\uA3F7\uA3F8\uA3F9\uA3FA\uA3FB\uA3FC\uA3FD\uA3FE\uA3FF\uA400\uA401\uA402\uA403\uA404\uA405\uA406\uA407\uA408\uA409\uA40A\uA40B\uA40C\uA40D\uA40E\uA40F\uA410\uA411\uA412\uA413\uA414\uA415\uA416\uA417\uA418\uA419\uA41A\uA41B\uA41C\uA41D\uA41E\uA41F\uA420\uA421\uA422\uA423\uA424\uA425\uA426\uA427\uA428\uA429\uA42A\uA42B\uA42C\uA42D\uA42E\uA42F\uA430\uA431\uA432\uA433\uA434\uA435\uA436\uA437\uA438\uA439\uA43A\uA43B\uA43C\uA43D\uA43E\uA43F\uA440\uA441\uA442\uA443\uA444\uA445\uA446\uA447\uA448\uA449\uA44A\uA44B\uA44C\uA44D\uA44E\uA44F\uA450\uA451\uA452\uA453\uA454\uA455\uA456\uA457\uA458\uA459\uA45A\uA45B\uA45C\uA45D\uA45E\uA45F\uA460\uA461\uA462\uA463\uA464\uA465\uA466\uA467\uA468\uA469\uA46A\uA46B\uA46C\uA46D\uA46E\uA46F\uA470\uA471\uA472\uA473\uA474\uA475\uA476\uA477\uA478\uA479\uA47A\uA47B\uA47C\uA47D\uA47E\uA47F\uA480\uA481\uA482\uA483\uA484\uA485\uA486\uA487\uA488\uA489\uA48A\uA48B\uA48C\uA500\uA501\uA502\uA503\uA504\uA505\uA506\uA507\uA508\uA509\uA50A\uA50B\uA50C\uA50D\uA50E\uA50F\uA510\uA511\uA512\uA513\uA514\uA515\uA516\uA517\uA518\uA519\uA51A\uA51B\uA51C\uA51D\uA51E\uA51F\uA520\uA521\uA522\uA523\uA524\uA525\uA526\uA527\uA528\uA529\uA52A\uA52B\uA52C\uA52D\uA52E\uA52F\uA530\uA531\uA532\uA533\uA534\uA535\uA536\uA537\uA538\uA539\uA53A\uA53B\uA53C\uA53D\uA53E\uA53F\uA540\uA541\uA542\uA543\uA544\uA545\uA546\uA547\uA548\uA549\uA54A\uA54B\uA54C\uA54D\uA54E\uA54F\uA550\uA551\uA552\uA553\uA554\uA555\uA556\uA557\uA558\uA559\uA55A\uA55B\uA55C\uA55D\uA55E\uA55F\uA560\uA561\uA562\uA563\uA564\uA565\uA566\uA567\uA568\uA569\uA56A\uA56B\uA56C\uA56D\uA56E\uA56F\uA570\uA571\uA572\uA573\uA574\uA575\uA576\uA577\uA578\uA579\uA57A\uA57B\uA57C\uA57D\uA57E\uA57F\uA580\uA581\uA582\uA583\uA584\uA585\uA586\uA587\uA588\uA589\uA58A\uA58B\uA58C\uA58D\uA58E\uA58F\uA590\uA591\uA592\uA593\uA594\uA595\uA596\uA597\uA598\uA599\uA59A\uA59B\uA59C\uA59D\uA59E\uA59F\uA5A0\uA5A1\uA5A2\uA5A3\uA5A4\uA5A5\uA5A6\uA5A7\uA5A8\uA5A9\uA5AA\uA5AB\uA5AC\uA5AD\uA5AE\uA5AF\uA5B0\uA5B1\uA5B2\uA5B3\uA5B4\uA5B5\uA5B6\uA5B7\uA5B8\uA5B9\uA5BA\uA5BB\uA5BC\uA5BD\uA5BE\uA5BF\uA5C0\uA5C1\uA5C2\uA5C3\uA5C4\uA5C5\uA5C6\uA5C7\uA5C8\uA5C9\uA5CA\uA5CB\uA5CC\uA5CD\uA5CE\uA5CF\uA5D0\uA5D1\uA5D2\uA5D3\uA5D4\uA5D5\uA5D6\uA5D7\uA5D8\uA5D9\uA5DA\uA5DB\uA5DC\uA5DD\uA5DE\uA5DF\uA5E0\uA5E1\uA5E2\uA5E3\uA5E4\uA5E5\uA5E6\uA5E7\uA5E8\uA5E9\uA5EA\uA5EB\uA5EC\uA5ED\uA5EE\uA5EF\uA5F0\uA5F1\uA5F2\uA5F3\uA5F4\uA5F5\uA5F6\uA5F7\uA5F8\uA5F9\uA5FA\uA5FB\uA5FC\uA5FD\uA5FE\uA5FF\uA600\uA601\uA602\uA603\uA604\uA605\uA606\uA607\uA608\uA609\uA60A\uA60B\uA610\uA611\uA612\uA613\uA614\uA615\uA616\uA617\uA618\uA619\uA61A\uA61B\uA61C\uA61D\uA61E\uA61F\uA62A\uA62B\uA66E\uA7FB\uA7FC\uA7FD\uA7FE\uA7FF\uA800\uA801\uA803\uA804\uA805\uA807\uA808\uA809\uA80A\uA80C\uA80D\uA80E\uA80F\uA810\uA811\uA812\uA813\uA814\uA815\uA816\uA817\uA818\uA819\uA81A\uA81B\uA81C\uA81D\uA81E\uA81F\uA820\uA821\uA822\uA840\uA841\uA842\uA843\uA844\uA845\uA846\uA847\uA848\uA849\uA84A\uA84B\uA84C\uA84D\uA84E\uA84F\uA850\uA851\uA852\uA853\uA854\uA855\uA856\uA857\uA858\uA859\uA85A\uA85B\uA85C\uA85D\uA85E\uA85F\uA860\uA861\uA862\uA863\uA864\uA865\uA866\uA867\uA868\uA869\uA86A\uA86B\uA86C\uA86D\uA86E\uA86F\uA870\uA871\uA872\uA873\uA882\uA883\uA884\uA885\uA886\uA887\uA888\uA889\uA88A\uA88B\uA88C\uA88D\uA88E\uA88F\uA890\uA891\uA892\uA893\uA894\uA895\uA896\uA897\uA898\uA899\uA89A\uA89B\uA89C\uA89D\uA89E\uA89F\uA8A0\uA8A1\uA8A2\uA8A3\uA8A4\uA8A5\uA8A6\uA8A7\uA8A8\uA8A9\uA8AA\uA8AB\uA8AC\uA8AD\uA8AE\uA8AF\uA8B0\uA8B1\uA8B2\uA8B3\uA90A\uA90B\uA90C\uA90D\uA90E\uA90F\uA910\uA911\uA912\uA913\uA914\uA915\uA916\uA917\uA918\uA919\uA91A\uA91B\uA91C\uA91D\uA91E\uA91F\uA920\uA921\uA922\uA923\uA924\uA925\uA930\uA931\uA932\uA933\uA934\uA935\uA936\uA937\uA938\uA939\uA93A\uA93B\uA93C\uA93D\uA93E\uA93F\uA940\uA941\uA942\uA943\uA944\uA945\uA946\uAA00\uAA01\uAA02\uAA03\uAA04\uAA05\uAA06\uAA07\uAA08\uAA09\uAA0A\uAA0B\uAA0C\uAA0D\uAA0E\uAA0F\uAA10\uAA11\uAA12\uAA13\uAA14\uAA15\uAA16\uAA17\uAA18\uAA19\uAA1A\uAA1B\uAA1C\uAA1D\uAA1E\uAA1F\uAA20\uAA21\uAA22\uAA23\uAA24\uAA25\uAA26\uAA27\uAA28\uAA40\uAA41\uAA42\uAA44\uAA45\uAA46\uAA47\uAA48\uAA49\uAA4A\uAA4B\uAC00\uD7A3\uF900\uF901\uF902\uF903\uF904\uF905\uF906\uF907\uF908\uF909\uF90A\uF90B\uF90C\uF90D\uF90E\uF90F\uF910\uF911\uF912\uF913\uF914\uF915\uF916\uF917\uF918\uF919\uF91A\uF91B\uF91C\uF91D\uF91E\uF91F\uF920\uF921\uF922\uF923\uF924\uF925\uF926\uF927\uF928\uF929\uF92A\uF92B\uF92C\uF92D\uF92E\uF92F\uF930\uF931\uF932\uF933\uF934\uF935\uF936\uF937\uF938\uF939\uF93A\uF93B\uF93C\uF93D\uF93E\uF93F\uF940\uF941\uF942\uF943\uF944\uF945\uF946\uF947\uF948\uF949\uF94A\uF94B\uF94C\uF94D\uF94E\uF94F\uF950\uF951\uF952\uF953\uF954\uF955\uF956\uF957\uF958\uF959\uF95A\uF95B\uF95C\uF95D\uF95E\uF95F\uF960\uF961\uF962\uF963\uF964\uF965\uF966\uF967\uF968\uF969\uF96A\uF96B\uF96C\uF96D\uF96E\uF96F\uF970\uF971\uF972\uF973\uF974\uF975\uF976\uF977\uF978\uF979\uF97A\uF97B\uF97C\uF97D\uF97E\uF97F\uF980\uF981\uF982\uF983\uF984\uF985\uF986\uF987\uF988\uF989\uF98A\uF98B\uF98C\uF98D\uF98E\uF98F\uF990\uF991\uF992\uF993\uF994\uF995\uF996\uF997\uF998\uF999\uF99A\uF99B\uF99C\uF99D\uF99E\uF99F\uF9A0\uF9A1\uF9A2\uF9A3\uF9A4\uF9A5\uF9A6\uF9A7\uF9A8\uF9A9\uF9AA\uF9AB\uF9AC\uF9AD\uF9AE\uF9AF\uF9B0\uF9B1\uF9B2\uF9B3\uF9B4\uF9B5\uF9B6\uF9B7\uF9B8\uF9B9\uF9BA\uF9BB\uF9BC\uF9BD\uF9BE\uF9BF\uF9C0\uF9C1\uF9C2\uF9C3\uF9C4\uF9C5\uF9C6\uF9C7\uF9C8\uF9C9\uF9CA\uF9CB\uF9CC\uF9CD\uF9CE\uF9CF\uF9D0\uF9D1\uF9D2\uF9D3\uF9D4\uF9D5\uF9D6\uF9D7\uF9D8\uF9D9\uF9DA\uF9DB\uF9DC\uF9DD\uF9DE\uF9DF\uF9E0\uF9E1\uF9E2\uF9E3\uF9E4\uF9E5\uF9E6\uF9E7\uF9E8\uF9E9\uF9EA\uF9EB\uF9EC\uF9ED\uF9EE\uF9EF\uF9F0\uF9F1\uF9F2\uF9F3\uF9F4\uF9F5\uF9F6\uF9F7\uF9F8\uF9F9\uF9FA\uF9FB\uF9FC\uF9FD\uF9FE\uF9FF\uFA00\uFA01\uFA02\uFA03\uFA04\uFA05\uFA06\uFA07\uFA08\uFA09\uFA0A\uFA0B\uFA0C\uFA0D\uFA0E\uFA0F\uFA10\uFA11\uFA12\uFA13\uFA14\uFA15\uFA16\uFA17\uFA18\uFA19\uFA1A\uFA1B\uFA1C\uFA1D\uFA1E\uFA1F\uFA20\uFA21\uFA22\uFA23\uFA24\uFA25\uFA26\uFA27\uFA28\uFA29\uFA2A\uFA2B\uFA2C\uFA2D\uFA30\uFA31\uFA32\uFA33\uFA34\uFA35\uFA36\uFA37\uFA38\uFA39\uFA3A\uFA3B\uFA3C\uFA3D\uFA3E\uFA3F\uFA40\uFA41\uFA42\uFA43\uFA44\uFA45\uFA46\uFA47\uFA48\uFA49\uFA4A\uFA4B\uFA4C\uFA4D\uFA4E\uFA4F\uFA50\uFA51\uFA52\uFA53\uFA54\uFA55\uFA56\uFA57\uFA58\uFA59\uFA5A\uFA5B\uFA5C\uFA5D\uFA5E\uFA5F\uFA60\uFA61\uFA62\uFA63\uFA64\uFA65\uFA66\uFA67\uFA68\uFA69\uFA6A\uFA70\uFA71\uFA72\uFA73\uFA74\uFA75\uFA76\uFA77\uFA78\uFA79\uFA7A\uFA7B\uFA7C\uFA7D\uFA7E\uFA7F\uFA80\uFA81\uFA82\uFA83\uFA84\uFA85\uFA86\uFA87\uFA88\uFA89\uFA8A\uFA8B\uFA8C\uFA8D\uFA8E\uFA8F\uFA90\uFA91\uFA92\uFA93\uFA94\uFA95\uFA96\uFA97\uFA98\uFA99\uFA9A\uFA9B\uFA9C\uFA9D\uFA9E\uFA9F\uFAA0\uFAA1\uFAA2\uFAA3\uFAA4\uFAA5\uFAA6\uFAA7\uFAA8\uFAA9\uFAAA\uFAAB\uFAAC\uFAAD\uFAAE\uFAAF\uFAB0\uFAB1\uFAB2\uFAB3\uFAB4\uFAB5\uFAB6\uFAB7\uFAB8\uFAB9\uFABA\uFABB\uFABC\uFABD\uFABE\uFABF\uFAC0\uFAC1\uFAC2\uFAC3\uFAC4\uFAC5\uFAC6\uFAC7\uFAC8\uFAC9\uFACA\uFACB\uFACC\uFACD\uFACE\uFACF\uFAD0\uFAD1\uFAD2\uFAD3\uFAD4\uFAD5\uFAD6\uFAD7\uFAD8\uFAD9\uFB1D\uFB1F\uFB20\uFB21\uFB22\uFB23\uFB24\uFB25\uFB26\uFB27\uFB28\uFB2A\uFB2B\uFB2C\uFB2D\uFB2E\uFB2F\uFB30\uFB31\uFB32\uFB33\uFB34\uFB35\uFB36\uFB38\uFB39\uFB3A\uFB3B\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46\uFB47\uFB48\uFB49\uFB4A\uFB4B\uFB4C\uFB4D\uFB4E\uFB4F\uFB50\uFB51\uFB52\uFB53\uFB54\uFB55\uFB56\uFB57\uFB58\uFB59\uFB5A\uFB5B\uFB5C\uFB5D\uFB5E\uFB5F\uFB60\uFB61\uFB62\uFB63\uFB64\uFB65\uFB66\uFB67\uFB68\uFB69\uFB6A\uFB6B\uFB6C\uFB6D\uFB6E\uFB6F\uFB70\uFB71\uFB72\uFB73\uFB74\uFB75\uFB76\uFB77\uFB78\uFB79\uFB7A\uFB7B\uFB7C\uFB7D\uFB7E\uFB7F\uFB80\uFB81\uFB82\uFB83\uFB84\uFB85\uFB86\uFB87\uFB88\uFB89\uFB8A\uFB8B\uFB8C\uFB8D\uFB8E\uFB8F\uFB90\uFB91\uFB92\uFB93\uFB94\uFB95\uFB96\uFB97\uFB98\uFB99\uFB9A\uFB9B\uFB9C\uFB9D\uFB9E\uFB9F\uFBA0\uFBA1\uFBA2\uFBA3\uFBA4\uFBA5\uFBA6\uFBA7\uFBA8\uFBA9\uFBAA\uFBAB\uFBAC\uFBAD\uFBAE\uFBAF\uFBB0\uFBB1\uFBD3\uFBD4\uFBD5\uFBD6\uFBD7\uFBD8\uFBD9\uFBDA\uFBDB\uFBDC\uFBDD\uFBDE\uFBDF\uFBE0\uFBE1\uFBE2\uFBE3\uFBE4\uFBE5\uFBE6\uFBE7\uFBE8\uFBE9\uFBEA\uFBEB\uFBEC\uFBED\uFBEE\uFBEF\uFBF0\uFBF1\uFBF2\uFBF3\uFBF4\uFBF5\uFBF6\uFBF7\uFBF8\uFBF9\uFBFA\uFBFB\uFBFC\uFBFD\uFBFE\uFBFF\uFC00\uFC01\uFC02\uFC03\uFC04\uFC05\uFC06\uFC07\uFC08\uFC09\uFC0A\uFC0B\uFC0C\uFC0D\uFC0E\uFC0F\uFC10\uFC11\uFC12\uFC13\uFC14\uFC15\uFC16\uFC17\uFC18\uFC19\uFC1A\uFC1B\uFC1C\uFC1D\uFC1E\uFC1F\uFC20\uFC21\uFC22\uFC23\uFC24\uFC25\uFC26\uFC27\uFC28\uFC29\uFC2A\uFC2B\uFC2C\uFC2D\uFC2E\uFC2F\uFC30\uFC31\uFC32\uFC33\uFC34\uFC35\uFC36\uFC37\uFC38\uFC39\uFC3A\uFC3B\uFC3C\uFC3D\uFC3E\uFC3F\uFC40\uFC41\uFC42\uFC43\uFC44\uFC45\uFC46\uFC47\uFC48\uFC49\uFC4A\uFC4B\uFC4C\uFC4D\uFC4E\uFC4F\uFC50\uFC51\uFC52\uFC53\uFC54\uFC55\uFC56\uFC57\uFC58\uFC59\uFC5A\uFC5B\uFC5C\uFC5D\uFC5E\uFC5F\uFC60\uFC61\uFC62\uFC63\uFC64\uFC65\uFC66\uFC67\uFC68\uFC69\uFC6A\uFC6B\uFC6C\uFC6D\uFC6E\uFC6F\uFC70\uFC71\uFC72\uFC73\uFC74\uFC75\uFC76\uFC77\uFC78\uFC79\uFC7A\uFC7B\uFC7C\uFC7D\uFC7E\uFC7F\uFC80\uFC81\uFC82\uFC83\uFC84\uFC85\uFC86\uFC87\uFC88\uFC89\uFC8A\uFC8B\uFC8C\uFC8D\uFC8E\uFC8F\uFC90\uFC91\uFC92\uFC93\uFC94\uFC95\uFC96\uFC97\uFC98\uFC99\uFC9A\uFC9B\uFC9C\uFC9D\uFC9E\uFC9F\uFCA0\uFCA1\uFCA2\uFCA3\uFCA4\uFCA5\uFCA6\uFCA7\uFCA8\uFCA9\uFCAA\uFCAB\uFCAC\uFCAD\uFCAE\uFCAF\uFCB0\uFCB1\uFCB2\uFCB3\uFCB4\uFCB5\uFCB6\uFCB7\uFCB8\uFCB9\uFCBA\uFCBB\uFCBC\uFCBD\uFCBE\uFCBF\uFCC0\uFCC1\uFCC2\uFCC3\uFCC4\uFCC5\uFCC6\uFCC7\uFCC8\uFCC9\uFCCA\uFCCB\uFCCC\uFCCD\uFCCE\uFCCF\uFCD0\uFCD1\uFCD2\uFCD3\uFCD4\uFCD5\uFCD6\uFCD7\uFCD8\uFCD9\uFCDA\uFCDB\uFCDC\uFCDD\uFCDE\uFCDF\uFCE0\uFCE1\uFCE2\uFCE3\uFCE4\uFCE5\uFCE6\uFCE7\uFCE8\uFCE9\uFCEA\uFCEB\uFCEC\uFCED\uFCEE\uFCEF\uFCF0\uFCF1\uFCF2\uFCF3\uFCF4\uFCF5\uFCF6\uFCF7\uFCF8\uFCF9\uFCFA\uFCFB\uFCFC\uFCFD\uFCFE\uFCFF\uFD00\uFD01\uFD02\uFD03\uFD04\uFD05\uFD06\uFD07\uFD08\uFD09\uFD0A\uFD0B\uFD0C\uFD0D\uFD0E\uFD0F\uFD10\uFD11\uFD12\uFD13\uFD14\uFD15\uFD16\uFD17\uFD18\uFD19\uFD1A\uFD1B\uFD1C\uFD1D\uFD1E\uFD1F\uFD20\uFD21\uFD22\uFD23\uFD24\uFD25\uFD26\uFD27\uFD28\uFD29\uFD2A\uFD2B\uFD2C\uFD2D\uFD2E\uFD2F\uFD30\uFD31\uFD32\uFD33\uFD34\uFD35\uFD36\uFD37\uFD38\uFD39\uFD3A\uFD3B\uFD3C\uFD3D\uFD50\uFD51\uFD52\uFD53\uFD54\uFD55\uFD56\uFD57\uFD58\uFD59\uFD5A\uFD5B\uFD5C\uFD5D\uFD5E\uFD5F\uFD60\uFD61\uFD62\uFD63\uFD64\uFD65\uFD66\uFD67\uFD68\uFD69\uFD6A\uFD6B\uFD6C\uFD6D\uFD6E\uFD6F\uFD70\uFD71\uFD72\uFD73\uFD74\uFD75\uFD76\uFD77\uFD78\uFD79\uFD7A\uFD7B\uFD7C\uFD7D\uFD7E\uFD7F\uFD80\uFD81\uFD82\uFD83\uFD84\uFD85\uFD86\uFD87\uFD88\uFD89\uFD8A\uFD8B\uFD8C\uFD8D\uFD8E\uFD8F\uFD92\uFD93\uFD94\uFD95\uFD96\uFD97\uFD98\uFD99\uFD9A\uFD9B\uFD9C\uFD9D\uFD9E\uFD9F\uFDA0\uFDA1\uFDA2\uFDA3\uFDA4\uFDA5\uFDA6\uFDA7\uFDA8\uFDA9\uFDAA\uFDAB\uFDAC\uFDAD\uFDAE\uFDAF\uFDB0\uFDB1\uFDB2\uFDB3\uFDB4\uFDB5\uFDB6\uFDB7\uFDB8\uFDB9\uFDBA\uFDBB\uFDBC\uFDBD\uFDBE\uFDBF\uFDC0\uFDC1\uFDC2\uFDC3\uFDC4\uFDC5\uFDC6\uFDC7\uFDF0\uFDF1\uFDF2\uFDF3\uFDF4\uFDF5\uFDF6\uFDF7\uFDF8\uFDF9\uFDFA\uFDFB\uFE70\uFE71\uFE72\uFE73\uFE74\uFE76\uFE77\uFE78\uFE79\uFE7A\uFE7B\uFE7C\uFE7D\uFE7E\uFE7F\uFE80\uFE81\uFE82\uFE83\uFE84\uFE85\uFE86\uFE87\uFE88\uFE89\uFE8A\uFE8B\uFE8C\uFE8D\uFE8E\uFE8F\uFE90\uFE91\uFE92\uFE93\uFE94\uFE95\uFE96\uFE97\uFE98\uFE99\uFE9A\uFE9B\uFE9C\uFE9D\uFE9E\uFE9F\uFEA0\uFEA1\uFEA2\uFEA3\uFEA4\uFEA5\uFEA6\uFEA7\uFEA8\uFEA9\uFEAA\uFEAB\uFEAC\uFEAD\uFEAE\uFEAF\uFEB0\uFEB1\uFEB2\uFEB3\uFEB4\uFEB5\uFEB6\uFEB7\uFEB8\uFEB9\uFEBA\uFEBB\uFEBC\uFEBD\uFEBE\uFEBF\uFEC0\uFEC1\uFEC2\uFEC3\uFEC4\uFEC5\uFEC6\uFEC7\uFEC8\uFEC9\uFECA\uFECB\uFECC\uFECD\uFECE\uFECF\uFED0\uFED1\uFED2\uFED3\uFED4\uFED5\uFED6\uFED7\uFED8\uFED9\uFEDA\uFEDB\uFEDC\uFEDD\uFEDE\uFEDF\uFEE0\uFEE1\uFEE2\uFEE3\uFEE4\uFEE5\uFEE6\uFEE7\uFEE8\uFEE9\uFEEA\uFEEB\uFEEC\uFEED\uFEEE\uFEEF\uFEF0\uFEF1\uFEF2\uFEF3\uFEF4\uFEF5\uFEF6\uFEF7\uFEF8\uFEF9\uFEFA\uFEFB\uFEFC\uFF66\uFF67\uFF68\uFF69\uFF6A\uFF6B\uFF6C\uFF6D\uFF6E\uFF6F\uFF71\uFF72\uFF73\uFF74\uFF75\uFF76\uFF77\uFF78\uFF79\uFF7A\uFF7B\uFF7C\uFF7D\uFF7E\uFF7F\uFF80\uFF81\uFF82\uFF83\uFF84\uFF85\uFF86\uFF87\uFF88\uFF89\uFF8A\uFF8B\uFF8C\uFF8D\uFF8E\uFF8F\uFF90\uFF91\uFF92\uFF93\uFF94\uFF95\uFF96\uFF97\uFF98\uFF99\uFF9A\uFF9B\uFF9C\uFF9D\uFFA0\uFFA1\uFFA2\uFFA3\uFFA4\uFFA5\uFFA6\uFFA7\uFFA8\uFFA9\uFFAA\uFFAB\uFFAC\uFFAD\uFFAE\uFFAF\uFFB0\uFFB1\uFFB2\uFFB3\uFFB4\uFFB5\uFFB6\uFFB7\uFFB8\uFFB9\uFFBA\uFFBB\uFFBC\uFFBD\uFFBE\uFFC2\uFFC3\uFFC4\uFFC5\uFFC6\uFFC7\uFFCA\uFFCB\uFFCC\uFFCD\uFFCE\uFFCF\uFFD2\uFFD3\uFFD4\uFFD5\uFFD6\uFFD7\uFFDA\uFFDB\uFFDC]
431 Lo = [\u00AA\u00BA\u01BB\u01C0-\u01C3\u0294\u05D0-\u05EA\u05F0-\u05F2\u0620-\u063F\u0641-\u064A\u066E-\u066F\u0671-\u06D3\u06D5\u06EE-\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u0800-\u0815\u0840-\u0858\u08A0-\u08B4\u0904-\u0939\u093D\u0950\u0958-\u0961\u0972-\u0980\u0985-\u098C\u098F-\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC-\u09DD\u09DF-\u09E1\u09F0-\u09F1\u0A05-\u0A0A\u0A0F-\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32-\u0A33\u0A35-\u0A36\u0A38-\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2-\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0-\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F-\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32-\u0B33\u0B35-\u0B39\u0B3D\u0B5C-\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99-\u0B9A\u0B9C\u0B9E-\u0B9F\u0BA3-\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60-\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0-\u0CE1\u0CF1-\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32-\u0E33\u0E40-\u0E45\u0E81-\u0E82\u0E84\u0E87-\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA-\u0EAB\u0EAD-\u0EB0\u0EB2-\u0EB3\u0EBD\u0EC0-\u0EC4\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065-\u1066\u106E-\u1070\u1075-\u1081\u108E\u10D0-\u10FA\u10FD-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17DC\u1820-\u1842\u1844-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE-\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C77\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5-\u1CF6\u2135-\u2138\u2D30-\u2D67\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3006\u303C\u3041-\u3096\u309F\u30A1-\u30FA\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA014\uA016-\uA48C\uA4D0-\uA4F7\uA500-\uA60B\uA610-\uA61F\uA62A-\uA62B\uA66E\uA6A0-\uA6E5\uA78F\uA7F7\uA7FB-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9E0-\uA9E4\uA9E7-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA6F\uAA71-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5-\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADC\uAAE0-\uAAEA\uAAF2\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40-\uFB41\uFB43-\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF66-\uFF6F\uFF71-\uFF9D\uFFA0-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]
418432
419433 // Letter, Titlecase
420 Lt = [\u01C5\u01C8\u01CB\u01F2\u1F88\u1F89\u1F8A\u1F8B\u1F8C\u1F8D\u1F8E\u1F8F\u1F98\u1F99\u1F9A\u1F9B\u1F9C\u1F9D\u1F9E\u1F9F\u1FA8\u1FA9\u1FAA\u1FAB\u1FAC\u1FAD\u1FAE\u1FAF\u1FBC\u1FCC\u1FFC]
434 Lt = [\u01C5\u01C8\u01CB\u01F2\u1F88-\u1F8F\u1F98-\u1F9F\u1FA8-\u1FAF\u1FBC\u1FCC\u1FFC]
421435
422436 // Letter, Uppercase
423 Lu = [\u0041\u0042\u0043\u0044\u0045\u0046\u0047\u0048\u0049\u004A\u004B\u004C\u004D\u004E\u004F\u0050\u0051\u0052\u0053\u0054\u0055\u0056\u0057\u0058\u0059\u005A\u00C0\u00C1\u00C2\u00C3\u00C4\u00C5\u00C6\u00C7\u00C8\u00C9\u00CA\u00CB\u00CC\u00CD\u00CE\u00CF\u00D0\u00D1\u00D2\u00D3\u00D4\u00D5\u00D6\u00D8\u00D9\u00DA\u00DB\u00DC\u00DD\u00DE\u0100\u0102\u0104\u0106\u0108\u010A\u010C\u010E\u0110\u0112\u0114\u0116\u0118\u011A\u011C\u011E\u0120\u0122\u0124\u0126\u0128\u012A\u012C\u012E\u0130\u0132\u0134\u0136\u0139\u013B\u013D\u013F\u0141\u0143\u0145\u0147\u014A\u014C\u014E\u0150\u0152\u0154\u0156\u0158\u015A\u015C\u015E\u0160\u0162\u0164\u0166\u0168\u016A\u016C\u016E\u0170\u0172\u0174\u0176\u0178\u0179\u017B\u017D\u0181\u0182\u0184\u0186\u0187\u0189\u018A\u018B\u018E\u018F\u0190\u0191\u0193\u0194\u0196\u0197\u0198\u019C\u019D\u019F\u01A0\u01A2\u01A4\u01A6\u01A7\u01A9\u01AC\u01AE\u01AF\u01B1\u01B2\u01B3\u01B5\u01B7\u01B8\u01BC\u01C4\u01C7\u01CA\u01CD\u01CF\u01D1\u01D3\u01D5\u01D7\u01D9\u01DB\u01DE\u01E0\u01E2\u01E4\u01E6\u01E8\u01EA\u01EC\u01EE\u01F1\u01F4\u01F6\u01F7\u01F8\u01FA\u01FC\u01FE\u0200\u0202\u0204\u0206\u0208\u020A\u020C\u020E\u0210\u0212\u0214\u0216\u0218\u021A\u021C\u021E\u0220\u0222\u0224\u0226\u0228\u022A\u022C\u022E\u0230\u0232\u023A\u023B\u023D\u023E\u0241\u0243\u0244\u0245\u0246\u0248\u024A\u024C\u024E\u0370\u0372\u0376\u0386\u0388\u0389\u038A\u038C\u038E\u038F\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039A\u039B\u039C\u039D\u039E\u039F\u03A0\u03A1\u03A3\u03A4\u03A5\u03A6\u03A7\u03A8\u03A9\u03AA\u03AB\u03CF\u03D2\u03D3\u03D4\u03D8\u03DA\u03DC\u03DE\u03E0\u03E2\u03E4\u03E6\u03E8\u03EA\u03EC\u03EE\u03F4\u03F7\u03F9\u03FA\u03FD\u03FE\u03FF\u0400\u0401\u0402\u0403\u0404\u0405\u0406\u0407\u0408\u0409\u040A\u040B\u040C\u040D\u040E\u040F\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041A\u041B\u041C\u041D\u041E\u041F\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042A\u042B\u042C\u042D\u042E\u042F\u0460\u0462\u0464\u0466\u0468\u046A\u046C\u046E\u0470\u0472\u0474\u0476\u0478\u047A\u047C\u047E\u0480\u048A\u048C\u048E\u0490\u0492\u0494\u0496\u0498\u049A\u049C\u049E\u04A0\u04A2\u04A4\u04A6\u04A8\u04AA\u04AC\u04AE\u04B0\u04B2\u04B4\u04B6\u04B8\u04BA\u04BC\u04BE\u04C0\u04C1\u04C3\u04C5\u04C7\u04C9\u04CB\u04CD\u04D0\u04D2\u04D4\u04D6\u04D8\u04DA\u04DC\u04DE\u04E0\u04E2\u04E4\u04E6\u04E8\u04EA\u04EC\u04EE\u04F0\u04F2\u04F4\u04F6\u04F8\u04FA\u04FC\u04FE\u0500\u0502\u0504\u0506\u0508\u050A\u050C\u050E\u0510\u0512\u0514\u0516\u0518\u051A\u051C\u051E\u0520\u0522\u0531\u0532\u0533\u0534\u0535\u0536\u0537\u0538\u0539\u053A\u053B\u053C\u053D\u053E\u053F\u0540\u0541\u0542\u0543\u0544\u0545\u0546\u0547\u0548\u0549\u054A\u054B\u054C\u054D\u054E\u054F\u0550\u0551\u0552\u0553\u0554\u0555\u0556\u10A0\u10A1\u10A2\u10A3\u10A4\u10A5\u10A6\u10A7\u10A8\u10A9\u10AA\u10AB\u10AC\u10AD\u10AE\u10AF\u10B0\u10B1\u10B2\u10B3\u10B4\u10B5\u10B6\u10B7\u10B8\u10B9\u10BA\u10BB\u10BC\u10BD\u10BE\u10BF\u10C0\u10C1\u10C2\u10C3\u10C4\u10C5\u1E00\u1E02\u1E04\u1E06\u1E08\u1E0A\u1E0C\u1E0E\u1E10\u1E12\u1E14\u1E16\u1E18\u1E1A\u1E1C\u1E1E\u1E20\u1E22\u1E24\u1E26\u1E28\u1E2A\u1E2C\u1E2E\u1E30\u1E32\u1E34\u1E36\u1E38\u1E3A\u1E3C\u1E3E\u1E40\u1E42\u1E44\u1E46\u1E48\u1E4A\u1E4C\u1E4E\u1E50\u1E52\u1E54\u1E56\u1E58\u1E5A\u1E5C\u1E5E\u1E60\u1E62\u1E64\u1E66\u1E68\u1E6A\u1E6C\u1E6E\u1E70\u1E72\u1E74\u1E76\u1E78\u1E7A\u1E7C\u1E7E\u1E80\u1E82\u1E84\u1E86\u1E88\u1E8A\u1E8C\u1E8E\u1E90\u1E92\u1E94\u1E9E\u1EA0\u1EA2\u1EA4\u1EA6\u1EA8\u1EAA\u1EAC\u1EAE\u1EB0\u1EB2\u1EB4\u1EB6\u1EB8\u1EBA\u1EBC\u1EBE\u1EC0\u1EC2\u1EC4\u1EC6\u1EC8\u1ECA\u1ECC\u1ECE\u1ED0\u1ED2\u1ED4\u1ED6\u1ED8\u1EDA\u1EDC\u1EDE\u1EE0\u1EE2\u1EE4\u1EE6\u1EE8\u1EEA\u1EEC\u1EEE\u1EF0\u1EF2\u1EF4\u1EF6\u1EF8\u1EFA\u1EFC\u1EFE\u1F08\u1F09\u1F0A\u1F0B\u1F0C\u1F0D\u1F0E\u1F0F\u1F18\u1F19\u1F1A\u1F1B\u1F1C\u1F1D\u1F28\u1F29\u1F2A\u1F2B\u1F2C\u1F2D\u1F2E\u1F2F\u1F38\u1F39\u1F3A\u1F3B\u1F3C\u1F3D\u1F3E\u1F3F\u1F48\u1F49\u1F4A\u1F4B\u1F4C\u1F4D\u1F59\u1F5B\u1F5D\u1F5F\u1F68\u1F69\u1F6A\u1F6B\u1F6C\u1F6D\u1F6E\u1F6F\u1FB8\u1FB9\u1FBA\u1FBB\u1FC8\u1FC9\u1FCA\u1FCB\u1FD8\u1FD9\u1FDA\u1FDB\u1FE8\u1FE9\u1FEA\u1FEB\u1FEC\u1FF8\u1FF9\u1FFA\u1FFB\u2102\u2107\u210B\u210C\u210D\u2110\u2111\u2112\u2115\u2119\u211A\u211B\u211C\u211D\u2124\u2126\u2128\u212A\u212B\u212C\u212D\u2130\u2131\u2132\u2133\u213E\u213F\u2145\u2183\u2C00\u2C01\u2C02\u2C03\u2C04\u2C05\u2C06\u2C07\u2C08\u2C09\u2C0A\u2C0B\u2C0C\u2C0D\u2C0E\u2C0F\u2C10\u2C11\u2C12\u2C13\u2C14\u2C15\u2C16\u2C17\u2C18\u2C19\u2C1A\u2C1B\u2C1C\u2C1D\u2C1E\u2C1F\u2C20\u2C21\u2C22\u2C23\u2C24\u2C25\u2C26\u2C27\u2C28\u2C29\u2C2A\u2C2B\u2C2C\u2C2D\u2C2E\u2C60\u2C62\u2C63\u2C64\u2C67\u2C69\u2C6B\u2C6D\u2C6E\u2C6F\u2C72\u2C75\u2C80\u2C82\u2C84\u2C86\u2C88\u2C8A\u2C8C\u2C8E\u2C90\u2C92\u2C94\u2C96\u2C98\u2C9A\u2C9C\u2C9E\u2CA0\u2CA2\u2CA4\u2CA6\u2CA8\u2CAA\u2CAC\u2CAE\u2CB0\u2CB2\u2CB4\u2CB6\u2CB8\u2CBA\u2CBC\u2CBE\u2CC0\u2CC2\u2CC4\u2CC6\u2CC8\u2CCA\u2CCC\u2CCE\u2CD0\u2CD2\u2CD4\u2CD6\u2CD8\u2CDA\u2CDC\u2CDE\u2CE0\u2CE2\uA640\uA642\uA644\uA646\uA648\uA64A\uA64C\uA64E\uA650\uA652\uA654\uA656\uA658\uA65A\uA65C\uA65E\uA662\uA664\uA666\uA668\uA66A\uA66C\uA680\uA682\uA684\uA686\uA688\uA68A\uA68C\uA68E\uA690\uA692\uA694\uA696\uA722\uA724\uA726\uA728\uA72A\uA72C\uA72E\uA732\uA734\uA736\uA738\uA73A\uA73C\uA73E\uA740\uA742\uA744\uA746\uA748\uA74A\uA74C\uA74E\uA750\uA752\uA754\uA756\uA758\uA75A\uA75C\uA75E\uA760\uA762\uA764\uA766\uA768\uA76A\uA76C\uA76E\uA779\uA77B\uA77D\uA77E\uA780\uA782\uA784\uA786\uA78B\uFF21\uFF22\uFF23\uFF24\uFF25\uFF26\uFF27\uFF28\uFF29\uFF2A\uFF2B\uFF2C\uFF2D\uFF2E\uFF2F\uFF30\uFF31\uFF32\uFF33\uFF34\uFF35\uFF36\uFF37\uFF38\uFF39\uFF3A]
437 Lu = [\u0041-\u005A\u00C0-\u00D6\u00D8-\u00DE\u0100\u0102\u0104\u0106\u0108\u010A\u010C\u010E\u0110\u0112\u0114\u0116\u0118\u011A\u011C\u011E\u0120\u0122\u0124\u0126\u0128\u012A\u012C\u012E\u0130\u0132\u0134\u0136\u0139\u013B\u013D\u013F\u0141\u0143\u0145\u0147\u014A\u014C\u014E\u0150\u0152\u0154\u0156\u0158\u015A\u015C\u015E\u0160\u0162\u0164\u0166\u0168\u016A\u016C\u016E\u0170\u0172\u0174\u0176\u0178-\u0179\u017B\u017D\u0181-\u0182\u0184\u0186-\u0187\u0189-\u018B\u018E-\u0191\u0193-\u0194\u0196-\u0198\u019C-\u019D\u019F-\u01A0\u01A2\u01A4\u01A6-\u01A7\u01A9\u01AC\u01AE-\u01AF\u01B1-\u01B3\u01B5\u01B7-\u01B8\u01BC\u01C4\u01C7\u01CA\u01CD\u01CF\u01D1\u01D3\u01D5\u01D7\u01D9\u01DB\u01DE\u01E0\u01E2\u01E4\u01E6\u01E8\u01EA\u01EC\u01EE\u01F1\u01F4\u01F6-\u01F8\u01FA\u01FC\u01FE\u0200\u0202\u0204\u0206\u0208\u020A\u020C\u020E\u0210\u0212\u0214\u0216\u0218\u021A\u021C\u021E\u0220\u0222\u0224\u0226\u0228\u022A\u022C\u022E\u0230\u0232\u023A-\u023B\u023D-\u023E\u0241\u0243-\u0246\u0248\u024A\u024C\u024E\u0370\u0372\u0376\u037F\u0386\u0388-\u038A\u038C\u038E-\u038F\u0391-\u03A1\u03A3-\u03AB\u03CF\u03D2-\u03D4\u03D8\u03DA\u03DC\u03DE\u03E0\u03E2\u03E4\u03E6\u03E8\u03EA\u03EC\u03EE\u03F4\u03F7\u03F9-\u03FA\u03FD-\u042F\u0460\u0462\u0464\u0466\u0468\u046A\u046C\u046E\u0470\u0472\u0474\u0476\u0478\u047A\u047C\u047E\u0480\u048A\u048C\u048E\u0490\u0492\u0494\u0496\u0498\u049A\u049C\u049E\u04A0\u04A2\u04A4\u04A6\u04A8\u04AA\u04AC\u04AE\u04B0\u04B2\u04B4\u04B6\u04B8\u04BA\u04BC\u04BE\u04C0-\u04C1\u04C3\u04C5\u04C7\u04C9\u04CB\u04CD\u04D0\u04D2\u04D4\u04D6\u04D8\u04DA\u04DC\u04DE\u04E0\u04E2\u04E4\u04E6\u04E8\u04EA\u04EC\u04EE\u04F0\u04F2\u04F4\u04F6\u04F8\u04FA\u04FC\u04FE\u0500\u0502\u0504\u0506\u0508\u050A\u050C\u050E\u0510\u0512\u0514\u0516\u0518\u051A\u051C\u051E\u0520\u0522\u0524\u0526\u0528\u052A\u052C\u052E\u0531-\u0556\u10A0-\u10C5\u10C7\u10CD\u13A0-\u13F5\u1E00\u1E02\u1E04\u1E06\u1E08\u1E0A\u1E0C\u1E0E\u1E10\u1E12\u1E14\u1E16\u1E18\u1E1A\u1E1C\u1E1E\u1E20\u1E22\u1E24\u1E26\u1E28\u1E2A\u1E2C\u1E2E\u1E30\u1E32\u1E34\u1E36\u1E38\u1E3A\u1E3C\u1E3E\u1E40\u1E42\u1E44\u1E46\u1E48\u1E4A\u1E4C\u1E4E\u1E50\u1E52\u1E54\u1E56\u1E58\u1E5A\u1E5C\u1E5E\u1E60\u1E62\u1E64\u1E66\u1E68\u1E6A\u1E6C\u1E6E\u1E70\u1E72\u1E74\u1E76\u1E78\u1E7A\u1E7C\u1E7E\u1E80\u1E82\u1E84\u1E86\u1E88\u1E8A\u1E8C\u1E8E\u1E90\u1E92\u1E94\u1E9E\u1EA0\u1EA2\u1EA4\u1EA6\u1EA8\u1EAA\u1EAC\u1EAE\u1EB0\u1EB2\u1EB4\u1EB6\u1EB8\u1EBA\u1EBC\u1EBE\u1EC0\u1EC2\u1EC4\u1EC6\u1EC8\u1ECA\u1ECC\u1ECE\u1ED0\u1ED2\u1ED4\u1ED6\u1ED8\u1EDA\u1EDC\u1EDE\u1EE0\u1EE2\u1EE4\u1EE6\u1EE8\u1EEA\u1EEC\u1EEE\u1EF0\u1EF2\u1EF4\u1EF6\u1EF8\u1EFA\u1EFC\u1EFE\u1F08-\u1F0F\u1F18-\u1F1D\u1F28-\u1F2F\u1F38-\u1F3F\u1F48-\u1F4D\u1F59\u1F5B\u1F5D\u1F5F\u1F68-\u1F6F\u1FB8-\u1FBB\u1FC8-\u1FCB\u1FD8-\u1FDB\u1FE8-\u1FEC\u1FF8-\u1FFB\u2102\u2107\u210B-\u210D\u2110-\u2112\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u2130-\u2133\u213E-\u213F\u2145\u2183\u2C00-\u2C2E\u2C60\u2C62-\u2C64\u2C67\u2C69\u2C6B\u2C6D-\u2C70\u2C72\u2C75\u2C7E-\u2C80\u2C82\u2C84\u2C86\u2C88\u2C8A\u2C8C\u2C8E\u2C90\u2C92\u2C94\u2C96\u2C98\u2C9A\u2C9C\u2C9E\u2CA0\u2CA2\u2CA4\u2CA6\u2CA8\u2CAA\u2CAC\u2CAE\u2CB0\u2CB2\u2CB4\u2CB6\u2CB8\u2CBA\u2CBC\u2CBE\u2CC0\u2CC2\u2CC4\u2CC6\u2CC8\u2CCA\u2CCC\u2CCE\u2CD0\u2CD2\u2CD4\u2CD6\u2CD8\u2CDA\u2CDC\u2CDE\u2CE0\u2CE2\u2CEB\u2CED\u2CF2\uA640\uA642\uA644\uA646\uA648\uA64A\uA64C\uA64E\uA650\uA652\uA654\uA656\uA658\uA65A\uA65C\uA65E\uA660\uA662\uA664\uA666\uA668\uA66A\uA66C\uA680\uA682\uA684\uA686\uA688\uA68A\uA68C\uA68E\uA690\uA692\uA694\uA696\uA698\uA69A\uA722\uA724\uA726\uA728\uA72A\uA72C\uA72E\uA732\uA734\uA736\uA738\uA73A\uA73C\uA73E\uA740\uA742\uA744\uA746\uA748\uA74A\uA74C\uA74E\uA750\uA752\uA754\uA756\uA758\uA75A\uA75C\uA75E\uA760\uA762\uA764\uA766\uA768\uA76A\uA76C\uA76E\uA779\uA77B\uA77D-\uA77E\uA780\uA782\uA784\uA786\uA78B\uA78D\uA790\uA792\uA796\uA798\uA79A\uA79C\uA79E\uA7A0\uA7A2\uA7A4\uA7A6\uA7A8\uA7AA-\uA7AD\uA7B0-\uA7B4\uA7B6\uFF21-\uFF3A]
424438
425439 // Mark, Spacing Combining
426 Mc = [\u0903\u093E\u093F\u0940\u0949\u094A\u094B\u094C\u0982\u0983\u09BE\u09BF\u09C0\u09C7\u09C8\u09CB\u09CC\u09D7\u0A03\u0A3E\u0A3F\u0A40\u0A83\u0ABE\u0ABF\u0AC0\u0AC9\u0ACB\u0ACC\u0B02\u0B03\u0B3E\u0B40\u0B47\u0B48\u0B4B\u0B4C\u0B57\u0BBE\u0BBF\u0BC1\u0BC2\u0BC6\u0BC7\u0BC8\u0BCA\u0BCB\u0BCC\u0BD7\u0C01\u0C02\u0C03\u0C41\u0C42\u0C43\u0C44\u0C82\u0C83\u0CBE\u0CC0\u0CC1\u0CC2\u0CC3\u0CC4\u0CC7\u0CC8\u0CCA\u0CCB\u0CD5\u0CD6\u0D02\u0D03\u0D3E\u0D3F\u0D40\u0D46\u0D47\u0D48\u0D4A\u0D4B\u0D4C\u0D57\u0D82\u0D83\u0DCF\u0DD0\u0DD1\u0DD8\u0DD9\u0DDA\u0DDB\u0DDC\u0DDD\u0DDE\u0DDF\u0DF2\u0DF3\u0F3E\u0F3F\u0F7F\u102B\u102C\u1031\u1038\u103B\u103C\u1056\u1057\u1062\u1063\u1064\u1067\u1068\u1069\u106A\u106B\u106C\u106D\u1083\u1084\u1087\u1088\u1089\u108A\u108B\u108C\u108F\u17B6\u17BE\u17BF\u17C0\u17C1\u17C2\u17C3\u17C4\u17C5\u17C7\u17C8\u1923\u1924\u1925\u1926\u1929\u192A\u192B\u1930\u1931\u1933\u1934\u1935\u1936\u1937\u1938\u19B0\u19B1\u19B2\u19B3\u19B4\u19B5\u19B6\u19B7\u19B8\u19B9\u19BA\u19BB\u19BC\u19BD\u19BE\u19BF\u19C0\u19C8\u19C9\u1A19\u1A1A\u1A1B\u1B04\u1B35\u1B3B\u1B3D\u1B3E\u1B3F\u1B40\u1B41\u1B43\u1B44\u1B82\u1BA1\u1BA6\u1BA7\u1BAA\u1C24\u1C25\u1C26\u1C27\u1C28\u1C29\u1C2A\u1C2B\u1C34\u1C35\uA823\uA824\uA827\uA880\uA881\uA8B4\uA8B5\uA8B6\uA8B7\uA8B8\uA8B9\uA8BA\uA8BB\uA8BC\uA8BD\uA8BE\uA8BF\uA8C0\uA8C1\uA8C2\uA8C3\uA952\uA953\uAA2F\uAA30\uAA33\uAA34\uAA4D]
440 Mc = [\u0903\u093B\u093E-\u0940\u0949-\u094C\u094E-\u094F\u0982-\u0983\u09BE-\u09C0\u09C7-\u09C8\u09CB-\u09CC\u09D7\u0A03\u0A3E-\u0A40\u0A83\u0ABE-\u0AC0\u0AC9\u0ACB-\u0ACC\u0B02-\u0B03\u0B3E\u0B40\u0B47-\u0B48\u0B4B-\u0B4C\u0B57\u0BBE-\u0BBF\u0BC1-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCC\u0BD7\u0C01-\u0C03\u0C41-\u0C44\u0C82-\u0C83\u0CBE\u0CC0-\u0CC4\u0CC7-\u0CC8\u0CCA-\u0CCB\u0CD5-\u0CD6\u0D02-\u0D03\u0D3E-\u0D40\u0D46-\u0D48\u0D4A-\u0D4C\u0D57\u0D82-\u0D83\u0DCF-\u0DD1\u0DD8-\u0DDF\u0DF2-\u0DF3\u0F3E-\u0F3F\u0F7F\u102B-\u102C\u1031\u1038\u103B-\u103C\u1056-\u1057\u1062-\u1064\u1067-\u106D\u1083-\u1084\u1087-\u108C\u108F\u109A-\u109C\u17B6\u17BE-\u17C5\u17C7-\u17C8\u1923-\u1926\u1929-\u192B\u1930-\u1931\u1933-\u1938\u1A19-\u1A1A\u1A55\u1A57\u1A61\u1A63-\u1A64\u1A6D-\u1A72\u1B04\u1B35\u1B3B\u1B3D-\u1B41\u1B43-\u1B44\u1B82\u1BA1\u1BA6-\u1BA7\u1BAA\u1BE7\u1BEA-\u1BEC\u1BEE\u1BF2-\u1BF3\u1C24-\u1C2B\u1C34-\u1C35\u1CE1\u1CF2-\u1CF3\u302E-\u302F\uA823-\uA824\uA827\uA880-\uA881\uA8B4-\uA8C3\uA952-\uA953\uA983\uA9B4-\uA9B5\uA9BA-\uA9BB\uA9BD-\uA9C0\uAA2F-\uAA30\uAA33-\uAA34\uAA4D\uAA7B\uAA7D\uAAEB\uAAEE-\uAAEF\uAAF5\uABE3-\uABE4\uABE6-\uABE7\uABE9-\uABEA\uABEC]
427441
428442 // Mark, Nonspacing
429 Mn = [\u0300\u0301\u0302\u0303\u0304\u0305\u0306\u0307\u0308\u0309\u030A\u030B\u030C\u030D\u030E\u030F\u0310\u0311\u0312\u0313\u0314\u0315\u0316\u0317\u0318\u0319\u031A\u031B\u031C\u031D\u031E\u031F\u0320\u0321\u0322\u0323\u0324\u0325\u0326\u0327\u0328\u0329\u032A\u032B\u032C\u032D\u032E\u032F\u0330\u0331\u0332\u0333\u0334\u0335\u0336\u0337\u0338\u0339\u033A\u033B\u033C\u033D\u033E\u033F\u0340\u0341\u0342\u0343\u0344\u0345\u0346\u0347\u0348\u0349\u034A\u034B\u034C\u034D\u034E\u034F\u0350\u0351\u0352\u0353\u0354\u0355\u0356\u0357\u0358\u0359\u035A\u035B\u035C\u035D\u035E\u035F\u0360\u0361\u0362\u0363\u0364\u0365\u0366\u0367\u0368\u0369\u036A\u036B\u036C\u036D\u036E\u036F\u0483\u0484\u0485\u0486\u0487\u0591\u0592\u0593\u0594\u0595\u0596\u0597\u0598\u0599\u059A\u059B\u059C\u059D\u059E\u059F\u05A0\u05A1\u05A2\u05A3\u05A4\u05A5\u05A6\u05A7\u05A8\u05A9\u05AA\u05AB\u05AC\u05AD\u05AE\u05AF\u05B0\u05B1\u05B2\u05B3\u05B4\u05B5\u05B6\u05B7\u05B8\u05B9\u05BA\u05BB\u05BC\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610\u0611\u0612\u0613\u0614\u0615\u0616\u0617\u0618\u0619\u061A\u064B\u064C\u064D\u064E\u064F\u0650\u0651\u0652\u0653\u0654\u0655\u0656\u0657\u0658\u0659\u065A\u065B\u065C\u065D\u065E\u0670\u06D6\u06D7\u06D8\u06D9\u06DA\u06DB\u06DC\u06DF\u06E0\u06E1\u06E2\u06E3\u06E4\u06E7\u06E8\u06EA\u06EB\u06EC\u06ED\u0711\u0730\u0731\u0732\u0733\u0734\u0735\u0736\u0737\u0738\u0739\u073A\u073B\u073C\u073D\u073E\u073F\u0740\u0741\u0742\u0743\u0744\u0745\u0746\u0747\u0748\u0749\u074A\u07A6\u07A7\u07A8\u07A9\u07AA\u07AB\u07AC\u07AD\u07AE\u07AF\u07B0\u07EB\u07EC\u07ED\u07EE\u07EF\u07F0\u07F1\u07F2\u07F3\u0901\u0902\u093C\u0941\u0942\u0943\u0944\u0945\u0946\u0947\u0948\u094D\u0951\u0952\u0953\u0954\u0962\u0963\u0981\u09BC\u09C1\u09C2\u09C3\u09C4\u09CD\u09E2\u09E3\u0A01\u0A02\u0A3C\u0A41\u0A42\u0A47\u0A48\u0A4B\u0A4C\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81\u0A82\u0ABC\u0AC1\u0AC2\u0AC3\u0AC4\u0AC5\u0AC7\u0AC8\u0ACD\u0AE2\u0AE3\u0B01\u0B3C\u0B3F\u0B41\u0B42\u0B43\u0B44\u0B4D\u0B56\u0B62\u0B63\u0B82\u0BC0\u0BCD\u0C3E\u0C3F\u0C40\u0C46\u0C47\u0C48\u0C4A\u0C4B\u0C4C\u0C4D\u0C55\u0C56\u0C62\u0C63\u0CBC\u0CBF\u0CC6\u0CCC\u0CCD\u0CE2\u0CE3\u0D41\u0D42\u0D43\u0D44\u0D4D\u0D62\u0D63\u0DCA\u0DD2\u0DD3\u0DD4\u0DD6\u0E31\u0E34\u0E35\u0E36\u0E37\u0E38\u0E39\u0E3A\u0E47\u0E48\u0E49\u0E4A\u0E4B\u0E4C\u0E4D\u0E4E\u0EB1\u0EB4\u0EB5\u0EB6\u0EB7\u0EB8\u0EB9\u0EBB\u0EBC\u0EC8\u0EC9\u0ECA\u0ECB\u0ECC\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F71\u0F72\u0F73\u0F74\u0F75\u0F76\u0F77\u0F78\u0F79\u0F7A\u0F7B\u0F7C\u0F7D\u0F7E\u0F80\u0F81\u0F82\u0F83\u0F84\u0F86\u0F87\u0F90\u0F91\u0F92\u0F93\u0F94\u0F95\u0F96\u0F97\u0F99\u0F9A\u0F9B\u0F9C\u0F9D\u0F9E\u0F9F\u0FA0\u0FA1\u0FA2\u0FA3\u0FA4\u0FA5\u0FA6\u0FA7\u0FA8\u0FA9\u0FAA\u0FAB\u0FAC\u0FAD\u0FAE\u0FAF\u0FB0\u0FB1\u0FB2\u0FB3\u0FB4\u0FB5\u0FB6\u0FB7\u0FB8\u0FB9\u0FBA\u0FBB\u0FBC\u0FC6\u102D\u102E\u102F\u1030\u1032\u1033\u1034\u1035\u1036\u1037\u1039\u103A\u103D\u103E\u1058\u1059\u105E\u105F\u1060\u1071\u1072\u1073\u1074\u1082\u1085\u1086\u108D\u135F\u1712\u1713\u1714\u1732\u1733\u1734\u1752\u1753\u1772\u1773\u17B7\u17B8\u17B9\u17BA\u17BB\u17BC\u17BD\u17C6\u17C9\u17CA\u17CB\u17CC\u17CD\u17CE\u17CF\u17D0\u17D1\u17D2\u17D3\u17DD\u180B\u180C\u180D\u18A9\u1920\u1921\u1922\u1927\u1928\u1932\u1939\u193A\u193B\u1A17\u1A18\u1B00\u1B01\u1B02\u1B03\u1B34\u1B36\u1B37\u1B38\u1B39\u1B3A\u1B3C\u1B42\u1B6B\u1B6C\u1B6D\u1B6E\u1B6F\u1B70\u1B71\u1B72\u1B73\u1B80\u1B81\u1BA2\u1BA3\u1BA4\u1BA5\u1BA8\u1BA9\u1C2C\u1C2D\u1C2E\u1C2F\u1C30\u1C31\u1C32\u1C33\u1C36\u1C37\u1DC0\u1DC1\u1DC2\u1DC3\u1DC4\u1DC5\u1DC6\u1DC7\u1DC8\u1DC9\u1DCA\u1DCB\u1DCC\u1DCD\u1DCE\u1DCF\u1DD0\u1DD1\u1DD2\u1DD3\u1DD4\u1DD5\u1DD6\u1DD7\u1DD8\u1DD9\u1DDA\u1DDB\u1DDC\u1DDD\u1DDE\u1DDF\u1DE0\u1DE1\u1DE2\u1DE3\u1DE4\u1DE5\u1DE6\u1DFE\u1DFF\u20D0\u20D1\u20D2\u20D3\u20D4\u20D5\u20D6\u20D7\u20D8\u20D9\u20DA\u20DB\u20DC\u20E1\u20E5\u20E6\u20E7\u20E8\u20E9\u20EA\u20EB\u20EC\u20ED\u20EE\u20EF\u20F0\u2DE0\u2DE1\u2DE2\u2DE3\u2DE4\u2DE5\u2DE6\u2DE7\u2DE8\u2DE9\u2DEA\u2DEB\u2DEC\u2DED\u2DEE\u2DEF\u2DF0\u2DF1\u2DF2\u2DF3\u2DF4\u2DF5\u2DF6\u2DF7\u2DF8\u2DF9\u2DFA\u2DFB\u2DFC\u2DFD\u2DFE\u2DFF\u302A\u302B\u302C\u302D\u302E\u302F\u3099\u309A\uA66F\uA67C\uA67D\uA802\uA806\uA80B\uA825\uA826\uA8C4\uA926\uA927\uA928\uA929\uA92A\uA92B\uA92C\uA92D\uA947\uA948\uA949\uA94A\uA94B\uA94C\uA94D\uA94E\uA94F\uA950\uA951\uAA29\uAA2A\uAA2B\uAA2C\uAA2D\uAA2E\uAA31\uAA32\uAA35\uAA36\uAA43\uAA4C\uFB1E\uFE00\uFE01\uFE02\uFE03\uFE04\uFE05\uFE06\uFE07\uFE08\uFE09\uFE0A\uFE0B\uFE0C\uFE0D\uFE0E\uFE0F\uFE20\uFE21\uFE22\uFE23\uFE24\uFE25\uFE26]
443 Mn = [\u0300-\u036F\u0483-\u0487\u0591-\u05BD\u05BF\u05C1-\u05C2\u05C4-\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7-\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08E3-\u0902\u093A\u093C\u0941-\u0948\u094D\u0951-\u0957\u0962-\u0963\u0981\u09BC\u09C1-\u09C4\u09CD\u09E2-\u09E3\u0A01-\u0A02\u0A3C\u0A41-\u0A42\u0A47-\u0A48\u0A4B-\u0A4D\u0A51\u0A70-\u0A71\u0A75\u0A81-\u0A82\u0ABC\u0AC1-\u0AC5\u0AC7-\u0AC8\u0ACD\u0AE2-\u0AE3\u0B01\u0B3C\u0B3F\u0B41-\u0B44\u0B4D\u0B56\u0B62-\u0B63\u0B82\u0BC0\u0BCD\u0C00\u0C3E-\u0C40\u0C46-\u0C48\u0C4A-\u0C4D\u0C55-\u0C56\u0C62-\u0C63\u0C81\u0CBC\u0CBF\u0CC6\u0CCC-\u0CCD\u0CE2-\u0CE3\u0D01\u0D41-\u0D44\u0D4D\u0D62-\u0D63\u0DCA\u0DD2-\u0DD4\u0DD6\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB-\u0EBC\u0EC8-\u0ECD\u0F18-\u0F19\u0F35\u0F37\u0F39\u0F71-\u0F7E\u0F80-\u0F84\u0F86-\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102D-\u1030\u1032-\u1037\u1039-\u103A\u103D-\u103E\u1058-\u1059\u105E-\u1060\u1071-\u1074\u1082\u1085-\u1086\u108D\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752-\u1753\u1772-\u1773\u17B4-\u17B5\u17B7-\u17BD\u17C6\u17C9-\u17D3\u17DD\u180B-\u180D\u18A9\u1920-\u1922\u1927-\u1928\u1932\u1939-\u193B\u1A17-\u1A18\u1A1B\u1A56\u1A58-\u1A5E\u1A60\u1A62\u1A65-\u1A6C\u1A73-\u1A7C\u1A7F\u1AB0-\u1ABD\u1B00-\u1B03\u1B34\u1B36-\u1B3A\u1B3C\u1B42\u1B6B-\u1B73\u1B80-\u1B81\u1BA2-\u1BA5\u1BA8-\u1BA9\u1BAB-\u1BAD\u1BE6\u1BE8-\u1BE9\u1BED\u1BEF-\u1BF1\u1C2C-\u1C33\u1C36-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE0\u1CE2-\u1CE8\u1CED\u1CF4\u1CF8-\u1CF9\u1DC0-\u1DF5\u1DFC-\u1DFF\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302D\u3099-\u309A\uA66F\uA674-\uA67D\uA69E-\uA69F\uA6F0-\uA6F1\uA802\uA806\uA80B\uA825-\uA826\uA8C4\uA8E0-\uA8F1\uA926-\uA92D\uA947-\uA951\uA980-\uA982\uA9B3\uA9B6-\uA9B9\uA9BC\uA9E5\uAA29-\uAA2E\uAA31-\uAA32\uAA35-\uAA36\uAA43\uAA4C\uAA7C\uAAB0\uAAB2-\uAAB4\uAAB7-\uAAB8\uAABE-\uAABF\uAAC1\uAAEC-\uAAED\uAAF6\uABE5\uABE8\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2F]
430444
431445 // Number, Decimal Digit
432 Nd = [\u0030\u0031\u0032\u0033\u0034\u0035\u0036\u0037\u0038\u0039\u0660\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669\u06F0\u06F1\u06F2\u06F3\u06F4\u06F5\u06F6\u06F7\u06F8\u06F9\u07C0\u07C1\u07C2\u07C3\u07C4\u07C5\u07C6\u07C7\u07C8\u07C9\u0966\u0967\u0968\u0969\u096A\u096B\u096C\u096D\u096E\u096F\u09E6\u09E7\u09E8\u09E9\u09EA\u09EB\u09EC\u09ED\u09EE\u09EF\u0A66\u0A67\u0A68\u0A69\u0A6A\u0A6B\u0A6C\u0A6D\u0A6E\u0A6F\u0AE6\u0AE7\u0AE8\u0AE9\u0AEA\u0AEB\u0AEC\u0AED\u0AEE\u0AEF\u0B66\u0B67\u0B68\u0B69\u0B6A\u0B6B\u0B6C\u0B6D\u0B6E\u0B6F\u0BE6\u0BE7\u0BE8\u0BE9\u0BEA\u0BEB\u0BEC\u0BED\u0BEE\u0BEF\u0C66\u0C67\u0C68\u0C69\u0C6A\u0C6B\u0C6C\u0C6D\u0C6E\u0C6F\u0CE6\u0CE7\u0CE8\u0CE9\u0CEA\u0CEB\u0CEC\u0CED\u0CEE\u0CEF\u0D66\u0D67\u0D68\u0D69\u0D6A\u0D6B\u0D6C\u0D6D\u0D6E\u0D6F\u0E50\u0E51\u0E52\u0E53\u0E54\u0E55\u0E56\u0E57\u0E58\u0E59\u0ED0\u0ED1\u0ED2\u0ED3\u0ED4\u0ED5\u0ED6\u0ED7\u0ED8\u0ED9\u0F20\u0F21\u0F22\u0F23\u0F24\u0F25\u0F26\u0F27\u0F28\u0F29\u1040\u1041\u1042\u1043\u1044\u1045\u1046\u1047\u1048\u1049\u1090\u1091\u1092\u1093\u1094\u1095\u1096\u1097\u1098\u1099\u17E0\u17E1\u17E2\u17E3\u17E4\u17E5\u17E6\u17E7\u17E8\u17E9\u1810\u1811\u1812\u1813\u1814\u1815\u1816\u1817\u1818\u1819\u1946\u1947\u1948\u1949\u194A\u194B\u194C\u194D\u194E\u194F\u19D0\u19D1\u19D2\u19D3\u19D4\u19D5\u19D6\u19D7\u19D8\u19D9\u1B50\u1B51\u1B52\u1B53\u1B54\u1B55\u1B56\u1B57\u1B58\u1B59\u1BB0\u1BB1\u1BB2\u1BB3\u1BB4\u1BB5\u1BB6\u1BB7\u1BB8\u1BB9\u1C40\u1C41\u1C42\u1C43\u1C44\u1C45\u1C46\u1C47\u1C48\u1C49\u1C50\u1C51\u1C52\u1C53\u1C54\u1C55\u1C56\u1C57\u1C58\u1C59\uA620\uA621\uA622\uA623\uA624\uA625\uA626\uA627\uA628\uA629\uA8D0\uA8D1\uA8D2\uA8D3\uA8D4\uA8D5\uA8D6\uA8D7\uA8D8\uA8D9\uA900\uA901\uA902\uA903\uA904\uA905\uA906\uA907\uA908\uA909\uAA50\uAA51\uAA52\uAA53\uAA54\uAA55\uAA56\uAA57\uAA58\uAA59\uFF10\uFF11\uFF12\uFF13\uFF14\uFF15\uFF16\uFF17\uFF18\uFF19]
446 Nd = [\u0030-\u0039\u0660-\u0669\u06F0-\u06F9\u07C0-\u07C9\u0966-\u096F\u09E6-\u09EF\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0BE6-\u0BEF\u0C66-\u0C6F\u0CE6-\u0CEF\u0D66-\u0D6F\u0DE6-\u0DEF\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F29\u1040-\u1049\u1090-\u1099\u17E0-\u17E9\u1810-\u1819\u1946-\u194F\u19D0-\u19D9\u1A80-\u1A89\u1A90-\u1A99\u1B50-\u1B59\u1BB0-\u1BB9\u1C40-\u1C49\u1C50-\u1C59\uA620-\uA629\uA8D0-\uA8D9\uA900-\uA909\uA9D0-\uA9D9\uA9F0-\uA9F9\uAA50-\uAA59\uABF0-\uABF9\uFF10-\uFF19]
433447
434448 // Number, Letter
435 Nl = [\u16EE\u16EF\u16F0\u2160\u2161\u2162\u2163\u2164\u2165\u2166\u2167\u2168\u2169\u216A\u216B\u216C\u216D\u216E\u216F\u2170\u2171\u2172\u2173\u2174\u2175\u2176\u2177\u2178\u2179\u217A\u217B\u217C\u217D\u217E\u217F\u2180\u2181\u2182\u2185\u2186\u2187\u2188\u3007\u3021\u3022\u3023\u3024\u3025\u3026\u3027\u3028\u3029\u3038\u3039\u303A]
449 Nl = [\u16EE-\u16F0\u2160-\u2182\u2185-\u2188\u3007\u3021-\u3029\u3038-\u303A\uA6E6-\uA6EF]
436450
437451 // Punctuation, Connector
438 Pc = [\u005F\u203F\u2040\u2054\uFE33\uFE34\uFE4D\uFE4E\uFE4F\uFF3F]
452 Pc = [\u005F\u203F-\u2040\u2054\uFE33-\uFE34\uFE4D-\uFE4F\uFF3F]
439453
440454 // Separator, Space
441 Zs = [\u0020\u00A0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000]
455 Zs = [\u0020\u00A0\u1680\u2000-\u200A\u202F\u205F\u3000]
456
457 /* Tokens */
458
459 BreakToken = "break" !IdentifierPart
460 CaseToken = "case" !IdentifierPart
461 CatchToken = "catch" !IdentifierPart
462 ClassToken = "class" !IdentifierPart
463 ConstToken = "const" !IdentifierPart
464 ContinueToken = "continue" !IdentifierPart
465 DebuggerToken = "debugger" !IdentifierPart
466 DefaultToken = "default" !IdentifierPart
467 DeleteToken = "delete" !IdentifierPart
468 DoToken = "do" !IdentifierPart
469 ElseToken = "else" !IdentifierPart
470 EnumToken = "enum" !IdentifierPart
471 ExportToken = "export" !IdentifierPart
472 ExtendsToken = "extends" !IdentifierPart
473 FalseToken = "false" !IdentifierPart
474 FinallyToken = "finally" !IdentifierPart
475 ForToken = "for" !IdentifierPart
476 FunctionToken = "function" !IdentifierPart
477 GetToken = "get" !IdentifierPart
478 IfToken = "if" !IdentifierPart
479 ImportToken = "import" !IdentifierPart
480 InstanceofToken = "instanceof" !IdentifierPart
481 InToken = "in" !IdentifierPart
482 NewToken = "new" !IdentifierPart
483 NullToken = "null" !IdentifierPart
484 ReturnToken = "return" !IdentifierPart
485 SetToken = "set" !IdentifierPart
486 SuperToken = "super" !IdentifierPart
487 SwitchToken = "switch" !IdentifierPart
488 ThisToken = "this" !IdentifierPart
489 ThrowToken = "throw" !IdentifierPart
490 TrueToken = "true" !IdentifierPart
491 TryToken = "try" !IdentifierPart
492 TypeofToken = "typeof" !IdentifierPart
493 VarToken = "var" !IdentifierPart
494 VoidToken = "void" !IdentifierPart
495 WhileToken = "while" !IdentifierPart
496 WithToken = "with" !IdentifierPart
497
498 /* Skipped */
499
500 __
501 = (WhiteSpace / LineTerminatorSequence / Comment)*
502
503 _
504 = (WhiteSpace / MultiLineCommentNoLineTerminator)*
442505
443506 /* Automatic Semicolon Insertion */
444507
445508 EOS
446509 = __ ";"
447 / _ LineTerminatorSequence
510 / _ SingleLineComment? LineTerminatorSequence
448511 / _ &"}"
449512 / __ EOF
450513
451 EOSNoLineTerminator
452 = _ ";"
453 / _ LineTerminatorSequence
454 / _ &"}"
455 / _ EOF
456
457514 EOF
458515 = !.
459516
460 /* Whitespace */
461
462 _
463 = (WhiteSpace / MultiLineCommentNoLineTerminator / SingleLineComment)*
464
465 __
466 = (WhiteSpace / LineTerminatorSequence / Comment)*
467
468 /* ===== A.2 Number Conversions ===== */
469
470 /*
471 * Rules from this section are either unused or merged into previous section of
472 * the grammar.
473 */
474
475 /* ===== A.3 Expressions ===== */
517 /* ----- A.2 Number Conversions ----- */
518
519 /* Irrelevant. */
520
521 /* ----- A.3 Expressions ----- */
476522
477523 PrimaryExpression
478 = ThisToken { return { type: "This" }; }
479 / name:Identifier { return { type: "Variable", name: name }; }
524 = ThisToken { return { type: "ThisExpression" }; }
525 / Identifier
480526 / Literal
481527 / ArrayLiteral
482528 / ObjectLiteral
483529 / "(" __ expression:Expression __ ")" { return expression; }
484530
485531 ArrayLiteral
486 = "[" __ elements:ElementList? __ (Elision __)? "]" {
487 return {
488 type: "ArrayLiteral",
489 elements: elements !== "" ? elements : []
532 = "[" __ elision:(Elision __)? "]" {
533 return {
534 type: "ArrayExpression",
535 elements: optionalList(extractOptional(elision, 0))
536 };
537 }
538 / "[" __ elements:ElementList __ "]" {
539 return {
540 type: "ArrayExpression",
541 elements: elements
542 };
543 }
544 / "[" __ elements:ElementList __ "," __ elision:(Elision __)? "]" {
545 return {
546 type: "ArrayExpression",
547 elements: elements.concat(optionalList(extractOptional(elision, 0)))
490548 };
491549 }
492550
493551 ElementList
494 = (Elision __)?
495 head:AssignmentExpression
496 tail:(__ "," __ Elision? __ AssignmentExpression)* {
497 var result = [head];
498 for (var i = 0; i < tail.length; i++) {
499 result.push(tail[i][5]);
552 = head:(
553 elision:(Elision __)? element:AssignmentExpression {
554 return optionalList(extractOptional(elision, 0)).concat(element);
500555 }
501 return result;
502 }
556 )
557 tail:(
558 __ "," __ elision:(Elision __)? element:AssignmentExpression {
559 return optionalList(extractOptional(elision, 0)).concat(element);
560 }
561 )*
562 { return Array.prototype.concat.apply(head, tail); }
503563
504564 Elision
505 = "," (__ ",")*
565 = "," commas:(__ ",")* { return filledArray(commas.length + 1, null); }
506566
507567 ObjectLiteral
508 = "{" __ properties:(PropertyNameAndValueList __ ("," __)?)? "}" {
509 return {
510 type: "ObjectLiteral",
511 properties: properties !== "" ? properties[0] : []
512 };
513 }
514
568 = "{" __ "}" { return { type: "ObjectExpression", properties: [] }; }
569 / "{" __ properties:PropertyNameAndValueList __ "}" {
570 return { type: "ObjectExpression", properties: properties };
571 }
572 / "{" __ properties:PropertyNameAndValueList __ "," __ "}" {
573 return { type: "ObjectExpression", properties: properties };
574 }
515575 PropertyNameAndValueList
516576 = head:PropertyAssignment tail:(__ "," __ PropertyAssignment)* {
517 var result = [head];
518 for (var i = 0; i < tail.length; i++) {
519 result.push(tail[i][3]);
520 }
521 return result;
577 return buildList(head, tail, 3);
522578 }
523579
524580 PropertyAssignment
525 = name:PropertyName __ ":" __ value:AssignmentExpression {
526 return {
527 type: "PropertyAssignment",
528 name: name,
529 value: value
530 };
531 }
532 / GetToken __ name:PropertyName __
581 = key:PropertyName __ ":" __ value:AssignmentExpression {
582 return { key: key, value: value, kind: "init" };
583 }
584 / GetToken __ key:PropertyName __
533585 "(" __ ")" __
534 "{" __ body:FunctionBody __ "}" {
535 return {
536 type: "GetterDefinition",
537 name: name,
538 body: body
539 };
540 }
541 / SetToken __ name:PropertyName __
542 "(" __ param:PropertySetParameterList __ ")" __
543 "{" __ body:FunctionBody __ "}" {
544 return {
545 type: "SetterDefinition",
546 name: name,
547 param: param,
548 body: body
586 "{" __ body:FunctionBody __ "}"
587 {
588 return {
589 key: key,
590 value: {
591 type: "FunctionExpression",
592 id: null,
593 params: [],
594 body: body
595 },
596 kind: "get"
597 };
598 }
599 / SetToken __ key:PropertyName __
600 "(" __ params:PropertySetParameterList __ ")" __
601 "{" __ body:FunctionBody __ "}"
602 {
603 return {
604 key: key,
605 value: {
606 type: "FunctionExpression",
607 id: null,
608 params: params,
609 body: body
610 },
611 kind: "set"
549612 };
550613 }
551614
555618 / NumericLiteral
556619
557620 PropertySetParameterList
558 = Identifier
621 = id:Identifier { return [id]; }
559622
560623 MemberExpression
561 = base:(
624 = head:(
562625 PrimaryExpression
563626 / FunctionExpression
564 / NewToken __ constructor:MemberExpression __ arguments:Arguments {
627 / NewToken __ callee:MemberExpression __ args:Arguments {
628 return { type: "NewExpression", callee: callee, arguments: args };
629 }
630 )
631 tail:(
632 __ "[" __ property:Expression __ "]" {
633 return { property: property, computed: true };
634 }
635 / __ "." __ property:IdentifierName {
636 return { property: property, computed: false };
637 }
638 )*
639 {
640 return buildTree(head, tail, function(result, element) {
641 return {
642 type: "MemberExpression",
643 object: result,
644 property: element.property,
645 computed: element.computed
646 };
647 });
648 }
649
650 NewExpression
651 = MemberExpression
652 / NewToken __ callee:NewExpression {
653 return { type: "NewExpression", callee: callee, arguments: [] };
654 }
655
656 CallExpression
657 = head:(
658 callee:MemberExpression __ args:Arguments {
659 return { type: "CallExpression", callee: callee, arguments: args };
660 }
661 )
662 tail:(
663 __ args:Arguments {
664 return { type: "CallExpression", arguments: args };
665 }
666 / __ "[" __ property:Expression __ "]" {
565667 return {
566 type: "NewOperator",
567 constructor: constructor,
568 arguments: arguments
668 type: "MemberExpression",
669 property: property,
670 computed: true
569671 };
570672 }
571 )
572 accessors:(
573 __ "[" __ name:Expression __ "]" { return name; }
574 / __ "." __ name:IdentifierName { return name; }
575 )* {
576 var result = base;
577 for (var i = 0; i < accessors.length; i++) {
578 result = {
579 type: "PropertyAccess",
580 base: result,
581 name: accessors[i]
582 };
583 }
584 return result;
585 }
586
587 NewExpression
588 = MemberExpression
589 / NewToken __ constructor:NewExpression {
590 return {
591 type: "NewOperator",
592 constructor: constructor,
593 arguments: []
594 };
595 }
596
597 CallExpression
598 = base:(
599 name:MemberExpression __ arguments:Arguments {
600 return {
601 type: "FunctionCall",
602 name: name,
603 arguments: arguments
604 };
605 }
606 )
607 argumentsOrAccessors:(
608 __ arguments:Arguments {
673 / __ "." __ property:IdentifierName {
609674 return {
610 type: "FunctionCallArguments",
611 arguments: arguments
675 type: "MemberExpression",
676 property: property,
677 computed: false
612678 };
613679 }
614 / __ "[" __ name:Expression __ "]" {
615 return {
616 type: "PropertyAccessProperty",
617 name: name
618 };
619 }
620 / __ "." __ name:IdentifierName {
621 return {
622 type: "PropertyAccessProperty",
623 name: name
624 };
625 }
626 )* {
627 var result = base;
628 for (var i = 0; i < argumentsOrAccessors.length; i++) {
629 switch (argumentsOrAccessors[i].type) {
630 case "FunctionCallArguments":
631 result = {
632 type: "FunctionCall",
633 name: result,
634 arguments: argumentsOrAccessors[i].arguments
635 };
636 break;
637 case "PropertyAccessProperty":
638 result = {
639 type: "PropertyAccess",
640 base: result,
641 name: argumentsOrAccessors[i].name
642 };
643 break;
644 default:
645 throw new Error(
646 "Invalid expression type: " + argumentsOrAccessors[i].type
647 );
648 }
649 }
650 return result;
680 )*
681 {
682 return buildTree(head, tail, function(result, element) {
683 element[TYPES_TO_PROPERTY_NAMES[element.type]] = result;
684
685 return element;
686 });
651687 }
652688
653689 Arguments
654 = "(" __ arguments:ArgumentList? __ ")" {
655 return arguments !== "" ? arguments : [];
656 }
690 = "(" __ args:(ArgumentList __)? ")" {
691 return optionalList(extractOptional(args, 0));
692 }
657693
658694 ArgumentList
659695 = head:AssignmentExpression tail:(__ "," __ AssignmentExpression)* {
660 var result = [head];
661 for (var i = 0; i < tail.length; i++) {
662 result.push(tail[i][3]);
663 }
664 return result;
665 }
696 return buildList(head, tail, 3);
697 }
666698
667699 LeftHandSideExpression
668700 = CallExpression
669701 / NewExpression
670702
671703 PostfixExpression
672 = expression:LeftHandSideExpression _ operator:PostfixOperator {
673 return {
674 type: "PostfixExpression",
675 operator: operator,
676 expression: expression
704 = argument:LeftHandSideExpression _ operator:PostfixOperator {
705 return {
706 type: "UpdateExpression",
707 operator: operator,
708 argument: argument,
709 prefix: false
677710 };
678711 }
679712 / LeftHandSideExpression
684717
685718 UnaryExpression
686719 = PostfixExpression
687 / operator:UnaryOperator __ expression:UnaryExpression {
688 return {
689 type: "UnaryExpression",
690 operator: operator,
691 expression: expression
720 / operator:UnaryOperator __ argument:UnaryExpression {
721 var type = (operator === "++" || operator === "--")
722 ? "UpdateExpression"
723 : "UnaryExpression";
724
725 return {
726 type: type,
727 operator: operator,
728 argument: argument,
729 prefix: true
692730 };
693731 }
694732
695733 UnaryOperator
696 = DeleteToken
697 / VoidToken
698 / TypeofToken
734 = $DeleteToken
735 / $VoidToken
736 / $TypeofToken
699737 / "++"
700738 / "--"
701 / "+"
702 / "-"
739 / $("+" !"=")
740 / $("-" !"=")
703741 / "~"
704 / "!"
742 / "!"
705743
706744 MultiplicativeExpression
707745 = head:UnaryExpression
708 tail:(__ MultiplicativeOperator __ UnaryExpression)* {
709 var result = head;
710 for (var i = 0; i < tail.length; i++) {
711 result = {
712 type: "BinaryExpression",
713 operator: tail[i][1],
714 left: result,
715 right: tail[i][3]
716 };
717 }
718 return result;
719 }
746 tail:(__ MultiplicativeOperator __ UnaryExpression)*
747 { return buildBinaryExpression(head, tail); }
720748
721749 MultiplicativeOperator
722 = operator:("*" / "/" / "%") !"=" { return operator; }
750 = $("*" !"=")
751 / $("/" !"=")
752 / $("%" !"=")
723753
724754 AdditiveExpression
725755 = head:MultiplicativeExpression
726 tail:(__ AdditiveOperator __ MultiplicativeExpression)* {
727 var result = head;
728 for (var i = 0; i < tail.length; i++) {
729 result = {
730 type: "BinaryExpression",
731 operator: tail[i][1],
732 left: result,
733 right: tail[i][3]
734 };
735 }
736 return result;
737 }
756 tail:(__ AdditiveOperator __ MultiplicativeExpression)*
757 { return buildBinaryExpression(head, tail); }
738758
739759 AdditiveOperator
740 = "+" !("+" / "=") { return "+"; }
741 / "-" !("-" / "=") { return "-"; }
760 = $("+" ![+=])
761 / $("-" ![-=])
742762
743763 ShiftExpression
744764 = head:AdditiveExpression
745 tail:(__ ShiftOperator __ AdditiveExpression)* {
746 var result = head;
747 for (var i = 0; i < tail.length; i++) {
748 result = {
749 type: "BinaryExpression",
750 operator: tail[i][1],
751 left: result,
752 right: tail[i][3]
753 };
754 }
755 return result;
756 }
765 tail:(__ ShiftOperator __ AdditiveExpression)*
766 { return buildBinaryExpression(head, tail); }
757767
758768 ShiftOperator
759 = "<<"
760 / ">>>"
761 / ">>"
769 = $("<<" !"=")
770 / $(">>>" !"=")
771 / $(">>" !"=")
762772
763773 RelationalExpression
764774 = head:ShiftExpression
765 tail:(__ RelationalOperator __ ShiftExpression)* {
766 var result = head;
767 for (var i = 0; i < tail.length; i++) {
768 result = {
769 type: "BinaryExpression",
770 operator: tail[i][1],
771 left: result,
772 right: tail[i][3]
773 };
774 }
775 return result;
776 }
775 tail:(__ RelationalOperator __ ShiftExpression)*
776 { return buildBinaryExpression(head, tail); }
777777
778778 RelationalOperator
779779 = "<="
780780 / ">="
781 / "<"
782 / ">"
783 / InstanceofToken
784 / InToken
781 / $("<" !"<")
782 / $(">" !">")
783 / $InstanceofToken
784 / $InToken
785785
786786 RelationalExpressionNoIn
787787 = head:ShiftExpression
788 tail:(__ RelationalOperatorNoIn __ ShiftExpression)* {
789 var result = head;
790 for (var i = 0; i < tail.length; i++) {
791 result = {
792 type: "BinaryExpression",
793 operator: tail[i][1],
794 left: result,
795 right: tail[i][3]
796 };
797 }
798 return result;
799 }
788 tail:(__ RelationalOperatorNoIn __ ShiftExpression)*
789 { return buildBinaryExpression(head, tail); }
800790
801791 RelationalOperatorNoIn
802792 = "<="
803793 / ">="
804 / "<"
805 / ">"
806 / InstanceofToken
794 / $("<" !"<")
795 / $(">" !">")
796 / $InstanceofToken
807797
808798 EqualityExpression
809799 = head:RelationalExpression
810 tail:(__ EqualityOperator __ RelationalExpression)* {
811 var result = head;
812 for (var i = 0; i < tail.length; i++) {
813 result = {
814 type: "BinaryExpression",
815 operator: tail[i][1],
816 left: result,
817 right: tail[i][3]
818 };
819 }
820 return result;
821 }
800 tail:(__ EqualityOperator __ RelationalExpression)*
801 { return buildBinaryExpression(head, tail); }
822802
823803 EqualityExpressionNoIn
824804 = head:RelationalExpressionNoIn
825 tail:(__ EqualityOperator __ RelationalExpressionNoIn)* {
826 var result = head;
827 for (var i = 0; i < tail.length; i++) {
828 result = {
829 type: "BinaryExpression",
830 operator: tail[i][1],
831 left: result,
832 right: tail[i][3]
833 };
834 }
835 return result;
836 }
805 tail:(__ EqualityOperator __ RelationalExpressionNoIn)*
806 { return buildBinaryExpression(head, tail); }
837807
838808 EqualityOperator
839809 = "==="
843813
844814 BitwiseANDExpression
845815 = head:EqualityExpression
846 tail:(__ BitwiseANDOperator __ EqualityExpression)* {
847 var result = head;
848 for (var i = 0; i < tail.length; i++) {
849 result = {
850 type: "BinaryExpression",
851 operator: tail[i][1],
852 left: result,
853 right: tail[i][3]
854 };
855 }
856 return result;
857 }
816 tail:(__ BitwiseANDOperator __ EqualityExpression)*
817 { return buildBinaryExpression(head, tail); }
858818
859819 BitwiseANDExpressionNoIn
860820 = head:EqualityExpressionNoIn
861 tail:(__ BitwiseANDOperator __ EqualityExpressionNoIn)* {
862 var result = head;
863 for (var i = 0; i < tail.length; i++) {
864 result = {
865 type: "BinaryExpression",
866 operator: tail[i][1],
867 left: result,
868 right: tail[i][3]
869 };
870 }
871 return result;
872 }
821 tail:(__ BitwiseANDOperator __ EqualityExpressionNoIn)*
822 { return buildBinaryExpression(head, tail); }
873823
874824 BitwiseANDOperator
875 = "&" !("&" / "=") { return "&"; }
825 = $("&" ![&=])
876826
877827 BitwiseXORExpression
878828 = head:BitwiseANDExpression
879 tail:(__ BitwiseXOROperator __ BitwiseANDExpression)* {
880 var result = head;
881 for (var i = 0; i < tail.length; i++) {
882 result = {
883 type: "BinaryExpression",
884 operator: tail[i][1],
885 left: result,
886 right: tail[i][3]
887 };
888 }
889 return result;
890 }
829 tail:(__ BitwiseXOROperator __ BitwiseANDExpression)*
830 { return buildBinaryExpression(head, tail); }
891831
892832 BitwiseXORExpressionNoIn
893833 = head:BitwiseANDExpressionNoIn
894 tail:(__ BitwiseXOROperator __ BitwiseANDExpressionNoIn)* {
895 var result = head;
896 for (var i = 0; i < tail.length; i++) {
897 result = {
898 type: "BinaryExpression",
899 operator: tail[i][1],
900 left: result,
901 right: tail[i][3]
902 };
903 }
904 return result;
905 }
834 tail:(__ BitwiseXOROperator __ BitwiseANDExpressionNoIn)*
835 { return buildBinaryExpression(head, tail); }
906836
907837 BitwiseXOROperator
908 = "^" !("^" / "=") { return "^"; }
838 = $("^" !"=")
909839
910840 BitwiseORExpression
911841 = head:BitwiseXORExpression
912 tail:(__ BitwiseOROperator __ BitwiseXORExpression)* {
913 var result = head;
914 for (var i = 0; i < tail.length; i++) {
915 result = {
916 type: "BinaryExpression",
917 operator: tail[i][1],
918 left: result,
919 right: tail[i][3]
920 };
921 }
922 return result;
923 }
842 tail:(__ BitwiseOROperator __ BitwiseXORExpression)*
843 { return buildBinaryExpression(head, tail); }
924844
925845 BitwiseORExpressionNoIn
926846 = head:BitwiseXORExpressionNoIn
927 tail:(__ BitwiseOROperator __ BitwiseXORExpressionNoIn)* {
928 var result = head;
929 for (var i = 0; i < tail.length; i++) {
930 result = {
931 type: "BinaryExpression",
932 operator: tail[i][1],
933 left: result,
934 right: tail[i][3]
935 };
936 }
937 return result;
938 }
847 tail:(__ BitwiseOROperator __ BitwiseXORExpressionNoIn)*
848 { return buildBinaryExpression(head, tail); }
939849
940850 BitwiseOROperator
941 = "|" !("|" / "=") { return "|"; }
851 = $("|" ![|=])
942852
943853 LogicalANDExpression
944854 = head:BitwiseORExpression
945 tail:(__ LogicalANDOperator __ BitwiseORExpression)* {
946 var result = head;
947 for (var i = 0; i < tail.length; i++) {
948 result = {
949 type: "BinaryExpression",
950 operator: tail[i][1],
951 left: result,
952 right: tail[i][3]
953 };
954 }
955 return result;
956 }
855 tail:(__ LogicalANDOperator __ BitwiseORExpression)*
856 { return buildBinaryExpression(head, tail); }
957857
958858 LogicalANDExpressionNoIn
959859 = head:BitwiseORExpressionNoIn
960 tail:(__ LogicalANDOperator __ BitwiseORExpressionNoIn)* {
961 var result = head;
962 for (var i = 0; i < tail.length; i++) {
963 result = {
964 type: "BinaryExpression",
965 operator: tail[i][1],
966 left: result,
967 right: tail[i][3]
968 };
969 }
970 return result;
971 }
860 tail:(__ LogicalANDOperator __ BitwiseORExpressionNoIn)*
861 { return buildBinaryExpression(head, tail); }
972862
973863 LogicalANDOperator
974 = "&&" !"=" { return "&&"; }
864 = "&&"
975865
976866 LogicalORExpression
977867 = head:LogicalANDExpression
978 tail:(__ LogicalOROperator __ LogicalANDExpression)* {
979 var result = head;
980 for (var i = 0; i < tail.length; i++) {
981 result = {
982 type: "BinaryExpression",
983 operator: tail[i][1],
984 left: result,
985 right: tail[i][3]
986 };
987 }
988 return result;
989 }
868 tail:(__ LogicalOROperator __ LogicalANDExpression)*
869 { return buildBinaryExpression(head, tail); }
990870
991871 LogicalORExpressionNoIn
992872 = head:LogicalANDExpressionNoIn
993 tail:(__ LogicalOROperator __ LogicalANDExpressionNoIn)* {
994 var result = head;
995 for (var i = 0; i < tail.length; i++) {
996 result = {
997 type: "BinaryExpression",
998 operator: tail[i][1],
999 left: result,
1000 right: tail[i][3]
1001 };
1002 }
1003 return result;
1004 }
873 tail:(__ LogicalOROperator __ LogicalANDExpressionNoIn)*
874 { return buildBinaryExpression(head, tail); }
1005875
1006876 LogicalOROperator
1007 = "||" !"=" { return "||"; }
877 = "||"
1008878
1009879 ConditionalExpression
1010 = condition:LogicalORExpression __
1011 "?" __ trueExpression:AssignmentExpression __
1012 ":" __ falseExpression:AssignmentExpression {
1013 return {
1014 type: "ConditionalExpression",
1015 condition: condition,
1016 trueExpression: trueExpression,
1017 falseExpression: falseExpression
880 = test:LogicalORExpression __
881 "?" __ consequent:AssignmentExpression __
882 ":" __ alternate:AssignmentExpression
883 {
884 return {
885 type: "ConditionalExpression",
886 test: test,
887 consequent: consequent,
888 alternate: alternate
1018889 };
1019890 }
1020891 / LogicalORExpression
1021892
1022893 ConditionalExpressionNoIn
1023 = condition:LogicalORExpressionNoIn __
1024 "?" __ trueExpression:AssignmentExpressionNoIn __
1025 ":" __ falseExpression:AssignmentExpressionNoIn {
1026 return {
1027 type: "ConditionalExpression",
1028 condition: condition,
1029 trueExpression: trueExpression,
1030 falseExpression: falseExpression
894 = test:LogicalORExpressionNoIn __
895 "?" __ consequent:AssignmentExpression __
896 ":" __ alternate:AssignmentExpressionNoIn
897 {
898 return {
899 type: "ConditionalExpression",
900 test: test,
901 consequent: consequent,
902 alternate: alternate
1031903 };
1032904 }
1033905 / LogicalORExpressionNoIn
1034906
1035907 AssignmentExpression
1036908 = left:LeftHandSideExpression __
909 "=" !"=" __
910 right:AssignmentExpression
911 {
912 return {
913 type: "AssignmentExpression",
914 operator: "=",
915 left: left,
916 right: right
917 };
918 }
919 / left:LeftHandSideExpression __
1037920 operator:AssignmentOperator __
1038 right:AssignmentExpression {
921 right:AssignmentExpression
922 {
1039923 return {
1040924 type: "AssignmentExpression",
1041925 operator: operator,
1047931
1048932 AssignmentExpressionNoIn
1049933 = left:LeftHandSideExpression __
934 "=" !"=" __
935 right:AssignmentExpressionNoIn
936 {
937 return {
938 type: "AssignmentExpression",
939 operator: "=",
940 left: left,
941 right: right
942 };
943 }
944 / left:LeftHandSideExpression __
1050945 operator:AssignmentOperator __
1051 right:AssignmentExpressionNoIn {
946 right:AssignmentExpressionNoIn
947 {
1052948 return {
1053949 type: "AssignmentExpression",
1054950 operator: operator,
1059955 / ConditionalExpressionNoIn
1060956
1061957 AssignmentOperator
1062 = "=" (!"=") { return "="; }
1063 / "*="
958 = "*="
1064959 / "/="
1065960 / "%="
1066961 / "+="
1073968 / "|="
1074969
1075970 Expression
1076 = head:AssignmentExpression
1077 tail:(__ "," __ AssignmentExpression)* {
1078 var result = head;
1079 for (var i = 0; i < tail.length; i++) {
1080 result = {
1081 type: "BinaryExpression",
1082 operator: tail[i][1],
1083 left: result,
1084 right: tail[i][3]
1085 };
1086 }
1087 return result;
971 = head:AssignmentExpression tail:(__ "," __ AssignmentExpression)* {
972 return tail.length > 0
973 ? { type: "SequenceExpression", expressions: buildList(head, tail, 3) }
974 : head;
1088975 }
1089976
1090977 ExpressionNoIn
1091 = head:AssignmentExpressionNoIn
1092 tail:(__ "," __ AssignmentExpressionNoIn)* {
1093 var result = head;
1094 for (var i = 0; i < tail.length; i++) {
1095 result = {
1096 type: "BinaryExpression",
1097 operator: tail[i][1],
1098 left: result,
1099 right: tail[i][3]
1100 };
1101 }
1102 return result;
1103 }
1104
1105 /* ===== A.4 Statements ===== */
1106
1107 /*
1108 * The specification does not consider |FunctionDeclaration| and
1109 * |FunctionExpression| as statements, but JavaScript implementations do and so
1110 * are we. This syntax is actually used in the wild (e.g. by jQuery).
1111 */
978 = head:AssignmentExpressionNoIn tail:(__ "," __ AssignmentExpressionNoIn)* {
979 return tail.length > 0
980 ? { type: "SequenceExpression", expressions: buildList(head, tail, 3) }
981 : head;
982 }
983
984 /* ----- A.4 Statements ----- */
985
1112986 Statement
1113987 = Block
1114988 / VariableStatement
1125999 / ThrowStatement
11261000 / TryStatement
11271001 / DebuggerStatement
1128 / FunctionDeclaration
1129 / FunctionExpression
11301002
11311003 Block
1132 = "{" __ statements:(StatementList __)? "}" {
1133 return {
1134 type: "Block",
1135 statements: statements !== "" ? statements[0] : []
1004 = "{" __ body:(StatementList __)? "}" {
1005 return {
1006 type: "BlockStatement",
1007 body: optionalList(extractOptional(body, 0))
11361008 };
11371009 }
11381010
11391011 StatementList
1140 = head:Statement tail:(__ Statement)* {
1141 var result = [head];
1142 for (var i = 0; i < tail.length; i++) {
1143 result.push(tail[i][1]);
1144 }
1145 return result;
1146 }
1012 = head:Statement tail:(__ Statement)* { return buildList(head, tail, 1); }
11471013
11481014 VariableStatement
11491015 = VarToken __ declarations:VariableDeclarationList EOS {
11501016 return {
1151 type: "VariableStatement",
1017 type: "VariableDeclaration",
11521018 declarations: declarations
11531019 };
11541020 }
11551021
11561022 VariableDeclarationList
11571023 = head:VariableDeclaration tail:(__ "," __ VariableDeclaration)* {
1158 var result = [head];
1159 for (var i = 0; i < tail.length; i++) {
1160 result.push(tail[i][3]);
1161 }
1162 return result;
1024 return buildList(head, tail, 3);
11631025 }
11641026
11651027 VariableDeclarationListNoIn
11661028 = head:VariableDeclarationNoIn tail:(__ "," __ VariableDeclarationNoIn)* {
1167 var result = [head];
1168 for (var i = 0; i < tail.length; i++) {
1169 result.push(tail[i][3]);
1170 }
1171 return result;
1029 return buildList(head, tail, 3);
11721030 }
11731031
11741032 VariableDeclaration
1175 = name:Identifier __ value:Initialiser? {
1176 return {
1177 type: "VariableDeclaration",
1178 name: name,
1179 value: value !== "" ? value : null
1033 = id:Identifier init:(__ Initialiser)? {
1034 return {
1035 type: "VariableDeclarator",
1036 id: id,
1037 init: extractOptional(init, 1)
11801038 };
11811039 }
11821040
11831041 VariableDeclarationNoIn
1184 = name:Identifier __ value:InitialiserNoIn? {
1185 return {
1186 type: "VariableDeclaration",
1187 name: name,
1188 value: value !== "" ? value : null
1042 = id:Identifier init:(__ InitialiserNoIn)? {
1043 return {
1044 type: "VariableDeclarator",
1045 id: id,
1046 init: extractOptional(init, 1)
11891047 };
11901048 }
11911049
11921050 Initialiser
1193 = "=" (!"=") __ expression:AssignmentExpression { return expression; }
1051 = "=" !"=" __ expression:AssignmentExpression { return expression; }
11941052
11951053 InitialiserNoIn
1196 = "=" (!"=") __ expression:AssignmentExpressionNoIn { return expression; }
1054 = "=" !"=" __ expression:AssignmentExpressionNoIn { return expression; }
11971055
11981056 EmptyStatement
11991057 = ";" { return { type: "EmptyStatement" }; }
12001058
12011059 ExpressionStatement
1202 = !("{" / FunctionToken) expression:Expression EOS { return expression; }
1060 = !("{" / FunctionToken) expression:Expression EOS {
1061 return {
1062 type: "ExpressionStatement",
1063 expression: expression
1064 };
1065 }
12031066
12041067 IfStatement
1205 = IfToken __
1206 "(" __ condition:Expression __ ")" __
1207 ifStatement:Statement
1208 elseStatement:(__ ElseToken __ Statement)? {
1209 return {
1210 type: "IfStatement",
1211 condition: condition,
1212 ifStatement: ifStatement,
1213 elseStatement: elseStatement !== "" ? elseStatement[3] : null
1068 = IfToken __ "(" __ test:Expression __ ")" __
1069 consequent:Statement __
1070 ElseToken __
1071 alternate:Statement
1072 {
1073 return {
1074 type: "IfStatement",
1075 test: test,
1076 consequent: consequent,
1077 alternate: alternate
1078 };
1079 }
1080 / IfToken __ "(" __ test:Expression __ ")" __
1081 consequent:Statement {
1082 return {
1083 type: "IfStatement",
1084 test: test,
1085 consequent: consequent,
1086 alternate: null
12141087 };
12151088 }
12161089
12171090 IterationStatement
1218 = DoWhileStatement
1219 / WhileStatement
1220 / ForStatement
1221 / ForInStatement
1222
1223 DoWhileStatement
12241091 = DoToken __
1225 statement:Statement __
1226 WhileToken __ "(" __ condition:Expression __ ")" EOS {
1227 return {
1228 type: "DoWhileStatement",
1229 condition: condition,
1230 statement: statement
1231 };
1232 }
1233
1234 WhileStatement
1235 = WhileToken __ "(" __ condition:Expression __ ")" __ statement:Statement {
1236 return {
1237 type: "WhileStatement",
1238 condition: condition,
1239 statement: statement
1240 };
1241 }
1242
1243 ForStatement
1244 = ForToken __
1092 body:Statement __
1093 WhileToken __ "(" __ test:Expression __ ")" EOS
1094 { return { type: "DoWhileStatement", body: body, test: test }; }
1095 / WhileToken __ "(" __ test:Expression __ ")" __
1096 body:Statement
1097 { return { type: "WhileStatement", test: test, body: body }; }
1098 / ForToken __
12451099 "(" __
1246 initializer:(
1247 VarToken __ declarations:VariableDeclarationListNoIn {
1248 return {
1249 type: "VariableStatement",
1250 declarations: declarations
1251 };
1252 }
1253 / ExpressionNoIn?
1254 ) __
1255 ";" __
1256 test:Expression? __
1257 ";" __
1258 counter:Expression? __
1100 init:(ExpressionNoIn __)? ";" __
1101 test:(Expression __)? ";" __
1102 update:(Expression __)?
12591103 ")" __
1260 statement:Statement
1261 {
1262 return {
1263 type: "ForStatement",
1264 initializer: initializer !== "" ? initializer : null,
1265 test: test !== "" ? test : null,
1266 counter: counter !== "" ? counter : null,
1267 statement: statement
1268 };
1269 }
1270
1271 ForInStatement
1272 = ForToken __
1104 body:Statement
1105 {
1106 return {
1107 type: "ForStatement",
1108 init: extractOptional(init, 0),
1109 test: extractOptional(test, 0),
1110 update: extractOptional(update, 0),
1111 body: body
1112 };
1113 }
1114 / ForToken __
12731115 "(" __
1274 iterator:(
1275 VarToken __ declaration:VariableDeclarationNoIn { return declaration; }
1276 / LeftHandSideExpression
1277 ) __
1116 VarToken __ declarations:VariableDeclarationListNoIn __ ";" __
1117 test:(Expression __)? ";" __
1118 update:(Expression __)?
1119 ")" __
1120 body:Statement
1121 {
1122 return {
1123 type: "ForStatement",
1124 init: {
1125 type: "VariableDeclaration",
1126 declarations: declarations
1127 },
1128 test: extractOptional(test, 0),
1129 update: extractOptional(update, 0),
1130 body: body
1131 };
1132 }
1133 / ForToken __
1134 "(" __
1135 left:LeftHandSideExpression __
12781136 InToken __
1279 collection:Expression __
1137 right:Expression __
12801138 ")" __
1281 statement:Statement
1282 {
1283 return {
1284 type: "ForInStatement",
1285 iterator: iterator,
1286 collection: collection,
1287 statement: statement
1139 body:Statement
1140 {
1141 return {
1142 type: "ForInStatement",
1143 left: left,
1144 right: right,
1145 body: body
1146 };
1147 }
1148 / ForToken __
1149 "(" __
1150 VarToken __ declarations:VariableDeclarationListNoIn __
1151 InToken __
1152 right:Expression __
1153 ")" __
1154 body:Statement
1155 {
1156 return {
1157 type: "ForInStatement",
1158 left: {
1159 type: "VariableDeclaration",
1160 declarations: declarations
1161 },
1162 right: right,
1163 body: body
12881164 };
12891165 }
12901166
12911167 ContinueStatement
1292 = ContinueToken _
1293 label:(
1294 identifier:Identifier EOS { return identifier; }
1295 / EOSNoLineTerminator { return ""; }
1296 ) {
1297 return {
1298 type: "ContinueStatement",
1299 label: label !== "" ? label : null
1300 };
1168 = ContinueToken EOS {
1169 return { type: "ContinueStatement", label: null };
1170 }
1171 / ContinueToken _ label:Identifier EOS {
1172 return { type: "ContinueStatement", label: label };
13011173 }
13021174
13031175 BreakStatement
1304 = BreakToken _
1305 label:(
1306 identifier:Identifier EOS { return identifier; }
1307 / EOSNoLineTerminator { return ""; }
1308 ) {
1309 return {
1310 type: "BreakStatement",
1311 label: label !== "" ? label : null
1312 };
1176 = BreakToken EOS {
1177 return { type: "BreakStatement", label: null };
1178 }
1179 / BreakToken _ label:Identifier EOS {
1180 return { type: "BreakStatement", label: label };
13131181 }
13141182
13151183 ReturnStatement
1316 = ReturnToken _
1317 value:(
1318 expression:Expression EOS { return expression; }
1319 / EOSNoLineTerminator { return ""; }
1320 ) {
1321 return {
1322 type: "ReturnStatement",
1323 value: value !== "" ? value : null
1324 };
1184 = ReturnToken EOS {
1185 return { type: "ReturnStatement", argument: null };
1186 }
1187 / ReturnToken _ argument:Expression EOS {
1188 return { type: "ReturnStatement", argument: argument };
13251189 }
13261190
13271191 WithStatement
1328 = WithToken __ "(" __ environment:Expression __ ")" __ statement:Statement {
1329 return {
1330 type: "WithStatement",
1331 environment: environment,
1332 statement: statement
1333 };
1334 }
1192 = WithToken __ "(" __ object:Expression __ ")" __
1193 body:Statement
1194 { return { type: "WithStatement", object: object, body: body }; }
13351195
13361196 SwitchStatement
1337 = SwitchToken __ "(" __ expression:Expression __ ")" __ clauses:CaseBlock {
1338 return {
1339 type: "SwitchStatement",
1340 expression: expression,
1341 clauses: clauses
1197 = SwitchToken __ "(" __ discriminant:Expression __ ")" __
1198 cases:CaseBlock
1199 {
1200 return {
1201 type: "SwitchStatement",
1202 discriminant: discriminant,
1203 cases: cases
13421204 };
13431205 }
13441206
13451207 CaseBlock
1346 = "{" __
1347 before:CaseClauses?
1348 defaultAndAfter:(__ DefaultClause __ CaseClauses?)? __
1349 "}" {
1350 var before = before !== "" ? before : [];
1351 if (defaultAndAfter !== "") {
1352 var defaultClause = defaultAndAfter[1];
1353 var clausesAfter = defaultAndAfter[3] !== ""
1354 ? defaultAndAfter[3]
1355 : [];
1356 } else {
1357 var defaultClause = null;
1358 var clausesAfter = [];
1359 }
1360
1361 return (defaultClause ? before.concat(defaultClause) : before).concat(clausesAfter);
1208 = "{" __ clauses:(CaseClauses __)? "}" {
1209 return optionalList(extractOptional(clauses, 0));
1210 }
1211 / "{" __
1212 before:(CaseClauses __)?
1213 default_:DefaultClause __
1214 after:(CaseClauses __)? "}"
1215 {
1216 return optionalList(extractOptional(before, 0))
1217 .concat(default_)
1218 .concat(optionalList(extractOptional(after, 0)));
13621219 }
13631220
13641221 CaseClauses
1365 = head:CaseClause tail:(__ CaseClause)* {
1366 var result = [head];
1367 for (var i = 0; i < tail.length; i++) {
1368 result.push(tail[i][1]);
1369 }
1370 return result;
1371 }
1222 = head:CaseClause tail:(__ CaseClause)* { return buildList(head, tail, 1); }
13721223
13731224 CaseClause
1374 = CaseToken __ selector:Expression __ ":" statements:(__ StatementList)? {
1375 return {
1376 type: "CaseClause",
1377 selector: selector,
1378 statements: statements !== "" ? statements[1] : []
1225 = CaseToken __ test:Expression __ ":" consequent:(__ StatementList)? {
1226 return {
1227 type: "SwitchCase",
1228 test: test,
1229 consequent: optionalList(extractOptional(consequent, 1))
13791230 };
13801231 }
13811232
13821233 DefaultClause
1383 = DefaultToken __ ":" statements:(__ StatementList)? {
1384 return {
1385 type: "DefaultClause",
1386 statements: statements !== "" ? statements[1] : []
1234 = DefaultToken __ ":" consequent:(__ StatementList)? {
1235 return {
1236 type: "SwitchCase",
1237 test: null,
1238 consequent: optionalList(extractOptional(consequent, 1))
13871239 };
13881240 }
13891241
13901242 LabelledStatement
1391 = label:Identifier __ ":" __ statement:Statement {
1392 return {
1393 type: "LabelledStatement",
1394 label: label,
1395 statement: statement
1396 };
1243 = label:Identifier __ ":" __ body:Statement {
1244 return { type: "LabeledStatement", label: label, body: body };
13971245 }
13981246
13991247 ThrowStatement
1400 = ThrowToken _ exception:Expression EOSNoLineTerminator {
1401 return {
1402 type: "ThrowStatement",
1403 exception: exception
1404 };
1248 = ThrowToken _ argument:Expression EOS {
1249 return { type: "ThrowStatement", argument: argument };
14051250 }
14061251
14071252 TryStatement
1408 = TryToken __ block:Block __ catch_:Catch __ finally_:Finally {
1253 = TryToken __ block:Block __ handler:Catch __ finalizer:Finally {
14091254 return {
14101255 type: "TryStatement",
14111256 block: block,
1412 "catch": catch_,
1413 "finally": finally_
1414 };
1415 }
1416 / TryToken __ block:Block __ catch_:Catch {
1257 handler: handler,
1258 finalizer: finalizer
1259 };
1260 }
1261 / TryToken __ block:Block __ handler:Catch {
14171262 return {
14181263 type: "TryStatement",
14191264 block: block,
1420 "catch": catch_,
1421 "finally": null
1422 };
1423 }
1424 / TryToken __ block:Block __ finally_:Finally {
1265 handler: handler,
1266 finalizer: null
1267 };
1268 }
1269 / TryToken __ block:Block __ finalizer:Finally {
14251270 return {
14261271 type: "TryStatement",
14271272 block: block,
1428 "catch": null,
1429 "finally": finally_
1273 handler: null,
1274 finalizer: finalizer
14301275 };
14311276 }
14321277
14331278 Catch
1434 = CatchToken __ "(" __ identifier:Identifier __ ")" __ block:Block {
1435 return {
1436 type: "Catch",
1437 identifier: identifier,
1438 block: block
1279 = CatchToken __ "(" __ param:Identifier __ ")" __ body:Block {
1280 return {
1281 type: "CatchClause",
1282 param: param,
1283 body: body
14391284 };
14401285 }
14411286
14421287 Finally
1443 = FinallyToken __ block:Block {
1444 return {
1445 type: "Finally",
1446 block: block
1447 };
1448 }
1288 = FinallyToken __ block:Block { return block; }
14491289
14501290 DebuggerStatement
14511291 = DebuggerToken EOS { return { type: "DebuggerStatement" }; }
14521292
1453 /* ===== A.5 Functions and Programs ===== */
1293 /* ----- A.5 Functions and Programs ----- */
14541294
14551295 FunctionDeclaration
1456 = FunctionToken __ name:Identifier __
1457 "(" __ params:FormalParameterList? __ ")" __
1458 "{" __ elements:FunctionBody __ "}" {
1459 return {
1460 type: "Function",
1461 name: name,
1462 params: params !== "" ? params : [],
1463 elements: elements
1296 = FunctionToken __ id:Identifier __
1297 "(" __ params:(FormalParameterList __)? ")" __
1298 "{" __ body:FunctionBody __ "}"
1299 {
1300 return {
1301 type: "FunctionDeclaration",
1302 id: id,
1303 params: optionalList(extractOptional(params, 0)),
1304 body: body
14641305 };
14651306 }
14661307
14671308 FunctionExpression
1468 = FunctionToken __ name:Identifier? __
1469 "(" __ params:FormalParameterList? __ ")" __
1470 "{" __ elements:FunctionBody __ "}" {
1471 return {
1472 type: "Function",
1473 name: name !== "" ? name : null,
1474 params: params !== "" ? params : [],
1475 elements: elements
1309 = FunctionToken __ id:(Identifier __)?
1310 "(" __ params:(FormalParameterList __)? ")" __
1311 "{" __ body:FunctionBody __ "}"
1312 {
1313 return {
1314 type: "FunctionExpression",
1315 id: extractOptional(id, 0),
1316 params: optionalList(extractOptional(params, 0)),
1317 body: body
14761318 };
14771319 }
14781320
14791321 FormalParameterList
14801322 = head:Identifier tail:(__ "," __ Identifier)* {
1481 var result = [head];
1482 for (var i = 0; i < tail.length; i++) {
1483 result.push(tail[i][3]);
1484 }
1485 return result;
1323 return buildList(head, tail, 3);
14861324 }
14871325
14881326 FunctionBody
1489 = elements:SourceElements? { return elements !== "" ? elements : []; }
1327 = body:SourceElements? {
1328 return {
1329 type: "BlockStatement",
1330 body: optionalList(body)
1331 };
1332 }
14901333
14911334 Program
1492 = elements:SourceElements? {
1493 return {
1494 type: "Program",
1495 elements: elements !== "" ? elements : []
1335 = body:SourceElements? {
1336 return {
1337 type: "Program",
1338 body: optionalList(body)
14961339 };
14971340 }
14981341
14991342 SourceElements
15001343 = head:SourceElement tail:(__ SourceElement)* {
1501 var result = [head];
1502 for (var i = 0; i < tail.length; i++) {
1503 result.push(tail[i][1]);
1504 }
1505 return result;
1506 }
1507
1508 /*
1509 * The specification also allows |FunctionDeclaration| here. We do it
1510 * implicitly, because we consider |FunctionDeclaration| and
1511 * |FunctionExpression| as statements. See the comment at the |Statement| rule.
1512 */
1344 return buildList(head, tail, 1);
1345 }
1346
15131347 SourceElement
15141348 = Statement
1515
1516 /* ===== A.6 Universal Resource Identifier Character Classes ===== */
1349 / FunctionDeclaration
1350
1351 /* ----- A.6 Universal Resource Identifier Character Classes ----- */
15171352
15181353 /* Irrelevant. */
15191354
1520 /* ===== A.7 Regular Expressions ===== */
1521
1522 /*
1523 * We treat regular expressions as opaque character sequences and we do not use
1524 * rules from this part of the grammar to parse them further.
1525 */
1526
1527 /* ===== A.8 JSON ===== */
1355 /* ----- A.7 Regular Expressions ----- */
15281356
15291357 /* Irrelevant. */
1358
1359 /* ----- A.8 JSON ----- */
1360
1361 /* Irrelevant. */
0 /* JSON parser based on the grammar described at http://json.org/. */
0 /*
1 * JSON Grammar
2 * ============
3 *
4 * Based on the grammar from RFC 7159 [1].
5 *
6 * Note that JSON is also specified in ECMA-262 [2], ECMA-404 [3], and on the
7 * JSON website [4] (somewhat informally). The RFC seems the most authoritative
8 * source, which is confirmed e.g. by [5].
9 *
10 * [1] http://tools.ietf.org/html/rfc7159
11 * [2] http://www.ecma-international.org/publications/standards/Ecma-262.htm
12 * [3] http://www.ecma-international.org/publications/standards/Ecma-404.htm
13 * [4] http://json.org/
14 * [5] https://www.tbray.org/ongoing/When/201x/2014/03/05/RFC7159-JSON
15 */
116
2 /* ===== Syntactical Elements ===== */
17 /* ----- 2. JSON Grammar ----- */
318
4 start
5 = _ object:object { return object; }
19 JSON_text
20 = ws value:value ws { return value; }
21
22 begin_array = ws "[" ws
23 begin_object = ws "{" ws
24 end_array = ws "]" ws
25 end_object = ws "}" ws
26 name_separator = ws ":" ws
27 value_separator = ws "," ws
28
29 ws "whitespace" = [ \t\n\r]*
30
31 /* ----- 3. Values ----- */
32
33 value
34 = false
35 / null
36 / true
37 / object
38 / array
39 / number
40 / string
41
42 false = "false" { return false; }
43 null = "null" { return null; }
44 true = "true" { return true; }
45
46 /* ----- 4. Objects ----- */
647
748 object
8 = "{" _ "}" _ { return {}; }
9 / "{" _ members:members "}" _ { return members; }
49 = begin_object
50 members:(
51 head:member
52 tail:(value_separator m:member { return m; })*
53 {
54 var result = {}, i;
1055
11 members
12 = head:pair tail:("," _ pair)* {
13 var result = {};
14 result[head[0]] = head[1];
15 for (var i = 0; i < tail.length; i++) {
16 result[tail[i][2][0]] = tail[i][2][1];
56 result[head.name] = head.value;
57
58 for (i = 0; i < tail.length; i++) {
59 result[tail[i].name] = tail[i].value;
60 }
61
62 return result;
1763 }
18 return result;
64 )?
65 end_object
66 { return members !== null ? members: {}; }
67
68 member
69 = name:string name_separator value:value {
70 return { name: name, value: value };
1971 }
2072
21 pair
22 = name:string ":" _ value:value { return [name, value]; }
73 /* ----- 5. Arrays ----- */
2374
2475 array
25 = "[" _ "]" _ { return []; }
26 / "[" _ elements:elements "]" _ { return elements; }
76 = begin_array
77 values:(
78 head:value
79 tail:(value_separator v:value { return v; })*
80 { return [head].concat(tail); }
81 )?
82 end_array
83 { return values !== null ? values : []; }
2784
28 elements
29 = head:value tail:("," _ value)* {
30 var result = [head];
31 for (var i = 0; i < tail.length; i++) {
32 result.push(tail[i][2]);
33 }
34 return result;
35 }
85 /* ----- 6. Numbers ----- */
3686
37 value
38 = string
39 / number
40 / object
41 / array
42 / "true" _ { return true; }
43 / "false" _ { return false; }
44 // FIXME: We can't return null here because that would mean parse failure.
45 / "null" _ { return "null"; }
87 number "number"
88 = minus? int frac? exp? { return parseFloat(text()); }
4689
47 /* ===== Lexical Elements ===== */
90 decimal_point = "."
91 digit1_9 = [1-9]
92 e = [eE]
93 exp = e (minus / plus)? DIGIT+
94 frac = decimal_point DIGIT+
95 int = zero / (digit1_9 DIGIT*)
96 minus = "-"
97 plus = "+"
98 zero = "0"
99
100 /* ----- 7. Strings ----- */
48101
49102 string "string"
50 = '"' '"' _ { return ""; }
51 / '"' chars:chars '"' _ { return chars; }
52
53 chars
54 = chars:char+ { return chars.join(""); }
103 = quotation_mark chars:char* quotation_mark { return chars.join(""); }
55104
56105 char
57 // In the original JSON grammar: "any-Unicode-character-except-"-or-\-or-control-character"
58 = [^"\\\0-\x1F\x7f]
59 / '\\"' { return '"'; }
60 / "\\\\" { return "\\"; }
61 / "\\/" { return "/"; }
62 / "\\b" { return "\b"; }
63 / "\\f" { return "\f"; }
64 / "\\n" { return "\n"; }
65 / "\\r" { return "\r"; }
66 / "\\t" { return "\t"; }
67 / "\\u" h1:hexDigit h2:hexDigit h3:hexDigit h4:hexDigit {
68 return String.fromCharCode(parseInt("0x" + h1 + h2 + h3 + h4));
69 }
106 = unescaped
107 / escape
108 sequence:(
109 '"'
110 / "\\"
111 / "/"
112 / "b" { return "\b"; }
113 / "f" { return "\f"; }
114 / "n" { return "\n"; }
115 / "r" { return "\r"; }
116 / "t" { return "\t"; }
117 / "u" digits:$(HEXDIG HEXDIG HEXDIG HEXDIG) {
118 return String.fromCharCode(parseInt(digits, 16));
119 }
120 )
121 { return sequence; }
70122
71 number "number"
72 = int_:int frac:frac exp:exp _ { return parseFloat(int_ + frac + exp); }
73 / int_:int frac:frac _ { return parseFloat(int_ + frac); }
74 / int_:int exp:exp _ { return parseFloat(int_ + exp); }
75 / int_:int _ { return parseFloat(int_); }
123 escape = "\\"
124 quotation_mark = '"'
125 unescaped = [^\0-\x1F\x22\x5C]
76126
77 int
78 = digit19:digit19 digits:digits { return digit19 + digits; }
79 / digit:digit
80 / "-" digit19:digit19 digits:digits { return "-" + digit19 + digits; }
81 / "-" digit:digit { return "-" + digit; }
127 /* ----- Core ABNF Rules ----- */
82128
83 frac
84 = "." digits:digits { return "." + digits; }
85
86 exp
87 = e:e digits:digits { return e + digits; }
88
89 digits
90 = digits:digit+ { return digits.join(""); }
91
92 e
93 = e:[eE] sign:[+-]? { return e + sign; }
94
95 /*
96 * The following rules are not present in the original JSON gramar, but they are
97 * assumed to exist implicitly.
98 *
99 * FIXME: Define them according to ECMA-262, 5th ed.
100 */
101
102 digit
103 = [0-9]
104
105 digit19
106 = [1-9]
107
108 hexDigit
109 = [0-9a-fA-F]
110
111 /* ===== Whitespace ===== */
112
113 _ "whitespace"
114 = whitespace*
115
116 // Whitespace is undefined in the original JSON grammar, so I assume a simple
117 // conventional definition consistent with ECMA-262, 5th ed.
118 whitespace
119 = [ \t\n\r]
129 /* See RFC 4234, Appendix B (http://tools.ietf.org/html/rfc4627). */
130 DIGIT = [0-9]
131 HEXDIG = [0-9a-f]i
0 {
1 "env": {
2 "commonjs": true
3 }
4 }
0 "use strict";
1
2 var arrays = require("../utils/arrays"),
3 visitor = require("./visitor");
4
5 /* AST utilities. */
6 var asts = {
7 findRule: function(ast, name) {
8 return arrays.find(ast.rules, function(r) { return r.name === name; });
9 },
10
11 indexOfRule: function(ast, name) {
12 return arrays.indexOf(ast.rules, function(r) { return r.name === name; });
13 },
14
15 alwaysConsumesOnSuccess: function(ast, node) {
16 function consumesTrue() { return true; }
17 function consumesFalse() { return false; }
18
19 function consumesExpression(node) {
20 return consumes(node.expression);
21 }
22
23 var consumes = visitor.build({
24 rule: consumesExpression,
25 named: consumesExpression,
26
27 choice: function(node) {
28 return arrays.every(node.alternatives, consumes);
29 },
30
31 action: consumesExpression,
32
33 sequence: function(node) {
34 return arrays.some(node.elements, consumes);
35 },
36
37 labeled: consumesExpression,
38 text: consumesExpression,
39 simple_and: consumesFalse,
40 simple_not: consumesFalse,
41 optional: consumesFalse,
42 zero_or_more: consumesFalse,
43 one_or_more: consumesExpression,
44 group: consumesExpression,
45 semantic_and: consumesFalse,
46 semantic_not: consumesFalse,
47
48 rule_ref: function(node) {
49 return consumes(asts.findRule(ast, node.name));
50 },
51
52 literal: function(node) {
53 return node.value !== "";
54 },
55
56 "class": consumesTrue,
57 any: consumesTrue
58 });
59
60 return consumes(node);
61 }
62 };
63
64 module.exports = asts;
0 "use strict";
1
2 var arrays = require("../utils/arrays"),
3 objects = require("../utils/objects");
4
5 var compiler = {
6 /*
7 * AST node visitor builder. Useful mainly for plugins which manipulate the
8 * AST.
9 */
10 visitor: require("./visitor"),
11
12 /*
13 * Compiler passes.
14 *
15 * Each pass is a function that is passed the AST. It can perform checks on it
16 * or modify it as needed. If the pass encounters a semantic error, it throws
17 * |peg.GrammarError|.
18 */
19 passes: {
20 check: {
21 reportUndefinedRules: require("./passes/report-undefined-rules"),
22 reportDuplicateRules: require("./passes/report-duplicate-rules"),
23 reportDuplicateLabels: require("./passes/report-duplicate-labels"),
24 reportInfiniteRecursion: require("./passes/report-infinite-recursion"),
25 reportInfiniteRepetition: require("./passes/report-infinite-repetition")
26 },
27 transform: {
28 removeProxyRules: require("./passes/remove-proxy-rules")
29 },
30 generate: {
31 generateBytecode: require("./passes/generate-bytecode"),
32 generateJS: require("./passes/generate-js")
33 }
34 },
35
36 /*
37 * Generates a parser from a specified grammar AST. Throws |peg.GrammarError|
38 * if the AST contains a semantic error. Note that not all errors are detected
39 * during the generation and some may protrude to the generated parser and
40 * cause its malfunction.
41 */
42 compile: function(ast, passes, options) {
43 options = options !== void 0 ? options : {};
44
45 var stage;
46
47 options = objects.clone(options);
48 objects.defaults(options, {
49 allowedStartRules: [ast.rules[0].name],
50 cache: false,
51 dependencies: {},
52 exportVar: null,
53 format: "bare",
54 optimize: "speed",
55 output: "parser",
56 trace: false
57 });
58
59 for (stage in passes) {
60 if (passes.hasOwnProperty(stage)) {
61 arrays.each(passes[stage], function(p) { p(ast, options); });
62 }
63 }
64
65 switch (options.output) {
66 case "parser": return eval(ast.code);
67 case "source": return ast.code;
68 }
69 }
70 };
71
72 module.exports = compiler;
0 "use strict";
1
2 function hex(ch) { return ch.charCodeAt(0).toString(16).toUpperCase(); }
3
4 /* JavaScript code generation helpers. */
5 var js = {
6 stringEscape: function(s) {
7 /*
8 * ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a string
9 * literal except for the closing quote character, backslash, carriage
10 * return, line separator, paragraph separator, and line feed. Any character
11 * may appear in the form of an escape sequence.
12 *
13 * For portability, we also escape all control and non-ASCII characters.
14 * Note that the "\v" escape sequence is not used because IE does not like
15 * it.
16 */
17 return s
18 .replace(/\\/g, '\\\\') // backslash
19 .replace(/"/g, '\\"') // closing double quote
20 .replace(/\0/g, '\\0') // null
21 .replace(/\x08/g, '\\b') // backspace
22 .replace(/\t/g, '\\t') // horizontal tab
23 .replace(/\n/g, '\\n') // line feed
24 .replace(/\f/g, '\\f') // form feed
25 .replace(/\r/g, '\\r') // carriage return
26 .replace(/[\x00-\x0F]/g, function(ch) { return '\\x0' + hex(ch); })
27 .replace(/[\x10-\x1F\x7F-\xFF]/g, function(ch) { return '\\x' + hex(ch); })
28 .replace(/[\u0100-\u0FFF]/g, function(ch) { return '\\u0' + hex(ch); })
29 .replace(/[\u1000-\uFFFF]/g, function(ch) { return '\\u' + hex(ch); });
30 },
31
32 regexpClassEscape: function(s) {
33 /*
34 * Based on ECMA-262, 5th ed., 7.8.5 & 15.10.1.
35 *
36 * For portability, we also escape all control and non-ASCII characters.
37 */
38 return s
39 .replace(/\\/g, '\\\\') // backslash
40 .replace(/\//g, '\\/') // closing slash
41 .replace(/\]/g, '\\]') // closing bracket
42 .replace(/\^/g, '\\^') // caret
43 .replace(/-/g, '\\-') // dash
44 .replace(/\0/g, '\\0') // null
45 .replace(/\t/g, '\\t') // horizontal tab
46 .replace(/\n/g, '\\n') // line feed
47 .replace(/\v/g, '\\x0B') // vertical tab
48 .replace(/\f/g, '\\f') // form feed
49 .replace(/\r/g, '\\r') // carriage return
50 .replace(/[\x00-\x0F]/g, function(ch) { return '\\x0' + hex(ch); })
51 .replace(/[\x10-\x1F\x7F-\xFF]/g, function(ch) { return '\\x' + hex(ch); })
52 .replace(/[\u0100-\u0FFF]/g, function(ch) { return '\\u0' + hex(ch); })
53 .replace(/[\u1000-\uFFFF]/g, function(ch) { return '\\u' + hex(ch); });
54 }
55 };
56
57 module.exports = js;
0 "use strict";
1
2 /* Bytecode instruction opcodes. */
3 var opcodes = {
4 /* Stack Manipulation */
5
6 PUSH: 0, // PUSH c
7 PUSH_UNDEFINED: 1, // PUSH_UNDEFINED
8 PUSH_NULL: 2, // PUSH_NULL
9 PUSH_FAILED: 3, // PUSH_FAILED
10 PUSH_EMPTY_ARRAY: 4, // PUSH_EMPTY_ARRAY
11 PUSH_CURR_POS: 5, // PUSH_CURR_POS
12 POP: 6, // POP
13 POP_CURR_POS: 7, // POP_CURR_POS
14 POP_N: 8, // POP_N n
15 NIP: 9, // NIP
16 APPEND: 10, // APPEND
17 WRAP: 11, // WRAP n
18 TEXT: 12, // TEXT
19
20 /* Conditions and Loops */
21
22 IF: 13, // IF t, f
23 IF_ERROR: 14, // IF_ERROR t, f
24 IF_NOT_ERROR: 15, // IF_NOT_ERROR t, f
25 WHILE_NOT_ERROR: 16, // WHILE_NOT_ERROR b
26
27 /* Matching */
28
29 MATCH_ANY: 17, // MATCH_ANY a, f, ...
30 MATCH_STRING: 18, // MATCH_STRING s, a, f, ...
31 MATCH_STRING_IC: 19, // MATCH_STRING_IC s, a, f, ...
32 MATCH_REGEXP: 20, // MATCH_REGEXP r, a, f, ...
33 ACCEPT_N: 21, // ACCEPT_N n
34 ACCEPT_STRING: 22, // ACCEPT_STRING s
35 FAIL: 23, // FAIL e
36
37 /* Calls */
38
39 LOAD_SAVED_POS: 24, // LOAD_SAVED_POS p
40 UPDATE_SAVED_POS: 25, // UPDATE_SAVED_POS
41 CALL: 26, // CALL f, n, pc, p1, p2, ..., pN
42
43 /* Rules */
44
45 RULE: 27, // RULE r
46
47 /* Failure Reporting */
48
49 SILENT_FAILS_ON: 28, // SILENT_FAILS_ON
50 SILENT_FAILS_OFF: 29 // SILENT_FAILS_OFF
51 };
52
53 module.exports = opcodes;
0 "use strict";
1
2 var arrays = require("../../utils/arrays"),
3 objects = require("../../utils/objects"),
4 asts = require("../asts"),
5 visitor = require("../visitor"),
6 op = require("../opcodes"),
7 js = require("../js");
8
9 /* Generates bytecode.
10 *
11 * Instructions
12 * ============
13 *
14 * Stack Manipulation
15 * ------------------
16 *
17 * [0] PUSH c
18 *
19 * stack.push(consts[c]);
20 *
21 * [1] PUSH_UNDEFINED
22 *
23 * stack.push(undefined);
24 *
25 * [2] PUSH_NULL
26 *
27 * stack.push(null);
28 *
29 * [3] PUSH_FAILED
30 *
31 * stack.push(FAILED);
32 *
33 * [4] PUSH_EMPTY_ARRAY
34 *
35 * stack.push([]);
36 *
37 * [5] PUSH_CURR_POS
38 *
39 * stack.push(currPos);
40 *
41 * [6] POP
42 *
43 * stack.pop();
44 *
45 * [7] POP_CURR_POS
46 *
47 * currPos = stack.pop();
48 *
49 * [8] POP_N n
50 *
51 * stack.pop(n);
52 *
53 * [9] NIP
54 *
55 * value = stack.pop();
56 * stack.pop();
57 * stack.push(value);
58 *
59 * [10] APPEND
60 *
61 * value = stack.pop();
62 * array = stack.pop();
63 * array.push(value);
64 * stack.push(array);
65 *
66 * [11] WRAP n
67 *
68 * stack.push(stack.pop(n));
69 *
70 * [12] TEXT
71 *
72 * stack.push(input.substring(stack.pop(), currPos));
73 *
74 * Conditions and Loops
75 * --------------------
76 *
77 * [13] IF t, f
78 *
79 * if (stack.top()) {
80 * interpret(ip + 3, ip + 3 + t);
81 * } else {
82 * interpret(ip + 3 + t, ip + 3 + t + f);
83 * }
84 *
85 * [14] IF_ERROR t, f
86 *
87 * if (stack.top() === FAILED) {
88 * interpret(ip + 3, ip + 3 + t);
89 * } else {
90 * interpret(ip + 3 + t, ip + 3 + t + f);
91 * }
92 *
93 * [15] IF_NOT_ERROR t, f
94 *
95 * if (stack.top() !== FAILED) {
96 * interpret(ip + 3, ip + 3 + t);
97 * } else {
98 * interpret(ip + 3 + t, ip + 3 + t + f);
99 * }
100 *
101 * [16] WHILE_NOT_ERROR b
102 *
103 * while(stack.top() !== FAILED) {
104 * interpret(ip + 2, ip + 2 + b);
105 * }
106 *
107 * Matching
108 * --------
109 *
110 * [17] MATCH_ANY a, f, ...
111 *
112 * if (input.length > currPos) {
113 * interpret(ip + 3, ip + 3 + a);
114 * } else {
115 * interpret(ip + 3 + a, ip + 3 + a + f);
116 * }
117 *
118 * [18] MATCH_STRING s, a, f, ...
119 *
120 * if (input.substr(currPos, consts[s].length) === consts[s]) {
121 * interpret(ip + 4, ip + 4 + a);
122 * } else {
123 * interpret(ip + 4 + a, ip + 4 + a + f);
124 * }
125 *
126 * [19] MATCH_STRING_IC s, a, f, ...
127 *
128 * if (input.substr(currPos, consts[s].length).toLowerCase() === consts[s]) {
129 * interpret(ip + 4, ip + 4 + a);
130 * } else {
131 * interpret(ip + 4 + a, ip + 4 + a + f);
132 * }
133 *
134 * [20] MATCH_REGEXP r, a, f, ...
135 *
136 * if (consts[r].test(input.charAt(currPos))) {
137 * interpret(ip + 4, ip + 4 + a);
138 * } else {
139 * interpret(ip + 4 + a, ip + 4 + a + f);
140 * }
141 *
142 * [21] ACCEPT_N n
143 *
144 * stack.push(input.substring(currPos, n));
145 * currPos += n;
146 *
147 * [22] ACCEPT_STRING s
148 *
149 * stack.push(consts[s]);
150 * currPos += consts[s].length;
151 *
152 * [23] FAIL e
153 *
154 * stack.push(FAILED);
155 * fail(consts[e]);
156 *
157 * Calls
158 * -----
159 *
160 * [24] LOAD_SAVED_POS p
161 *
162 * savedPos = stack[p];
163 *
164 * [25] UPDATE_SAVED_POS
165 *
166 * savedPos = currPos;
167 *
168 * [26] CALL f, n, pc, p1, p2, ..., pN
169 *
170 * value = consts[f](stack[p1], ..., stack[pN]);
171 * stack.pop(n);
172 * stack.push(value);
173 *
174 * Rules
175 * -----
176 *
177 * [27] RULE r
178 *
179 * stack.push(parseRule(r));
180 *
181 * Failure Reporting
182 * -----------------
183 *
184 * [28] SILENT_FAILS_ON
185 *
186 * silentFails++;
187 *
188 * [29] SILENT_FAILS_OFF
189 *
190 * silentFails--;
191 */
192 function generateBytecode(ast) {
193 var consts = [];
194
195 function addConst(value) {
196 var index = arrays.indexOf(consts, value);
197
198 return index === -1 ? consts.push(value) - 1 : index;
199 }
200
201 function addFunctionConst(params, code) {
202 return addConst(
203 "function(" + params.join(", ") + ") {" + code + "}"
204 );
205 }
206
207 function buildSequence() {
208 return Array.prototype.concat.apply([], arguments);
209 }
210
211 function buildCondition(condCode, thenCode, elseCode) {
212 return condCode.concat(
213 [thenCode.length, elseCode.length],
214 thenCode,
215 elseCode
216 );
217 }
218
219 function buildLoop(condCode, bodyCode) {
220 return condCode.concat([bodyCode.length], bodyCode);
221 }
222
223 function buildCall(functionIndex, delta, env, sp) {
224 var params = arrays.map(objects.values(env), function(p) { return sp - p; });
225
226 return [op.CALL, functionIndex, delta, params.length].concat(params);
227 }
228
229 function buildSimplePredicate(expression, negative, context) {
230 return buildSequence(
231 [op.PUSH_CURR_POS],
232 [op.SILENT_FAILS_ON],
233 generate(expression, {
234 sp: context.sp + 1,
235 env: objects.clone(context.env),
236 action: null
237 }),
238 [op.SILENT_FAILS_OFF],
239 buildCondition(
240 [negative ? op.IF_ERROR : op.IF_NOT_ERROR],
241 buildSequence(
242 [op.POP],
243 [negative ? op.POP : op.POP_CURR_POS],
244 [op.PUSH_UNDEFINED]
245 ),
246 buildSequence(
247 [op.POP],
248 [negative ? op.POP_CURR_POS : op.POP],
249 [op.PUSH_FAILED]
250 )
251 )
252 );
253 }
254
255 function buildSemanticPredicate(code, negative, context) {
256 var functionIndex = addFunctionConst(objects.keys(context.env), code);
257
258 return buildSequence(
259 [op.UPDATE_SAVED_POS],
260 buildCall(functionIndex, 0, context.env, context.sp),
261 buildCondition(
262 [op.IF],
263 buildSequence(
264 [op.POP],
265 negative ? [op.PUSH_FAILED] : [op.PUSH_UNDEFINED]
266 ),
267 buildSequence(
268 [op.POP],
269 negative ? [op.PUSH_UNDEFINED] : [op.PUSH_FAILED]
270 )
271 )
272 );
273 }
274
275 function buildAppendLoop(expressionCode) {
276 return buildLoop(
277 [op.WHILE_NOT_ERROR],
278 buildSequence([op.APPEND], expressionCode)
279 );
280 }
281
282 var generate = visitor.build({
283 grammar: function(node) {
284 arrays.each(node.rules, generate);
285
286 node.consts = consts;
287 },
288
289 rule: function(node) {
290 node.bytecode = generate(node.expression, {
291 sp: -1, // stack pointer
292 env: { }, // mapping of label names to stack positions
293 action: null // action nodes pass themselves to children here
294 });
295 },
296
297 named: function(node, context) {
298 var nameIndex = addConst(
299 'peg$otherExpectation("' + js.stringEscape(node.name) + '")'
300 );
301
302 /*
303 * The code generated below is slightly suboptimal because |FAIL| pushes
304 * to the stack, so we need to stick a |POP| in front of it. We lack a
305 * dedicated instruction that would just report the failure and not touch
306 * the stack.
307 */
308 return buildSequence(
309 [op.SILENT_FAILS_ON],
310 generate(node.expression, context),
311 [op.SILENT_FAILS_OFF],
312 buildCondition([op.IF_ERROR], [op.FAIL, nameIndex], [])
313 );
314 },
315
316 choice: function(node, context) {
317 function buildAlternativesCode(alternatives, context) {
318 return buildSequence(
319 generate(alternatives[0], {
320 sp: context.sp,
321 env: objects.clone(context.env),
322 action: null
323 }),
324 alternatives.length > 1
325 ? buildCondition(
326 [op.IF_ERROR],
327 buildSequence(
328 [op.POP],
329 buildAlternativesCode(alternatives.slice(1), context)
330 ),
331 []
332 )
333 : []
334 );
335 }
336
337 return buildAlternativesCode(node.alternatives, context);
338 },
339
340 action: function(node, context) {
341 var env = objects.clone(context.env),
342 emitCall = node.expression.type !== "sequence"
343 || node.expression.elements.length === 0,
344 expressionCode = generate(node.expression, {
345 sp: context.sp + (emitCall ? 1 : 0),
346 env: env,
347 action: node
348 }),
349 functionIndex = addFunctionConst(objects.keys(env), node.code);
350
351 return emitCall
352 ? buildSequence(
353 [op.PUSH_CURR_POS],
354 expressionCode,
355 buildCondition(
356 [op.IF_NOT_ERROR],
357 buildSequence(
358 [op.LOAD_SAVED_POS, 1],
359 buildCall(functionIndex, 1, env, context.sp + 2)
360 ),
361 []
362 ),
363 [op.NIP]
364 )
365 : expressionCode;
366 },
367
368 sequence: function(node, context) {
369 function buildElementsCode(elements, context) {
370 var processedCount, functionIndex;
371
372 if (elements.length > 0) {
373 processedCount = node.elements.length - elements.slice(1).length;
374
375 return buildSequence(
376 generate(elements[0], {
377 sp: context.sp,
378 env: context.env,
379 action: null
380 }),
381 buildCondition(
382 [op.IF_NOT_ERROR],
383 buildElementsCode(elements.slice(1), {
384 sp: context.sp + 1,
385 env: context.env,
386 action: context.action
387 }),
388 buildSequence(
389 processedCount > 1 ? [op.POP_N, processedCount] : [op.POP],
390 [op.POP_CURR_POS],
391 [op.PUSH_FAILED]
392 )
393 )
394 );
395 } else {
396 if (context.action) {
397 functionIndex = addFunctionConst(
398 objects.keys(context.env),
399 context.action.code
400 );
401
402 return buildSequence(
403 [op.LOAD_SAVED_POS, node.elements.length],
404 buildCall(
405 functionIndex,
406 node.elements.length,
407 context.env,
408 context.sp
409 ),
410 [op.NIP]
411 );
412 } else {
413 return buildSequence([op.WRAP, node.elements.length], [op.NIP]);
414 }
415 }
416 }
417
418 return buildSequence(
419 [op.PUSH_CURR_POS],
420 buildElementsCode(node.elements, {
421 sp: context.sp + 1,
422 env: context.env,
423 action: context.action
424 })
425 );
426 },
427
428 labeled: function(node, context) {
429 var env = objects.clone(context.env);
430
431 context.env[node.label] = context.sp + 1;
432
433 return generate(node.expression, {
434 sp: context.sp,
435 env: env,
436 action: null
437 });
438 },
439
440 text: function(node, context) {
441 return buildSequence(
442 [op.PUSH_CURR_POS],
443 generate(node.expression, {
444 sp: context.sp + 1,
445 env: objects.clone(context.env),
446 action: null
447 }),
448 buildCondition(
449 [op.IF_NOT_ERROR],
450 buildSequence([op.POP], [op.TEXT]),
451 [op.NIP]
452 )
453 );
454 },
455
456 simple_and: function(node, context) {
457 return buildSimplePredicate(node.expression, false, context);
458 },
459
460 simple_not: function(node, context) {
461 return buildSimplePredicate(node.expression, true, context);
462 },
463
464 optional: function(node, context) {
465 return buildSequence(
466 generate(node.expression, {
467 sp: context.sp,
468 env: objects.clone(context.env),
469 action: null
470 }),
471 buildCondition(
472 [op.IF_ERROR],
473 buildSequence([op.POP], [op.PUSH_NULL]),
474 []
475 )
476 );
477 },
478
479 zero_or_more: function(node, context) {
480 var expressionCode = generate(node.expression, {
481 sp: context.sp + 1,
482 env: objects.clone(context.env),
483 action: null
484 });
485
486 return buildSequence(
487 [op.PUSH_EMPTY_ARRAY],
488 expressionCode,
489 buildAppendLoop(expressionCode),
490 [op.POP]
491 );
492 },
493
494 one_or_more: function(node, context) {
495 var expressionCode = generate(node.expression, {
496 sp: context.sp + 1,
497 env: objects.clone(context.env),
498 action: null
499 });
500
501 return buildSequence(
502 [op.PUSH_EMPTY_ARRAY],
503 expressionCode,
504 buildCondition(
505 [op.IF_NOT_ERROR],
506 buildSequence(buildAppendLoop(expressionCode), [op.POP]),
507 buildSequence([op.POP], [op.POP], [op.PUSH_FAILED])
508 )
509 );
510 },
511
512 group: function(node, context) {
513 return generate(node.expression, {
514 sp: context.sp,
515 env: objects.clone(context.env),
516 action: null
517 });
518 },
519
520 semantic_and: function(node, context) {
521 return buildSemanticPredicate(node.code, false, context);
522 },
523
524 semantic_not: function(node, context) {
525 return buildSemanticPredicate(node.code, true, context);
526 },
527
528 rule_ref: function(node) {
529 return [op.RULE, asts.indexOfRule(ast, node.name)];
530 },
531
532 literal: function(node) {
533 var stringIndex, expectedIndex;
534
535 if (node.value.length > 0) {
536 stringIndex = addConst('"'
537 + js.stringEscape(
538 node.ignoreCase ? node.value.toLowerCase() : node.value
539 )
540 + '"'
541 );
542 expectedIndex = addConst(
543 'peg$literalExpectation('
544 + '"' + js.stringEscape(node.value) + '", '
545 + node.ignoreCase
546 + ')'
547 );
548
549 /*
550 * For case-sensitive strings the value must match the beginning of the
551 * remaining input exactly. As a result, we can use |ACCEPT_STRING| and
552 * save one |substr| call that would be needed if we used |ACCEPT_N|.
553 */
554 return buildCondition(
555 node.ignoreCase
556 ? [op.MATCH_STRING_IC, stringIndex]
557 : [op.MATCH_STRING, stringIndex],
558 node.ignoreCase
559 ? [op.ACCEPT_N, node.value.length]
560 : [op.ACCEPT_STRING, stringIndex],
561 [op.FAIL, expectedIndex]
562 );
563 } else {
564 stringIndex = addConst('""');
565
566 return [op.PUSH, stringIndex];
567 }
568 },
569
570 "class": function(node) {
571 var regexp, parts, regexpIndex, expectedIndex;
572
573 if (node.parts.length > 0) {
574 regexp = '/^['
575 + (node.inverted ? '^' : '')
576 + arrays.map(node.parts, function(part) {
577 return part instanceof Array
578 ? js.regexpClassEscape(part[0])
579 + '-'
580 + js.regexpClassEscape(part[1])
581 : js.regexpClassEscape(part);
582 }).join('')
583 + ']/' + (node.ignoreCase ? 'i' : '');
584 } else {
585 /*
586 * IE considers regexps /[]/ and /[^]/ as syntactically invalid, so we
587 * translate them into equivalents it can handle.
588 */
589 regexp = node.inverted ? '/^[\\S\\s]/' : '/^(?!)/';
590 }
591
592 parts = '['
593 + arrays.map(node.parts, function(part) {
594 return part instanceof Array
595 ? '["' + js.stringEscape(part[0]) + '", "' + js.stringEscape(part[1]) + '"]'
596 : '"' + js.stringEscape(part) + '"';
597 }).join(', ')
598 + ']';
599
600 regexpIndex = addConst(regexp);
601 expectedIndex = addConst(
602 'peg$classExpectation('
603 + parts + ', '
604 + node.inverted + ', '
605 + node.ignoreCase
606 + ')'
607 );
608
609 return buildCondition(
610 [op.MATCH_REGEXP, regexpIndex],
611 [op.ACCEPT_N, 1],
612 [op.FAIL, expectedIndex]
613 );
614 },
615
616 any: function() {
617 var expectedIndex = addConst('peg$anyExpectation()');
618
619 return buildCondition(
620 [op.MATCH_ANY],
621 [op.ACCEPT_N, 1],
622 [op.FAIL, expectedIndex]
623 );
624 }
625 });
626
627 generate(ast);
628 }
629
630 module.exports = generateBytecode;
0 "use strict";
1
2 var arrays = require("../../utils/arrays"),
3 objects = require("../../utils/objects"),
4 asts = require("../asts"),
5 op = require("../opcodes"),
6 js = require("../js");
7
8 /* Generates parser JavaScript code. */
9 function generateJS(ast, options) {
10 /* These only indent non-empty lines to avoid trailing whitespace. */
11 function indent2(code) { return code.replace(/^(.+)$/gm, ' $1'); }
12 function indent6(code) { return code.replace(/^(.+)$/gm, ' $1'); }
13 function indent10(code) { return code.replace(/^(.+)$/gm, ' $1'); }
14
15 function generateTables() {
16 if (options.optimize === "size") {
17 return [
18 'peg$consts = [',
19 indent2(ast.consts.join(',\n')),
20 '],',
21 '',
22 'peg$bytecode = [',
23 indent2(arrays.map(ast.rules, function(rule) {
24 return 'peg$decode("'
25 + js.stringEscape(arrays.map(
26 rule.bytecode,
27 function(b) { return String.fromCharCode(b + 32); }
28 ).join(''))
29 + '")';
30 }).join(',\n')),
31 '],'
32 ].join('\n');
33 } else {
34 return arrays.map(
35 ast.consts,
36 function(c, i) { return 'peg$c' + i + ' = ' + c + ','; }
37 ).join('\n');
38 }
39 }
40
41 function generateRuleHeader(ruleNameCode, ruleIndexCode) {
42 var parts = [];
43
44 parts.push('');
45
46 if (options.trace) {
47 parts.push([
48 'peg$tracer.trace({',
49 ' type: "rule.enter",',
50 ' rule: ' + ruleNameCode + ',',
51 ' location: peg$computeLocation(startPos, startPos)',
52 '});',
53 ''
54 ].join('\n'));
55 }
56
57 if (options.cache) {
58 parts.push([
59 'var key = peg$currPos * ' + ast.rules.length + ' + ' + ruleIndexCode + ',',
60 ' cached = peg$resultsCache[key];',
61 '',
62 'if (cached) {',
63 ' peg$currPos = cached.nextPos;',
64 ''
65 ].join('\n'));
66
67 if (options.trace) {
68 parts.push([
69 'if (cached.result !== peg$FAILED) {',
70 ' peg$tracer.trace({',
71 ' type: "rule.match",',
72 ' rule: ' + ruleNameCode + ',',
73 ' result: cached.result,',
74 ' location: peg$computeLocation(startPos, peg$currPos)',
75 ' });',
76 '} else {',
77 ' peg$tracer.trace({',
78 ' type: "rule.fail",',
79 ' rule: ' + ruleNameCode + ',',
80 ' location: peg$computeLocation(startPos, startPos)',
81 ' });',
82 '}',
83 ''
84 ].join('\n'));
85 }
86
87 parts.push([
88 ' return cached.result;',
89 '}',
90 ''
91 ].join('\n'));
92 }
93
94 return parts.join('\n');
95 }
96
97 function generateRuleFooter(ruleNameCode, resultCode) {
98 var parts = [];
99
100 if (options.cache) {
101 parts.push([
102 '',
103 'peg$resultsCache[key] = { nextPos: peg$currPos, result: ' + resultCode + ' };'
104 ].join('\n'));
105 }
106
107 if (options.trace) {
108 parts.push([
109 '',
110 'if (' + resultCode + ' !== peg$FAILED) {',
111 ' peg$tracer.trace({',
112 ' type: "rule.match",',
113 ' rule: ' + ruleNameCode + ',',
114 ' result: ' + resultCode + ',',
115 ' location: peg$computeLocation(startPos, peg$currPos)',
116 ' });',
117 '} else {',
118 ' peg$tracer.trace({',
119 ' type: "rule.fail",',
120 ' rule: ' + ruleNameCode + ',',
121 ' location: peg$computeLocation(startPos, startPos)',
122 ' });',
123 '}'
124 ].join('\n'));
125 }
126
127 parts.push([
128 '',
129 'return ' + resultCode + ';'
130 ].join('\n'));
131
132 return parts.join('\n');
133 }
134
135 function generateInterpreter() {
136 var parts = [];
137
138 function generateCondition(cond, argsLength) {
139 var baseLength = argsLength + 3,
140 thenLengthCode = 'bc[ip + ' + (baseLength - 2) + ']',
141 elseLengthCode = 'bc[ip + ' + (baseLength - 1) + ']';
142
143 return [
144 'ends.push(end);',
145 'ips.push(ip + ' + baseLength + ' + ' + thenLengthCode + ' + ' + elseLengthCode + ');',
146 '',
147 'if (' + cond + ') {',
148 ' end = ip + ' + baseLength + ' + ' + thenLengthCode + ';',
149 ' ip += ' + baseLength + ';',
150 '} else {',
151 ' end = ip + ' + baseLength + ' + ' + thenLengthCode + ' + ' + elseLengthCode + ';',
152 ' ip += ' + baseLength + ' + ' + thenLengthCode + ';',
153 '}',
154 '',
155 'break;'
156 ].join('\n');
157 }
158
159 function generateLoop(cond) {
160 var baseLength = 2,
161 bodyLengthCode = 'bc[ip + ' + (baseLength - 1) + ']';
162
163 return [
164 'if (' + cond + ') {',
165 ' ends.push(end);',
166 ' ips.push(ip);',
167 '',
168 ' end = ip + ' + baseLength + ' + ' + bodyLengthCode + ';',
169 ' ip += ' + baseLength + ';',
170 '} else {',
171 ' ip += ' + baseLength + ' + ' + bodyLengthCode + ';',
172 '}',
173 '',
174 'break;'
175 ].join('\n');
176 }
177
178 function generateCall() {
179 var baseLength = 4,
180 paramsLengthCode = 'bc[ip + ' + (baseLength - 1) + ']';
181
182 return [
183 'params = bc.slice(ip + ' + baseLength + ', ip + ' + baseLength + ' + ' + paramsLengthCode + ');',
184 'for (i = 0; i < ' + paramsLengthCode + '; i++) {',
185 ' params[i] = stack[stack.length - 1 - params[i]];',
186 '}',
187 '',
188 'stack.splice(',
189 ' stack.length - bc[ip + 2],',
190 ' bc[ip + 2],',
191 ' peg$consts[bc[ip + 1]].apply(null, params)',
192 ');',
193 '',
194 'ip += ' + baseLength + ' + ' + paramsLengthCode + ';',
195 'break;'
196 ].join('\n');
197 }
198
199 parts.push([
200 'function peg$decode(s) {',
201 ' var bc = new Array(s.length), i;',
202 '',
203 ' for (i = 0; i < s.length; i++) {',
204 ' bc[i] = s.charCodeAt(i) - 32;',
205 ' }',
206 '',
207 ' return bc;',
208 '}',
209 '',
210 'function peg$parseRule(index) {'
211 ].join('\n'));
212
213 if (options.trace) {
214 parts.push([
215 ' var bc = peg$bytecode[index],',
216 ' ip = 0,',
217 ' ips = [],',
218 ' end = bc.length,',
219 ' ends = [],',
220 ' stack = [],',
221 ' startPos = peg$currPos,',
222 ' params, i;'
223 ].join('\n'));
224 } else {
225 parts.push([
226 ' var bc = peg$bytecode[index],',
227 ' ip = 0,',
228 ' ips = [],',
229 ' end = bc.length,',
230 ' ends = [],',
231 ' stack = [],',
232 ' params, i;'
233 ].join('\n'));
234 }
235
236 parts.push(indent2(generateRuleHeader('peg$ruleNames[index]', 'index')));
237
238 parts.push([
239 /*
240 * The point of the outer loop and the |ips| & |ends| stacks is to avoid
241 * recursive calls for interpreting parts of bytecode. In other words, we
242 * implement the |interpret| operation of the abstract machine without
243 * function calls. Such calls would likely slow the parser down and more
244 * importantly cause stack overflows for complex grammars.
245 */
246 ' while (true) {',
247 ' while (ip < end) {',
248 ' switch (bc[ip]) {',
249 ' case ' + op.PUSH + ':', // PUSH c
250 ' stack.push(peg$consts[bc[ip + 1]]);',
251 ' ip += 2;',
252 ' break;',
253 '',
254 ' case ' + op.PUSH_UNDEFINED + ':', // PUSH_UNDEFINED
255 ' stack.push(void 0);',
256 ' ip++;',
257 ' break;',
258 '',
259 ' case ' + op.PUSH_NULL + ':', // PUSH_NULL
260 ' stack.push(null);',
261 ' ip++;',
262 ' break;',
263 '',
264 ' case ' + op.PUSH_FAILED + ':', // PUSH_FAILED
265 ' stack.push(peg$FAILED);',
266 ' ip++;',
267 ' break;',
268 '',
269 ' case ' + op.PUSH_EMPTY_ARRAY + ':', // PUSH_EMPTY_ARRAY
270 ' stack.push([]);',
271 ' ip++;',
272 ' break;',
273 '',
274 ' case ' + op.PUSH_CURR_POS + ':', // PUSH_CURR_POS
275 ' stack.push(peg$currPos);',
276 ' ip++;',
277 ' break;',
278 '',
279 ' case ' + op.POP + ':', // POP
280 ' stack.pop();',
281 ' ip++;',
282 ' break;',
283 '',
284 ' case ' + op.POP_CURR_POS + ':', // POP_CURR_POS
285 ' peg$currPos = stack.pop();',
286 ' ip++;',
287 ' break;',
288 '',
289 ' case ' + op.POP_N + ':', // POP_N n
290 ' stack.length -= bc[ip + 1];',
291 ' ip += 2;',
292 ' break;',
293 '',
294 ' case ' + op.NIP + ':', // NIP
295 ' stack.splice(-2, 1);',
296 ' ip++;',
297 ' break;',
298 '',
299 ' case ' + op.APPEND + ':', // APPEND
300 ' stack[stack.length - 2].push(stack.pop());',
301 ' ip++;',
302 ' break;',
303 '',
304 ' case ' + op.WRAP + ':', // WRAP n
305 ' stack.push(stack.splice(stack.length - bc[ip + 1], bc[ip + 1]));',
306 ' ip += 2;',
307 ' break;',
308 '',
309 ' case ' + op.TEXT + ':', // TEXT
310 ' stack.push(input.substring(stack.pop(), peg$currPos));',
311 ' ip++;',
312 ' break;',
313 '',
314 ' case ' + op.IF + ':', // IF t, f
315 indent10(generateCondition('stack[stack.length - 1]', 0)),
316 '',
317 ' case ' + op.IF_ERROR + ':', // IF_ERROR t, f
318 indent10(generateCondition(
319 'stack[stack.length - 1] === peg$FAILED',
320 0
321 )),
322 '',
323 ' case ' + op.IF_NOT_ERROR + ':', // IF_NOT_ERROR t, f
324 indent10(
325 generateCondition('stack[stack.length - 1] !== peg$FAILED',
326 0
327 )),
328 '',
329 ' case ' + op.WHILE_NOT_ERROR + ':', // WHILE_NOT_ERROR b
330 indent10(generateLoop('stack[stack.length - 1] !== peg$FAILED')),
331 '',
332 ' case ' + op.MATCH_ANY + ':', // MATCH_ANY a, f, ...
333 indent10(generateCondition('input.length > peg$currPos', 0)),
334 '',
335 ' case ' + op.MATCH_STRING + ':', // MATCH_STRING s, a, f, ...
336 indent10(generateCondition(
337 'input.substr(peg$currPos, peg$consts[bc[ip + 1]].length) === peg$consts[bc[ip + 1]]',
338 1
339 )),
340 '',
341 ' case ' + op.MATCH_STRING_IC + ':', // MATCH_STRING_IC s, a, f, ...
342 indent10(generateCondition(
343 'input.substr(peg$currPos, peg$consts[bc[ip + 1]].length).toLowerCase() === peg$consts[bc[ip + 1]]',
344 1
345 )),
346 '',
347 ' case ' + op.MATCH_REGEXP + ':', // MATCH_REGEXP r, a, f, ...
348 indent10(generateCondition(
349 'peg$consts[bc[ip + 1]].test(input.charAt(peg$currPos))',
350 1
351 )),
352 '',
353 ' case ' + op.ACCEPT_N + ':', // ACCEPT_N n
354 ' stack.push(input.substr(peg$currPos, bc[ip + 1]));',
355 ' peg$currPos += bc[ip + 1];',
356 ' ip += 2;',
357 ' break;',
358 '',
359 ' case ' + op.ACCEPT_STRING + ':', // ACCEPT_STRING s
360 ' stack.push(peg$consts[bc[ip + 1]]);',
361 ' peg$currPos += peg$consts[bc[ip + 1]].length;',
362 ' ip += 2;',
363 ' break;',
364 '',
365 ' case ' + op.FAIL + ':', // FAIL e
366 ' stack.push(peg$FAILED);',
367 ' if (peg$silentFails === 0) {',
368 ' peg$fail(peg$consts[bc[ip + 1]]);',
369 ' }',
370 ' ip += 2;',
371 ' break;',
372 '',
373 ' case ' + op.LOAD_SAVED_POS + ':', // LOAD_SAVED_POS p
374 ' peg$savedPos = stack[stack.length - 1 - bc[ip + 1]];',
375 ' ip += 2;',
376 ' break;',
377 '',
378 ' case ' + op.UPDATE_SAVED_POS + ':', // UPDATE_SAVED_POS
379 ' peg$savedPos = peg$currPos;',
380 ' ip++;',
381 ' break;',
382 '',
383 ' case ' + op.CALL + ':', // CALL f, n, pc, p1, p2, ..., pN
384 indent10(generateCall()),
385 '',
386 ' case ' + op.RULE + ':', // RULE r
387 ' stack.push(peg$parseRule(bc[ip + 1]));',
388 ' ip += 2;',
389 ' break;',
390 '',
391 ' case ' + op.SILENT_FAILS_ON + ':', // SILENT_FAILS_ON
392 ' peg$silentFails++;',
393 ' ip++;',
394 ' break;',
395 '',
396 ' case ' + op.SILENT_FAILS_OFF + ':', // SILENT_FAILS_OFF
397 ' peg$silentFails--;',
398 ' ip++;',
399 ' break;',
400 '',
401 ' default:',
402 ' throw new Error("Invalid opcode: " + bc[ip] + ".");',
403 ' }',
404 ' }',
405 '',
406 ' if (ends.length > 0) {',
407 ' end = ends.pop();',
408 ' ip = ips.pop();',
409 ' } else {',
410 ' break;',
411 ' }',
412 ' }'
413 ].join('\n'));
414
415 parts.push(indent2(generateRuleFooter('peg$ruleNames[index]', 'stack[0]')));
416 parts.push('}');
417
418 return parts.join('\n');
419 }
420
421 function generateRuleFunction(rule) {
422 var parts = [], code;
423
424 function c(i) { return "peg$c" + i; } // |consts[i]| of the abstract machine
425 function s(i) { return "s" + i; } // |stack[i]| of the abstract machine
426
427 var stack = {
428 sp: -1,
429 maxSp: -1,
430
431 push: function(exprCode) {
432 var code = s(++this.sp) + ' = ' + exprCode + ';';
433
434 if (this.sp > this.maxSp) { this.maxSp = this.sp; }
435
436 return code;
437 },
438
439 pop: function(n) {
440 var values;
441
442 if (n === void 0) {
443 return s(this.sp--);
444 } else {
445 values = arrays.map(arrays.range(this.sp - n + 1, this.sp + 1), s);
446 this.sp -= n;
447
448 return values;
449 }
450 },
451
452 top: function() {
453 return s(this.sp);
454 },
455
456 index: function(i) {
457 return s(this.sp - i);
458 }
459 };
460
461 function compile(bc) {
462 var ip = 0,
463 end = bc.length,
464 parts = [],
465 value;
466
467 function compileCondition(cond, argCount) {
468 var baseLength = argCount + 3,
469 thenLength = bc[ip + baseLength - 2],
470 elseLength = bc[ip + baseLength - 1],
471 baseSp = stack.sp,
472 thenCode, elseCode, thenSp, elseSp;
473
474 ip += baseLength;
475 thenCode = compile(bc.slice(ip, ip + thenLength));
476 thenSp = stack.sp;
477 ip += thenLength;
478
479 if (elseLength > 0) {
480 stack.sp = baseSp;
481 elseCode = compile(bc.slice(ip, ip + elseLength));
482 elseSp = stack.sp;
483 ip += elseLength;
484
485 if (thenSp !== elseSp) {
486 throw new Error(
487 "Branches of a condition must move the stack pointer in the same way."
488 );
489 }
490 }
491
492 parts.push('if (' + cond + ') {');
493 parts.push(indent2(thenCode));
494 if (elseLength > 0) {
495 parts.push('} else {');
496 parts.push(indent2(elseCode));
497 }
498 parts.push('}');
499 }
500
501 function compileLoop(cond) {
502 var baseLength = 2,
503 bodyLength = bc[ip + baseLength - 1],
504 baseSp = stack.sp,
505 bodyCode, bodySp;
506
507 ip += baseLength;
508 bodyCode = compile(bc.slice(ip, ip + bodyLength));
509 bodySp = stack.sp;
510 ip += bodyLength;
511
512 if (bodySp !== baseSp) {
513 throw new Error("Body of a loop can't move the stack pointer.");
514 }
515
516 parts.push('while (' + cond + ') {');
517 parts.push(indent2(bodyCode));
518 parts.push('}');
519 }
520
521 function compileCall() {
522 var baseLength = 4,
523 paramsLength = bc[ip + baseLength - 1];
524
525 var value = c(bc[ip + 1]) + '('
526 + arrays.map(
527 bc.slice(ip + baseLength, ip + baseLength + paramsLength),
528 function(p) { return stack.index(p); }
529 ).join(', ')
530 + ')';
531 stack.pop(bc[ip + 2]);
532 parts.push(stack.push(value));
533 ip += baseLength + paramsLength;
534 }
535
536 while (ip < end) {
537 switch (bc[ip]) {
538 case op.PUSH: // PUSH c
539 parts.push(stack.push(c(bc[ip + 1])));
540 ip += 2;
541 break;
542
543 case op.PUSH_CURR_POS: // PUSH_CURR_POS
544 parts.push(stack.push('peg$currPos'));
545 ip++;
546 break;
547
548 case op.PUSH_UNDEFINED: // PUSH_UNDEFINED
549 parts.push(stack.push('void 0'));
550 ip++;
551 break;
552
553 case op.PUSH_NULL: // PUSH_NULL
554 parts.push(stack.push('null'));
555 ip++;
556 break;
557
558 case op.PUSH_FAILED: // PUSH_FAILED
559 parts.push(stack.push('peg$FAILED'));
560 ip++;
561 break;
562
563 case op.PUSH_EMPTY_ARRAY: // PUSH_EMPTY_ARRAY
564 parts.push(stack.push('[]'));
565 ip++;
566 break;
567
568 case op.POP: // POP
569 stack.pop();
570 ip++;
571 break;
572
573 case op.POP_CURR_POS: // POP_CURR_POS
574 parts.push('peg$currPos = ' + stack.pop() + ';');
575 ip++;
576 break;
577
578 case op.POP_N: // POP_N n
579 stack.pop(bc[ip + 1]);
580 ip += 2;
581 break;
582
583 case op.NIP: // NIP
584 value = stack.pop();
585 stack.pop();
586 parts.push(stack.push(value));
587 ip++;
588 break;
589
590 case op.APPEND: // APPEND
591 value = stack.pop();
592 parts.push(stack.top() + '.push(' + value + ');');
593 ip++;
594 break;
595
596 case op.WRAP: // WRAP n
597 parts.push(
598 stack.push('[' + stack.pop(bc[ip + 1]).join(', ') + ']')
599 );
600 ip += 2;
601 break;
602
603 case op.TEXT: // TEXT
604 parts.push(
605 stack.push('input.substring(' + stack.pop() + ', peg$currPos)')
606 );
607 ip++;
608 break;
609
610 case op.IF: // IF t, f
611 compileCondition(stack.top(), 0);
612 break;
613
614 case op.IF_ERROR: // IF_ERROR t, f
615 compileCondition(stack.top() + ' === peg$FAILED', 0);
616 break;
617
618 case op.IF_NOT_ERROR: // IF_NOT_ERROR t, f
619 compileCondition(stack.top() + ' !== peg$FAILED', 0);
620 break;
621
622 case op.WHILE_NOT_ERROR: // WHILE_NOT_ERROR b
623 compileLoop(stack.top() + ' !== peg$FAILED', 0);
624 break;
625
626 case op.MATCH_ANY: // MATCH_ANY a, f, ...
627 compileCondition('input.length > peg$currPos', 0);
628 break;
629
630 case op.MATCH_STRING: // MATCH_STRING s, a, f, ...
631 compileCondition(
632 eval(ast.consts[bc[ip + 1]]).length > 1
633 ? 'input.substr(peg$currPos, '
634 + eval(ast.consts[bc[ip + 1]]).length
635 + ') === '
636 + c(bc[ip + 1])
637 : 'input.charCodeAt(peg$currPos) === '
638 + eval(ast.consts[bc[ip + 1]]).charCodeAt(0),
639 1
640 );
641 break;
642
643 case op.MATCH_STRING_IC: // MATCH_STRING_IC s, a, f, ...
644 compileCondition(
645 'input.substr(peg$currPos, '
646 + eval(ast.consts[bc[ip + 1]]).length
647 + ').toLowerCase() === '
648 + c(bc[ip + 1]),
649 1
650 );
651 break;
652
653 case op.MATCH_REGEXP: // MATCH_REGEXP r, a, f, ...
654 compileCondition(
655 c(bc[ip + 1]) + '.test(input.charAt(peg$currPos))',
656 1
657 );
658 break;
659
660 case op.ACCEPT_N: // ACCEPT_N n
661 parts.push(stack.push(
662 bc[ip + 1] > 1
663 ? 'input.substr(peg$currPos, ' + bc[ip + 1] + ')'
664 : 'input.charAt(peg$currPos)'
665 ));
666 parts.push(
667 bc[ip + 1] > 1
668 ? 'peg$currPos += ' + bc[ip + 1] + ';'
669 : 'peg$currPos++;'
670 );
671 ip += 2;
672 break;
673
674 case op.ACCEPT_STRING: // ACCEPT_STRING s
675 parts.push(stack.push(c(bc[ip + 1])));
676 parts.push(
677 eval(ast.consts[bc[ip + 1]]).length > 1
678 ? 'peg$currPos += ' + eval(ast.consts[bc[ip + 1]]).length + ';'
679 : 'peg$currPos++;'
680 );
681 ip += 2;
682 break;
683
684 case op.FAIL: // FAIL e
685 parts.push(stack.push('peg$FAILED'));
686 parts.push('if (peg$silentFails === 0) { peg$fail(' + c(bc[ip + 1]) + '); }');
687 ip += 2;
688 break;
689
690 case op.LOAD_SAVED_POS: // LOAD_SAVED_POS p
691 parts.push('peg$savedPos = ' + stack.index(bc[ip + 1]) + ';');
692 ip += 2;
693 break;
694
695 case op.UPDATE_SAVED_POS: // UPDATE_SAVED_POS
696 parts.push('peg$savedPos = peg$currPos;');
697 ip++;
698 break;
699
700 case op.CALL: // CALL f, n, pc, p1, p2, ..., pN
701 compileCall();
702 break;
703
704 case op.RULE: // RULE r
705 parts.push(stack.push("peg$parse" + ast.rules[bc[ip + 1]].name + "()"));
706 ip += 2;
707 break;
708
709 case op.SILENT_FAILS_ON: // SILENT_FAILS_ON
710 parts.push('peg$silentFails++;');
711 ip++;
712 break;
713
714 case op.SILENT_FAILS_OFF: // SILENT_FAILS_OFF
715 parts.push('peg$silentFails--;');
716 ip++;
717 break;
718
719 default:
720 throw new Error("Invalid opcode: " + bc[ip] + ".");
721 }
722 }
723
724 return parts.join('\n');
725 }
726
727 code = compile(rule.bytecode);
728
729 parts.push('function peg$parse' + rule.name + '() {');
730
731 if (options.trace) {
732 parts.push([
733 ' var ' + arrays.map(arrays.range(0, stack.maxSp + 1), s).join(', ') + ',',
734 ' startPos = peg$currPos;'
735 ].join('\n'));
736 } else {
737 parts.push(
738 ' var ' + arrays.map(arrays.range(0, stack.maxSp + 1), s).join(', ') + ';'
739 );
740 }
741
742 parts.push(indent2(generateRuleHeader(
743 '"' + js.stringEscape(rule.name) + '"',
744 asts.indexOfRule(ast, rule.name)
745 )));
746 parts.push(indent2(code));
747 parts.push(indent2(generateRuleFooter(
748 '"' + js.stringEscape(rule.name) + '"',
749 s(0)
750 )));
751
752 parts.push('}');
753
754 return parts.join('\n');
755 }
756
757 function generateToplevel() {
758 var parts = [],
759 startRuleIndices, startRuleIndex,
760 startRuleFunctions, startRuleFunction,
761 ruleNames;
762
763 parts.push([
764 'function peg$subclass(child, parent) {',
765 ' function ctor() { this.constructor = child; }',
766 ' ctor.prototype = parent.prototype;',
767 ' child.prototype = new ctor();',
768 '}',
769 '',
770 'function peg$SyntaxError(message, expected, found, location) {',
771 ' this.message = message;',
772 ' this.expected = expected;',
773 ' this.found = found;',
774 ' this.location = location;',
775 ' this.name = "SyntaxError";',
776 '',
777 ' if (typeof Error.captureStackTrace === "function") {',
778 ' Error.captureStackTrace(this, peg$SyntaxError);',
779 ' }',
780 '}',
781 '',
782 'peg$subclass(peg$SyntaxError, Error);',
783 '',
784 'peg$SyntaxError.buildMessage = function(expected, found) {',
785 ' var DESCRIBE_EXPECTATION_FNS = {',
786 ' literal: function(expectation) {',
787 ' return "\\\"" + literalEscape(expectation.text) + "\\\"";',
788 ' },',
789 '',
790 ' "class": function(expectation) {',
791 ' var escapedParts = "",',
792 ' i;',
793 '',
794 ' for (i = 0; i < expectation.parts.length; i++) {',
795 ' escapedParts += expectation.parts[i] instanceof Array',
796 ' ? classEscape(expectation.parts[i][0]) + "-" + classEscape(expectation.parts[i][1])',
797 ' : classEscape(expectation.parts[i]);',
798 ' }',
799 '',
800 ' return "[" + (expectation.inverted ? "^" : "") + escapedParts + "]";',
801 ' },',
802 '',
803 ' any: function(expectation) {',
804 ' return "any character";',
805 ' },',
806 '',
807 ' end: function(expectation) {',
808 ' return "end of input";',
809 ' },',
810 '',
811 ' other: function(expectation) {',
812 ' return expectation.description;',
813 ' }',
814 ' };',
815 '',
816 ' function hex(ch) {',
817 ' return ch.charCodeAt(0).toString(16).toUpperCase();',
818 ' }',
819 '',
820 ' function literalEscape(s) {',
821 ' return s',
822 ' .replace(/\\\\/g, \'\\\\\\\\\')', // backslash
823 ' .replace(/"/g, \'\\\\"\')', // closing double quote
824 ' .replace(/\\0/g, \'\\\\0\')', // null
825 ' .replace(/\\t/g, \'\\\\t\')', // horizontal tab
826 ' .replace(/\\n/g, \'\\\\n\')', // line feed
827 ' .replace(/\\r/g, \'\\\\r\')', // carriage return
828 ' .replace(/[\\x00-\\x0F]/g, function(ch) { return \'\\\\x0\' + hex(ch); })',
829 ' .replace(/[\\x10-\\x1F\\x7F-\\x9F]/g, function(ch) { return \'\\\\x\' + hex(ch); });',
830 ' }',
831 '',
832 ' function classEscape(s) {',
833 ' return s',
834 ' .replace(/\\\\/g, \'\\\\\\\\\')', // backslash
835 ' .replace(/\\]/g, \'\\\\]\')', // closing bracket
836 ' .replace(/\\^/g, \'\\\\^\')', // caret
837 ' .replace(/-/g, \'\\\\-\')', // dash
838 ' .replace(/\\0/g, \'\\\\0\')', // null
839 ' .replace(/\\t/g, \'\\\\t\')', // horizontal tab
840 ' .replace(/\\n/g, \'\\\\n\')', // line feed
841 ' .replace(/\\r/g, \'\\\\r\')', // carriage return
842 ' .replace(/[\\x00-\\x0F]/g, function(ch) { return \'\\\\x0\' + hex(ch); })',
843 ' .replace(/[\\x10-\\x1F\\x7F-\\x9F]/g, function(ch) { return \'\\\\x\' + hex(ch); });',
844 ' }',
845 '',
846 ' function describeExpectation(expectation) {',
847 ' return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation);',
848 ' }',
849 '',
850 ' function describeExpected(expected) {',
851 ' var descriptions = new Array(expected.length),',
852 ' i, j;',
853 '',
854 ' for (i = 0; i < expected.length; i++) {',
855 ' descriptions[i] = describeExpectation(expected[i]);',
856 ' }',
857 '',
858 ' descriptions.sort();',
859 '',
860 ' if (descriptions.length > 0) {',
861 ' for (i = 1, j = 1; i < descriptions.length; i++) {',
862 ' if (descriptions[i - 1] !== descriptions[i]) {',
863 ' descriptions[j] = descriptions[i];',
864 ' j++;',
865 ' }',
866 ' }',
867 ' descriptions.length = j;',
868 ' }',
869 '',
870 ' switch (descriptions.length) {',
871 ' case 1:',
872 ' return descriptions[0];',
873 '',
874 ' case 2:',
875 ' return descriptions[0] + " or " + descriptions[1];',
876 '',
877 ' default:',
878 ' return descriptions.slice(0, -1).join(", ")',
879 ' + ", or "',
880 ' + descriptions[descriptions.length - 1];',
881 ' }',
882 ' }',
883 '',
884 ' function describeFound(found) {',
885 ' return found ? "\\"" + literalEscape(found) + "\\"" : "end of input";',
886 ' }',
887 '',
888 ' return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found.";',
889 '};',
890 ''
891 ].join('\n'));
892
893 if (options.trace) {
894 parts.push([
895 'function peg$DefaultTracer() {',
896 ' this.indentLevel = 0;',
897 '}',
898 '',
899 'peg$DefaultTracer.prototype.trace = function(event) {',
900 ' var that = this;',
901 '',
902 ' function log(event) {',
903 ' function repeat(string, n) {',
904 ' var result = "", i;',
905 '',
906 ' for (i = 0; i < n; i++) {',
907 ' result += string;',
908 ' }',
909 '',
910 ' return result;',
911 ' }',
912 '',
913 ' function pad(string, length) {',
914 ' return string + repeat(" ", length - string.length);',
915 ' }',
916 '',
917 ' if (typeof console === "object") {', // IE 8-10
918 ' console.log(',
919 ' event.location.start.line + ":" + event.location.start.column + "-"',
920 ' + event.location.end.line + ":" + event.location.end.column + " "',
921 ' + pad(event.type, 10) + " "',
922 ' + repeat(" ", that.indentLevel) + event.rule',
923 ' );',
924 ' }',
925 ' }',
926 '',
927 ' switch (event.type) {',
928 ' case "rule.enter":',
929 ' log(event);',
930 ' this.indentLevel++;',
931 ' break;',
932 '',
933 ' case "rule.match":',
934 ' this.indentLevel--;',
935 ' log(event);',
936 ' break;',
937 '',
938 ' case "rule.fail":',
939 ' this.indentLevel--;',
940 ' log(event);',
941 ' break;',
942 '',
943 ' default:',
944 ' throw new Error("Invalid event type: " + event.type + ".");',
945 ' }',
946 '};',
947 ''
948 ].join('\n'));
949 }
950
951 parts.push([
952 'function peg$parse(input, options) {',
953 ' options = options !== void 0 ? options : {};',
954 '',
955 ' var peg$FAILED = {},',
956 ''
957 ].join('\n'));
958
959 if (options.optimize === "size") {
960 startRuleIndices = '{ '
961 + arrays.map(
962 options.allowedStartRules,
963 function(r) { return r + ': ' + asts.indexOfRule(ast, r); }
964 ).join(', ')
965 + ' }';
966 startRuleIndex = asts.indexOfRule(ast, options.allowedStartRules[0]);
967
968 parts.push([
969 ' peg$startRuleIndices = ' + startRuleIndices + ',',
970 ' peg$startRuleIndex = ' + startRuleIndex + ','
971 ].join('\n'));
972 } else {
973 startRuleFunctions = '{ '
974 + arrays.map(
975 options.allowedStartRules,
976 function(r) { return r + ': peg$parse' + r; }
977 ).join(', ')
978 + ' }';
979 startRuleFunction = 'peg$parse' + options.allowedStartRules[0];
980
981 parts.push([
982 ' peg$startRuleFunctions = ' + startRuleFunctions + ',',
983 ' peg$startRuleFunction = ' + startRuleFunction + ','
984 ].join('\n'));
985 }
986
987 parts.push('');
988
989 parts.push(indent6(generateTables()));
990
991 parts.push([
992 '',
993 ' peg$currPos = 0,',
994 ' peg$savedPos = 0,',
995 ' peg$posDetailsCache = [{ line: 1, column: 1 }],',
996 ' peg$maxFailPos = 0,',
997 ' peg$maxFailExpected = [],',
998 ' peg$silentFails = 0,', // 0 = report failures, > 0 = silence failures
999 ''
1000 ].join('\n'));
1001
1002 if (options.cache) {
1003 parts.push([
1004 ' peg$resultsCache = {},',
1005 ''
1006 ].join('\n'));
1007 }
1008
1009 if (options.trace) {
1010 if (options.optimize === "size") {
1011 ruleNames = '['
1012 + arrays.map(
1013 ast.rules,
1014 function(r) { return '"' + js.stringEscape(r.name) + '"'; }
1015 ).join(', ')
1016 + ']';
1017
1018 parts.push([
1019 ' peg$ruleNames = ' + ruleNames + ',',
1020 ''
1021 ].join('\n'));
1022 }
1023
1024 parts.push([
1025 ' peg$tracer = "tracer" in options ? options.tracer : new peg$DefaultTracer(),',
1026 ''
1027 ].join('\n'));
1028 }
1029
1030 parts.push([
1031 ' peg$result;',
1032 ''
1033 ].join('\n'));
1034
1035 if (options.optimize === "size") {
1036 parts.push([
1037 ' if ("startRule" in options) {',
1038 ' if (!(options.startRule in peg$startRuleIndices)) {',
1039 ' throw new Error("Can\'t start parsing from rule \\"" + options.startRule + "\\".");',
1040 ' }',
1041 '',
1042 ' peg$startRuleIndex = peg$startRuleIndices[options.startRule];',
1043 ' }'
1044 ].join('\n'));
1045 } else {
1046 parts.push([
1047 ' if ("startRule" in options) {',
1048 ' if (!(options.startRule in peg$startRuleFunctions)) {',
1049 ' throw new Error("Can\'t start parsing from rule \\"" + options.startRule + "\\".");',
1050 ' }',
1051 '',
1052 ' peg$startRuleFunction = peg$startRuleFunctions[options.startRule];',
1053 ' }'
1054 ].join('\n'));
1055 }
1056
1057 parts.push([
1058 '',
1059 ' function text() {',
1060 ' return input.substring(peg$savedPos, peg$currPos);',
1061 ' }',
1062 '',
1063 ' function location() {',
1064 ' return peg$computeLocation(peg$savedPos, peg$currPos);',
1065 ' }',
1066 '',
1067 ' function expected(description, location) {',
1068 ' location = location !== void 0 ? location : peg$computeLocation(peg$savedPos, peg$currPos)',
1069 '',
1070 ' throw peg$buildStructuredError(',
1071 ' [peg$otherExpectation(description)],',
1072 ' input.substring(peg$savedPos, peg$currPos),',
1073 ' location',
1074 ' );',
1075 ' }',
1076 '',
1077 ' function error(message, location) {',
1078 ' location = location !== void 0 ? location : peg$computeLocation(peg$savedPos, peg$currPos)',
1079 '',
1080 ' throw peg$buildSimpleError(message, location);',
1081 ' }',
1082 '',
1083 ' function peg$literalExpectation(text, ignoreCase) {',
1084 ' return { type: "literal", text: text, ignoreCase: ignoreCase };',
1085 ' }',
1086 '',
1087 ' function peg$classExpectation(parts, inverted, ignoreCase) {',
1088 ' return { type: "class", parts: parts, inverted: inverted, ignoreCase: ignoreCase };',
1089 ' }',
1090 '',
1091 ' function peg$anyExpectation() {',
1092 ' return { type: "any" };',
1093 ' }',
1094 '',
1095 ' function peg$endExpectation() {',
1096 ' return { type: "end" };',
1097 ' }',
1098 '',
1099 ' function peg$otherExpectation(description) {',
1100 ' return { type: "other", description: description };',
1101 ' }',
1102 '',
1103 ' function peg$computePosDetails(pos) {',
1104 ' var details = peg$posDetailsCache[pos], p;',
1105 '',
1106 ' if (details) {',
1107 ' return details;',
1108 ' } else {',
1109 ' p = pos - 1;',
1110 ' while (!peg$posDetailsCache[p]) {',
1111 ' p--;',
1112 ' }',
1113 '',
1114 ' details = peg$posDetailsCache[p];',
1115 ' details = {',
1116 ' line: details.line,',
1117 ' column: details.column',
1118 ' };',
1119 '',
1120 ' while (p < pos) {',
1121 ' if (input.charCodeAt(p) === 10) {',
1122 ' details.line++;',
1123 ' details.column = 1;',
1124 ' } else {',
1125 ' details.column++;',
1126 ' }',
1127 '',
1128 ' p++;',
1129 ' }',
1130 '',
1131 ' peg$posDetailsCache[pos] = details;',
1132 ' return details;',
1133 ' }',
1134 ' }',
1135 '',
1136 ' function peg$computeLocation(startPos, endPos) {',
1137 ' var startPosDetails = peg$computePosDetails(startPos),',
1138 ' endPosDetails = peg$computePosDetails(endPos);',
1139 '',
1140 ' return {',
1141 ' start: {',
1142 ' offset: startPos,',
1143 ' line: startPosDetails.line,',
1144 ' column: startPosDetails.column',
1145 ' },',
1146 ' end: {',
1147 ' offset: endPos,',
1148 ' line: endPosDetails.line,',
1149 ' column: endPosDetails.column',
1150 ' }',
1151 ' };',
1152 ' }',
1153 '',
1154 ' function peg$fail(expected) {',
1155 ' if (peg$currPos < peg$maxFailPos) { return; }',
1156 '',
1157 ' if (peg$currPos > peg$maxFailPos) {',
1158 ' peg$maxFailPos = peg$currPos;',
1159 ' peg$maxFailExpected = [];',
1160 ' }',
1161 '',
1162 ' peg$maxFailExpected.push(expected);',
1163 ' }',
1164 '',
1165 ' function peg$buildSimpleError(message, location) {',
1166 ' return new peg$SyntaxError(message, null, null, location);',
1167 ' }',
1168 '',
1169 ' function peg$buildStructuredError(expected, found, location) {',
1170 ' return new peg$SyntaxError(',
1171 ' peg$SyntaxError.buildMessage(expected, found),',
1172 ' expected,',
1173 ' found,',
1174 ' location',
1175 ' );',
1176 ' }',
1177 ''
1178 ].join('\n'));
1179
1180 if (options.optimize === "size") {
1181 parts.push(indent2(generateInterpreter()));
1182 parts.push('');
1183 } else {
1184 arrays.each(ast.rules, function(rule) {
1185 parts.push(indent2(generateRuleFunction(rule)));
1186 parts.push('');
1187 });
1188 }
1189
1190 if (ast.initializer) {
1191 parts.push(indent2(ast.initializer.code));
1192 parts.push('');
1193 }
1194
1195 if (options.optimize === "size") {
1196 parts.push(' peg$result = peg$parseRule(peg$startRuleIndex);');
1197 } else {
1198 parts.push(' peg$result = peg$startRuleFunction();');
1199 }
1200
1201 parts.push([
1202 '',
1203 ' if (peg$result !== peg$FAILED && peg$currPos === input.length) {',
1204 ' return peg$result;',
1205 ' } else {',
1206 ' if (peg$result !== peg$FAILED && peg$currPos < input.length) {',
1207 ' peg$fail(peg$endExpectation());',
1208 ' }',
1209 '',
1210 ' throw peg$buildStructuredError(',
1211 ' peg$maxFailExpected,',
1212 ' peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null,',
1213 ' peg$maxFailPos < input.length',
1214 ' ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1)',
1215 ' : peg$computeLocation(peg$maxFailPos, peg$maxFailPos)',
1216 ' );',
1217 ' }',
1218 '}'
1219 ].join('\n'));
1220
1221 return parts.join('\n');
1222 }
1223
1224 function generateWrapper(toplevelCode) {
1225 function generateGeneratedByComment() {
1226 return [
1227 '/*',
1228 ' * Generated by PEG.js 0.10.0.',
1229 ' *',
1230 ' * http://pegjs.org/',
1231 ' */'
1232 ].join('\n');
1233 }
1234
1235 function generateParserObject() {
1236 return options.trace
1237 ? [
1238 '{',
1239 ' SyntaxError: peg$SyntaxError,',
1240 ' DefaultTracer: peg$DefaultTracer,',
1241 ' parse: peg$parse',
1242 '}'
1243 ].join('\n')
1244 : [
1245 '{',
1246 ' SyntaxError: peg$SyntaxError,',
1247 ' parse: peg$parse',
1248 '}'
1249 ].join('\n');
1250 }
1251
1252 var generators = {
1253 bare: function() {
1254 return [
1255 generateGeneratedByComment(),
1256 '(function() {',
1257 ' "use strict";',
1258 '',
1259 indent2(toplevelCode),
1260 '',
1261 indent2('return ' + generateParserObject() + ';'),
1262 '})()'
1263 ].join('\n');
1264 },
1265
1266 commonjs: function() {
1267 var parts = [],
1268 dependencyVars = objects.keys(options.dependencies),
1269 requires = arrays.map(
1270 dependencyVars,
1271 function(variable) {
1272 return variable
1273 + ' = require("'
1274 + js.stringEscape(options.dependencies[variable])
1275 + '")';
1276 }
1277 );
1278
1279 parts.push([
1280 generateGeneratedByComment(),
1281 '',
1282 '"use strict";',
1283 ''
1284 ].join('\n'));
1285
1286 if (requires.length > 0) {
1287 parts.push('var ' + requires.join(', ') + ';');
1288 parts.push('');
1289 }
1290
1291 parts.push([
1292 toplevelCode,
1293 '',
1294 'module.exports = ' + generateParserObject() + ';',
1295 ''
1296 ].join('\n'));
1297
1298 return parts.join('\n');
1299 },
1300
1301 amd: function() {
1302 var dependencyIds = objects.values(options.dependencies),
1303 dependencyVars = objects.keys(options.dependencies),
1304 dependencies = '['
1305 + arrays.map(
1306 dependencyIds,
1307 function(id) { return '"' + js.stringEscape(id) + '"'; }
1308 ).join(', ')
1309 + ']',
1310 params = dependencyVars.join(', ');
1311
1312 return [
1313 generateGeneratedByComment(),
1314 'define(' + dependencies + ', function(' + params + ') {',
1315 ' "use strict";',
1316 '',
1317 indent2(toplevelCode),
1318 '',
1319 indent2('return ' + generateParserObject() + ';'),
1320 '});',
1321 ''
1322 ].join('\n');
1323 },
1324
1325 globals: function() {
1326 return [
1327 generateGeneratedByComment(),
1328 '(function(root) {',
1329 ' "use strict";',
1330 '',
1331 indent2(toplevelCode),
1332 '',
1333 indent2('root.' + options.exportVar + ' = ' + generateParserObject() + ';'),
1334 '})(this);',
1335 ''
1336 ].join('\n');
1337 },
1338
1339 umd: function() {
1340 var parts = [],
1341 dependencyIds = objects.values(options.dependencies),
1342 dependencyVars = objects.keys(options.dependencies),
1343 dependencies = '['
1344 + arrays.map(
1345 dependencyIds,
1346 function(id) { return '"' + js.stringEscape(id) + '"'; }
1347 ).join(', ')
1348 + ']',
1349 requires = arrays.map(
1350 dependencyIds,
1351 function(id) { return 'require("' + js.stringEscape(id) + '")'; }
1352 ).join(', '),
1353 params = dependencyVars.join(', ');
1354
1355 parts.push([
1356 generateGeneratedByComment(),
1357 '(function(root, factory) {',
1358 ' if (typeof define === "function" && define.amd) {',
1359 ' define(' + dependencies + ', factory);',
1360 ' } else if (typeof module === "object" && module.exports) {',
1361 ' module.exports = factory(' + requires + ');'
1362 ].join('\n'));
1363
1364 if (options.exportVar !== null) {
1365 parts.push([
1366 ' } else {',
1367 ' root.' + options.exportVar + ' = factory();'
1368 ].join('\n'));
1369 }
1370
1371 parts.push([
1372 ' }',
1373 '})(this, function(' + params + ') {',
1374 ' "use strict";',
1375 '',
1376 indent2(toplevelCode),
1377 '',
1378 indent2('return ' + generateParserObject() + ';'),
1379 '});',
1380 ''
1381 ].join('\n'));
1382
1383 return parts.join('\n');
1384 }
1385 };
1386
1387 return generators[options.format]();
1388 }
1389
1390 ast.code = generateWrapper(generateToplevel());
1391 }
1392
1393 module.exports = generateJS;
0 "use strict";
1
2 var arrays = require("../../utils/arrays"),
3 visitor = require("../visitor");
4
5 /*
6 * Removes proxy rules -- that is, rules that only delegate to other rule.
7 */
8 function removeProxyRules(ast, options) {
9 function isProxyRule(node) {
10 return node.type === "rule" && node.expression.type === "rule_ref";
11 }
12
13 function replaceRuleRefs(ast, from, to) {
14 var replace = visitor.build({
15 rule_ref: function(node) {
16 if (node.name === from) {
17 node.name = to;
18 }
19 }
20 });
21
22 replace(ast);
23 }
24
25 var indices = [];
26
27 arrays.each(ast.rules, function(rule, i) {
28 if (isProxyRule(rule)) {
29 replaceRuleRefs(ast, rule.name, rule.expression.name);
30 if (!arrays.contains(options.allowedStartRules, rule.name)) {
31 indices.push(i);
32 }
33 }
34 });
35
36 indices.reverse();
37
38 arrays.each(indices, function(i) { ast.rules.splice(i, 1); });
39 }
40
41 module.exports = removeProxyRules;
0 "use strict";
1
2 var GrammarError = require("../../grammar-error"),
3 arrays = require("../../utils/arrays"),
4 objects = require("../../utils/objects"),
5 visitor = require("../visitor");
6
7 /* Checks that each label is defined only once within each scope. */
8 function reportDuplicateLabels(ast) {
9 function checkExpressionWithClonedEnv(node, env) {
10 check(node.expression, objects.clone(env));
11 }
12
13 var check = visitor.build({
14 rule: function(node) {
15 check(node.expression, { });
16 },
17
18 choice: function(node, env) {
19 arrays.each(node.alternatives, function(alternative) {
20 check(alternative, objects.clone(env));
21 });
22 },
23
24 action: checkExpressionWithClonedEnv,
25
26 labeled: function(node, env) {
27 if (env.hasOwnProperty(node.label)) {
28 throw new GrammarError(
29 "Label \"" + node.label + "\" is already defined "
30 + "at line " + env[node.label].start.line + ", "
31 + "column " + env[node.label].start.column + ".",
32 node.location
33 );
34 }
35
36 check(node.expression, env);
37
38 env[node.label] = node.location;
39 },
40
41 text: checkExpressionWithClonedEnv,
42 simple_and: checkExpressionWithClonedEnv,
43 simple_not: checkExpressionWithClonedEnv,
44 optional: checkExpressionWithClonedEnv,
45 zero_or_more: checkExpressionWithClonedEnv,
46 one_or_more: checkExpressionWithClonedEnv,
47 group: checkExpressionWithClonedEnv
48 });
49
50 check(ast);
51 }
52
53 module.exports = reportDuplicateLabels;
0 "use strict";
1
2 var GrammarError = require("../../grammar-error"),
3 visitor = require("../visitor");
4
5 /* Checks that each rule is defined only once. */
6 function reportDuplicateRules(ast) {
7 var rules = {};
8
9 var check = visitor.build({
10 rule: function(node) {
11 if (rules.hasOwnProperty(node.name)) {
12 throw new GrammarError(
13 "Rule \"" + node.name + "\" is already defined "
14 + "at line " + rules[node.name].start.line + ", "
15 + "column " + rules[node.name].start.column + ".",
16 node.location
17 );
18 }
19
20 rules[node.name] = node.location;
21 }
22 });
23
24 check(ast);
25 }
26
27 module.exports = reportDuplicateRules;
0 "use strict";
1
2 var arrays = require("../../utils/arrays"),
3 GrammarError = require("../../grammar-error"),
4 asts = require("../asts"),
5 visitor = require("../visitor");
6
7 /*
8 * Reports left recursion in the grammar, which prevents infinite recursion in
9 * the generated parser.
10 *
11 * Both direct and indirect recursion is detected. The pass also correctly
12 * reports cases like this:
13 *
14 * start = "a"? start
15 *
16 * In general, if a rule reference can be reached without consuming any input,
17 * it can lead to left recursion.
18 */
19 function reportInfiniteRecursion(ast) {
20 var visitedRules = [];
21
22 var check = visitor.build({
23 rule: function(node) {
24 visitedRules.push(node.name);
25 check(node.expression);
26 visitedRules.pop(node.name);
27 },
28
29 sequence: function(node) {
30 arrays.every(node.elements, function(element) {
31 check(element);
32
33 return !asts.alwaysConsumesOnSuccess(ast, element);
34 });
35 },
36
37 rule_ref: function(node) {
38 if (arrays.contains(visitedRules, node.name)) {
39 visitedRules.push(node.name);
40
41 throw new GrammarError(
42 "Possible infinite loop when parsing (left recursion: "
43 + visitedRules.join(" -> ")
44 + ").",
45 node.location
46 );
47 }
48
49 check(asts.findRule(ast, node.name));
50 }
51 });
52
53 check(ast);
54 }
55
56 module.exports = reportInfiniteRecursion;
0 "use strict";
1
2 var GrammarError = require("../../grammar-error"),
3 asts = require("../asts"),
4 visitor = require("../visitor");
5
6 /*
7 * Reports expressions that don't consume any input inside |*| or |+| in the
8 * grammar, which prevents infinite loops in the generated parser.
9 */
10 function reportInfiniteRepetition(ast) {
11 var check = visitor.build({
12 zero_or_more: function(node) {
13 if (!asts.alwaysConsumesOnSuccess(ast, node.expression)) {
14 throw new GrammarError(
15 "Possible infinite loop when parsing (repetition used with an expression that may not consume any input).",
16 node.location
17 );
18 }
19 },
20
21 one_or_more: function(node) {
22 if (!asts.alwaysConsumesOnSuccess(ast, node.expression)) {
23 throw new GrammarError(
24 "Possible infinite loop when parsing (repetition used with an expression that may not consume any input).",
25 node.location
26 );
27 }
28 }
29 });
30
31 check(ast);
32 }
33
34 module.exports = reportInfiniteRepetition;
0 "use strict";
1
2 var GrammarError = require("../../grammar-error"),
3 asts = require("../asts"),
4 visitor = require("../visitor");
5
6 /* Checks that all referenced rules exist. */
7 function reportUndefinedRules(ast) {
8 var check = visitor.build({
9 rule_ref: function(node) {
10 if (!asts.findRule(ast, node.name)) {
11 throw new GrammarError(
12 "Rule \"" + node.name + "\" is not defined.",
13 node.location
14 );
15 }
16 }
17 });
18
19 check(ast);
20 }
21
22 module.exports = reportUndefinedRules;
0 "use strict";
1
2 var objects = require("../utils/objects"),
3 arrays = require("../utils/arrays");
4
5 /* Simple AST node visitor builder. */
6 var visitor = {
7 build: function(functions) {
8 function visit(node) {
9 return functions[node.type].apply(null, arguments);
10 }
11
12 function visitNop() { }
13
14 function visitExpression(node) {
15 var extraArgs = Array.prototype.slice.call(arguments, 1);
16
17 visit.apply(null, [node.expression].concat(extraArgs));
18 }
19
20 function visitChildren(property) {
21 return function(node) {
22 var extraArgs = Array.prototype.slice.call(arguments, 1);
23
24 arrays.each(node[property], function(child) {
25 visit.apply(null, [child].concat(extraArgs));
26 });
27 };
28 }
29
30 var DEFAULT_FUNCTIONS = {
31 grammar: function(node) {
32 var extraArgs = Array.prototype.slice.call(arguments, 1);
33
34 if (node.initializer) {
35 visit.apply(null, [node.initializer].concat(extraArgs));
36 }
37
38 arrays.each(node.rules, function(rule) {
39 visit.apply(null, [rule].concat(extraArgs));
40 });
41 },
42
43 initializer: visitNop,
44 rule: visitExpression,
45 named: visitExpression,
46 choice: visitChildren("alternatives"),
47 action: visitExpression,
48 sequence: visitChildren("elements"),
49 labeled: visitExpression,
50 text: visitExpression,
51 simple_and: visitExpression,
52 simple_not: visitExpression,
53 optional: visitExpression,
54 zero_or_more: visitExpression,
55 one_or_more: visitExpression,
56 group: visitExpression,
57 semantic_and: visitNop,
58 semantic_not: visitNop,
59 rule_ref: visitNop,
60 literal: visitNop,
61 "class": visitNop,
62 any: visitNop
63 };
64
65 objects.defaults(functions, DEFAULT_FUNCTIONS);
66
67 return visit;
68 }
69 };
70
71 module.exports = visitor;
0 "use strict";
1
2 var classes = require("./utils/classes");
3
4 /* Thrown when the grammar contains an error. */
5 function GrammarError(message, location) {
6 this.name = "GrammarError";
7 this.message = message;
8 this.location = location;
9
10 if (typeof Error.captureStackTrace === "function") {
11 Error.captureStackTrace(this, GrammarError);
12 }
13 }
14
15 classes.subclass(GrammarError, Error);
16
17 module.exports = GrammarError;
0 /* eslint-env node, amd */
1 /* eslint no-unused-vars: 0 */
2
3 /*
4 * Generated by PEG.js 0.10.0.
5 *
6 * http://pegjs.org/
7 */
8
9 "use strict";
10
11 function peg$subclass(child, parent) {
12 function ctor() { this.constructor = child; }
13 ctor.prototype = parent.prototype;
14 child.prototype = new ctor();
15 }
16
17 function peg$SyntaxError(message, expected, found, location) {
18 this.message = message;
19 this.expected = expected;
20 this.found = found;
21 this.location = location;
22 this.name = "SyntaxError";
23
24 if (typeof Error.captureStackTrace === "function") {
25 Error.captureStackTrace(this, peg$SyntaxError);
26 }
27 }
28
29 peg$subclass(peg$SyntaxError, Error);
30
31 peg$SyntaxError.buildMessage = function(expected, found) {
32 var DESCRIBE_EXPECTATION_FNS = {
33 literal: function(expectation) {
34 return "\"" + literalEscape(expectation.text) + "\"";
35 },
36
37 "class": function(expectation) {
38 var escapedParts = "",
39 i;
40
41 for (i = 0; i < expectation.parts.length; i++) {
42 escapedParts += expectation.parts[i] instanceof Array
43 ? classEscape(expectation.parts[i][0]) + "-" + classEscape(expectation.parts[i][1])
44 : classEscape(expectation.parts[i]);
45 }
46
47 return "[" + (expectation.inverted ? "^" : "") + escapedParts + "]";
48 },
49
50 any: function(expectation) {
51 return "any character";
52 },
53
54 end: function(expectation) {
55 return "end of input";
56 },
57
58 other: function(expectation) {
59 return expectation.description;
60 }
61 };
62
63 function hex(ch) {
64 return ch.charCodeAt(0).toString(16).toUpperCase();
65 }
66
67 function literalEscape(s) {
68 return s
69 .replace(/\\/g, '\\\\')
70 .replace(/"/g, '\\"')
71 .replace(/\0/g, '\\0')
72 .replace(/\t/g, '\\t')
73 .replace(/\n/g, '\\n')
74 .replace(/\r/g, '\\r')
75 .replace(/[\x00-\x0F]/g, function(ch) { return '\\x0' + hex(ch); })
76 .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return '\\x' + hex(ch); });
77 }
78
79 function classEscape(s) {
80 return s
81 .replace(/\\/g, '\\\\')
82 .replace(/\]/g, '\\]')
83 .replace(/\^/g, '\\^')
84 .replace(/-/g, '\\-')
85 .replace(/\0/g, '\\0')
86 .replace(/\t/g, '\\t')
87 .replace(/\n/g, '\\n')
88 .replace(/\r/g, '\\r')
89 .replace(/[\x00-\x0F]/g, function(ch) { return '\\x0' + hex(ch); })
90 .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return '\\x' + hex(ch); });
91 }
92
93 function describeExpectation(expectation) {
94 return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation);
95 }
96
97 function describeExpected(expected) {
98 var descriptions = new Array(expected.length),
99 i, j;
100
101 for (i = 0; i < expected.length; i++) {
102 descriptions[i] = describeExpectation(expected[i]);
103 }
104
105 descriptions.sort();
106
107 if (descriptions.length > 0) {
108 for (i = 1, j = 1; i < descriptions.length; i++) {
109 if (descriptions[i - 1] !== descriptions[i]) {
110 descriptions[j] = descriptions[i];
111 j++;
112 }
113 }
114 descriptions.length = j;
115 }
116
117 switch (descriptions.length) {
118 case 1:
119 return descriptions[0];
120
121 case 2:
122 return descriptions[0] + " or " + descriptions[1];
123
124 default:
125 return descriptions.slice(0, -1).join(", ")
126 + ", or "
127 + descriptions[descriptions.length - 1];
128 }
129 }
130
131 function describeFound(found) {
132 return found ? "\"" + literalEscape(found) + "\"" : "end of input";
133 }
134
135 return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found.";
136 };
137
138 function peg$parse(input, options) {
139 options = options !== void 0 ? options : {};
140
141 var peg$FAILED = {},
142
143 peg$startRuleFunctions = { Grammar: peg$parseGrammar },
144 peg$startRuleFunction = peg$parseGrammar,
145
146 peg$c0 = function(initializer, rules) {
147 return {
148 type: "grammar",
149 initializer: extractOptional(initializer, 0),
150 rules: extractList(rules, 0),
151 location: location()
152 };
153 },
154 peg$c1 = function(code) {
155 return { type: "initializer", code: code, location: location() };
156 },
157 peg$c2 = "=",
158 peg$c3 = peg$literalExpectation("=", false),
159 peg$c4 = function(name, displayName, expression) {
160 return {
161 type: "rule",
162 name: name,
163 expression: displayName !== null
164 ? {
165 type: "named",
166 name: displayName[0],
167 expression: expression,
168 location: location()
169 }
170 : expression,
171 location: location()
172 };
173 },
174 peg$c5 = "/",
175 peg$c6 = peg$literalExpectation("/", false),
176 peg$c7 = function(head, tail) {
177 return tail.length > 0
178 ? {
179 type: "choice",
180 alternatives: buildList(head, tail, 3),
181 location: location()
182 }
183 : head;
184 },
185 peg$c8 = function(expression, code) {
186 return code !== null
187 ? {
188 type: "action",
189 expression: expression,
190 code: code[1],
191 location: location()
192 }
193 : expression;
194 },
195 peg$c9 = function(head, tail) {
196 return tail.length > 0
197 ? {
198 type: "sequence",
199 elements: buildList(head, tail, 1),
200 location: location()
201 }
202 : head;
203 },
204 peg$c10 = ":",
205 peg$c11 = peg$literalExpectation(":", false),
206 peg$c12 = function(label, expression) {
207 return {
208 type: "labeled",
209 label: label,
210 expression: expression,
211 location: location()
212 };
213 },
214 peg$c13 = function(operator, expression) {
215 return {
216 type: OPS_TO_PREFIXED_TYPES[operator],
217 expression: expression,
218 location: location()
219 };
220 },
221 peg$c14 = "$",
222 peg$c15 = peg$literalExpectation("$", false),
223 peg$c16 = "&",
224 peg$c17 = peg$literalExpectation("&", false),
225 peg$c18 = "!",
226 peg$c19 = peg$literalExpectation("!", false),
227 peg$c20 = function(expression, operator) {
228 return {
229 type: OPS_TO_SUFFIXED_TYPES[operator],
230 expression: expression,
231 location: location()
232 };
233 },
234 peg$c21 = "?",
235 peg$c22 = peg$literalExpectation("?", false),
236 peg$c23 = "*",
237 peg$c24 = peg$literalExpectation("*", false),
238 peg$c25 = "+",
239 peg$c26 = peg$literalExpectation("+", false),
240 peg$c27 = "(",
241 peg$c28 = peg$literalExpectation("(", false),
242 peg$c29 = ")",
243 peg$c30 = peg$literalExpectation(")", false),
244 peg$c31 = function(expression) {
245 /*
246 * The purpose of the "group" AST node is just to isolate label scope. We
247 * don't need to put it around nodes that can't contain any labels or
248 * nodes that already isolate label scope themselves. This leaves us with
249 * "labeled" and "sequence".
250 */
251 return expression.type === 'labeled' || expression.type === 'sequence'
252 ? { type: "group", expression: expression }
253 : expression;
254 },
255 peg$c32 = function(name) {
256 return { type: "rule_ref", name: name, location: location() };
257 },
258 peg$c33 = function(operator, code) {
259 return {
260 type: OPS_TO_SEMANTIC_PREDICATE_TYPES[operator],
261 code: code,
262 location: location()
263 };
264 },
265 peg$c34 = peg$anyExpectation(),
266 peg$c35 = peg$otherExpectation("whitespace"),
267 peg$c36 = "\t",
268 peg$c37 = peg$literalExpectation("\t", false),
269 peg$c38 = "\x0B",
270 peg$c39 = peg$literalExpectation("\x0B", false),
271 peg$c40 = "\f",
272 peg$c41 = peg$literalExpectation("\f", false),
273 peg$c42 = " ",
274 peg$c43 = peg$literalExpectation(" ", false),
275 peg$c44 = "\xA0",
276 peg$c45 = peg$literalExpectation("\xA0", false),
277 peg$c46 = "\uFEFF",
278 peg$c47 = peg$literalExpectation("\uFEFF", false),
279 peg$c48 = /^[\n\r\u2028\u2029]/,
280 peg$c49 = peg$classExpectation(["\n", "\r", "\u2028", "\u2029"], false, false),
281 peg$c50 = peg$otherExpectation("end of line"),
282 peg$c51 = "\n",
283 peg$c52 = peg$literalExpectation("\n", false),
284 peg$c53 = "\r\n",
285 peg$c54 = peg$literalExpectation("\r\n", false),
286 peg$c55 = "\r",
287 peg$c56 = peg$literalExpectation("\r", false),
288 peg$c57 = "\u2028",
289 peg$c58 = peg$literalExpectation("\u2028", false),
290 peg$c59 = "\u2029",
291 peg$c60 = peg$literalExpectation("\u2029", false),
292 peg$c61 = peg$otherExpectation("comment"),
293 peg$c62 = "/*",
294 peg$c63 = peg$literalExpectation("/*", false),
295 peg$c64 = "*/",
296 peg$c65 = peg$literalExpectation("*/", false),
297 peg$c66 = "//",
298 peg$c67 = peg$literalExpectation("//", false),
299 peg$c68 = function(name) { return name; },
300 peg$c69 = peg$otherExpectation("identifier"),
301 peg$c70 = function(head, tail) { return head + tail.join(""); },
302 peg$c71 = "_",
303 peg$c72 = peg$literalExpectation("_", false),
304 peg$c73 = "\\",
305 peg$c74 = peg$literalExpectation("\\", false),
306 peg$c75 = function(sequence) { return sequence; },
307 peg$c76 = "\u200C",
308 peg$c77 = peg$literalExpectation("\u200C", false),
309 peg$c78 = "\u200D",
310 peg$c79 = peg$literalExpectation("\u200D", false),
311 peg$c80 = peg$otherExpectation("literal"),
312 peg$c81 = "i",
313 peg$c82 = peg$literalExpectation("i", false),
314 peg$c83 = function(value, ignoreCase) {
315 return {
316 type: "literal",
317 value: value,
318 ignoreCase: ignoreCase !== null,
319 location: location()
320 };
321 },
322 peg$c84 = peg$otherExpectation("string"),
323 peg$c85 = "\"",
324 peg$c86 = peg$literalExpectation("\"", false),
325 peg$c87 = function(chars) { return chars.join(""); },
326 peg$c88 = "'",
327 peg$c89 = peg$literalExpectation("'", false),
328 peg$c90 = function() { return text(); },
329 peg$c91 = peg$otherExpectation("character class"),
330 peg$c92 = "[",
331 peg$c93 = peg$literalExpectation("[", false),
332 peg$c94 = "^",
333 peg$c95 = peg$literalExpectation("^", false),
334 peg$c96 = "]",
335 peg$c97 = peg$literalExpectation("]", false),
336 peg$c98 = function(inverted, parts, ignoreCase) {
337 return {
338 type: "class",
339 parts: filterEmptyStrings(parts),
340 inverted: inverted !== null,
341 ignoreCase: ignoreCase !== null,
342 location: location()
343 };
344 },
345 peg$c99 = "-",
346 peg$c100 = peg$literalExpectation("-", false),
347 peg$c101 = function(begin, end) {
348 if (begin.charCodeAt(0) > end.charCodeAt(0)) {
349 error(
350 "Invalid character range: " + text() + "."
351 );
352 }
353
354 return [begin, end];
355 },
356 peg$c102 = function() { return ""; },
357 peg$c103 = "0",
358 peg$c104 = peg$literalExpectation("0", false),
359 peg$c105 = function() { return "\0"; },
360 peg$c106 = "b",
361 peg$c107 = peg$literalExpectation("b", false),
362 peg$c108 = function() { return "\b"; },
363 peg$c109 = "f",
364 peg$c110 = peg$literalExpectation("f", false),
365 peg$c111 = function() { return "\f"; },
366 peg$c112 = "n",
367 peg$c113 = peg$literalExpectation("n", false),
368 peg$c114 = function() { return "\n"; },
369 peg$c115 = "r",
370 peg$c116 = peg$literalExpectation("r", false),
371 peg$c117 = function() { return "\r"; },
372 peg$c118 = "t",
373 peg$c119 = peg$literalExpectation("t", false),
374 peg$c120 = function() { return "\t"; },
375 peg$c121 = "v",
376 peg$c122 = peg$literalExpectation("v", false),
377 peg$c123 = function() { return "\x0B"; },
378 peg$c124 = "x",
379 peg$c125 = peg$literalExpectation("x", false),
380 peg$c126 = "u",
381 peg$c127 = peg$literalExpectation("u", false),
382 peg$c128 = function(digits) {
383 return String.fromCharCode(parseInt(digits, 16));
384 },
385 peg$c129 = /^[0-9]/,
386 peg$c130 = peg$classExpectation([["0", "9"]], false, false),
387 peg$c131 = /^[0-9a-f]/i,
388 peg$c132 = peg$classExpectation([["0", "9"], ["a", "f"]], false, true),
389 peg$c133 = ".",
390 peg$c134 = peg$literalExpectation(".", false),
391 peg$c135 = function() { return { type: "any", location: location() }; },
392 peg$c136 = peg$otherExpectation("code block"),
393 peg$c137 = "{",
394 peg$c138 = peg$literalExpectation("{", false),
395 peg$c139 = "}",
396 peg$c140 = peg$literalExpectation("}", false),
397 peg$c141 = function(code) { return code; },
398 peg$c142 = /^[{}]/,
399 peg$c143 = peg$classExpectation(["{", "}"], false, false),
400 peg$c144 = /^[a-z\xB5\xDF-\xF6\xF8-\xFF\u0101\u0103\u0105\u0107\u0109\u010B\u010D\u010F\u0111\u0113\u0115\u0117\u0119\u011B\u011D\u011F\u0121\u0123\u0125\u0127\u0129\u012B\u012D\u012F\u0131\u0133\u0135\u0137-\u0138\u013A\u013C\u013E\u0140\u0142\u0144\u0146\u0148-\u0149\u014B\u014D\u014F\u0151\u0153\u0155\u0157\u0159\u015B\u015D\u015F\u0161\u0163\u0165\u0167\u0169\u016B\u016D\u016F\u0171\u0173\u0175\u0177\u017A\u017C\u017E-\u0180\u0183\u0185\u0188\u018C-\u018D\u0192\u0195\u0199-\u019B\u019E\u01A1\u01A3\u01A5\u01A8\u01AA-\u01AB\u01AD\u01B0\u01B4\u01B6\u01B9-\u01BA\u01BD-\u01BF\u01C6\u01C9\u01CC\u01CE\u01D0\u01D2\u01D4\u01D6\u01D8\u01DA\u01DC-\u01DD\u01DF\u01E1\u01E3\u01E5\u01E7\u01E9\u01EB\u01ED\u01EF-\u01F0\u01F3\u01F5\u01F9\u01FB\u01FD\u01FF\u0201\u0203\u0205\u0207\u0209\u020B\u020D\u020F\u0211\u0213\u0215\u0217\u0219\u021B\u021D\u021F\u0221\u0223\u0225\u0227\u0229\u022B\u022D\u022F\u0231\u0233-\u0239\u023C\u023F-\u0240\u0242\u0247\u0249\u024B\u024D\u024F-\u0293\u0295-\u02AF\u0371\u0373\u0377\u037B-\u037D\u0390\u03AC-\u03CE\u03D0-\u03D1\u03D5-\u03D7\u03D9\u03DB\u03DD\u03DF\u03E1\u03E3\u03E5\u03E7\u03E9\u03EB\u03ED\u03EF-\u03F3\u03F5\u03F8\u03FB-\u03FC\u0430-\u045F\u0461\u0463\u0465\u0467\u0469\u046B\u046D\u046F\u0471\u0473\u0475\u0477\u0479\u047B\u047D\u047F\u0481\u048B\u048D\u048F\u0491\u0493\u0495\u0497\u0499\u049B\u049D\u049F\u04A1\u04A3\u04A5\u04A7\u04A9\u04AB\u04AD\u04AF\u04B1\u04B3\u04B5\u04B7\u04B9\u04BB\u04BD\u04BF\u04C2\u04C4\u04C6\u04C8\u04CA\u04CC\u04CE-\u04CF\u04D1\u04D3\u04D5\u04D7\u04D9\u04DB\u04DD\u04DF\u04E1\u04E3\u04E5\u04E7\u04E9\u04EB\u04ED\u04EF\u04F1\u04F3\u04F5\u04F7\u04F9\u04FB\u04FD\u04FF\u0501\u0503\u0505\u0507\u0509\u050B\u050D\u050F\u0511\u0513\u0515\u0517\u0519\u051B\u051D\u051F\u0521\u0523\u0525\u0527\u0529\u052B\u052D\u052F\u0561-\u0587\u13F8-\u13FD\u1D00-\u1D2B\u1D6B-\u1D77\u1D79-\u1D9A\u1E01\u1E03\u1E05\u1E07\u1E09\u1E0B\u1E0D\u1E0F\u1E11\u1E13\u1E15\u1E17\u1E19\u1E1B\u1E1D\u1E1F\u1E21\u1E23\u1E25\u1E27\u1E29\u1E2B\u1E2D\u1E2F\u1E31\u1E33\u1E35\u1E37\u1E39\u1E3B\u1E3D\u1E3F\u1E41\u1E43\u1E45\u1E47\u1E49\u1E4B\u1E4D\u1E4F\u1E51\u1E53\u1E55\u1E57\u1E59\u1E5B\u1E5D\u1E5F\u1E61\u1E63\u1E65\u1E67\u1E69\u1E6B\u1E6D\u1E6F\u1E71\u1E73\u1E75\u1E77\u1E79\u1E7B\u1E7D\u1E7F\u1E81\u1E83\u1E85\u1E87\u1E89\u1E8B\u1E8D\u1E8F\u1E91\u1E93\u1E95-\u1E9D\u1E9F\u1EA1\u1EA3\u1EA5\u1EA7\u1EA9\u1EAB\u1EAD\u1EAF\u1EB1\u1EB3\u1EB5\u1EB7\u1EB9\u1EBB\u1EBD\u1EBF\u1EC1\u1EC3\u1EC5\u1EC7\u1EC9\u1ECB\u1ECD\u1ECF\u1ED1\u1ED3\u1ED5\u1ED7\u1ED9\u1EDB\u1EDD\u1EDF\u1EE1\u1EE3\u1EE5\u1EE7\u1EE9\u1EEB\u1EED\u1EEF\u1EF1\u1EF3\u1EF5\u1EF7\u1EF9\u1EFB\u1EFD\u1EFF-\u1F07\u1F10-\u1F15\u1F20-\u1F27\u1F30-\u1F37\u1F40-\u1F45\u1F50-\u1F57\u1F60-\u1F67\u1F70-\u1F7D\u1F80-\u1F87\u1F90-\u1F97\u1FA0-\u1FA7\u1FB0-\u1FB4\u1FB6-\u1FB7\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FC7\u1FD0-\u1FD3\u1FD6-\u1FD7\u1FE0-\u1FE7\u1FF2-\u1FF4\u1FF6-\u1FF7\u210A\u210E-\u210F\u2113\u212F\u2134\u2139\u213C-\u213D\u2146-\u2149\u214E\u2184\u2C30-\u2C5E\u2C61\u2C65-\u2C66\u2C68\u2C6A\u2C6C\u2C71\u2C73-\u2C74\u2C76-\u2C7B\u2C81\u2C83\u2C85\u2C87\u2C89\u2C8B\u2C8D\u2C8F\u2C91\u2C93\u2C95\u2C97\u2C99\u2C9B\u2C9D\u2C9F\u2CA1\u2CA3\u2CA5\u2CA7\u2CA9\u2CAB\u2CAD\u2CAF\u2CB1\u2CB3\u2CB5\u2CB7\u2CB9\u2CBB\u2CBD\u2CBF\u2CC1\u2CC3\u2CC5\u2CC7\u2CC9\u2CCB\u2CCD\u2CCF\u2CD1\u2CD3\u2CD5\u2CD7\u2CD9\u2CDB\u2CDD\u2CDF\u2CE1\u2CE3-\u2CE4\u2CEC\u2CEE\u2CF3\u2D00-\u2D25\u2D27\u2D2D\uA641\uA643\uA645\uA647\uA649\uA64B\uA64D\uA64F\uA651\uA653\uA655\uA657\uA659\uA65B\uA65D\uA65F\uA661\uA663\uA665\uA667\uA669\uA66B\uA66D\uA681\uA683\uA685\uA687\uA689\uA68B\uA68D\uA68F\uA691\uA693\uA695\uA697\uA699\uA69B\uA723\uA725\uA727\uA729\uA72B\uA72D\uA72F-\uA731\uA733\uA735\uA737\uA739\uA73B\uA73D\uA73F\uA741\uA743\uA745\uA747\uA749\uA74B\uA74D\uA74F\uA751\uA753\uA755\uA757\uA759\uA75B\uA75D\uA75F\uA761\uA763\uA765\uA767\uA769\uA76B\uA76D\uA76F\uA771-\uA778\uA77A\uA77C\uA77F\uA781\uA783\uA785\uA787\uA78C\uA78E\uA791\uA793-\uA795\uA797\uA799\uA79B\uA79D\uA79F\uA7A1\uA7A3\uA7A5\uA7A7\uA7A9\uA7B5\uA7B7\uA7FA\uAB30-\uAB5A\uAB60-\uAB65\uAB70-\uABBF\uFB00-\uFB06\uFB13-\uFB17\uFF41-\uFF5A]/,
401 peg$c145 = peg$classExpectation([["a", "z"], "\xB5", ["\xDF", "\xF6"], ["\xF8", "\xFF"], "\u0101", "\u0103", "\u0105", "\u0107", "\u0109", "\u010B", "\u010D", "\u010F", "\u0111", "\u0113", "\u0115", "\u0117", "\u0119", "\u011B", "\u011D", "\u011F", "\u0121", "\u0123", "\u0125", "\u0127", "\u0129", "\u012B", "\u012D", "\u012F", "\u0131", "\u0133", "\u0135", ["\u0137", "\u0138"], "\u013A", "\u013C", "\u013E", "\u0140", "\u0142", "\u0144", "\u0146", ["\u0148", "\u0149"], "\u014B", "\u014D", "\u014F", "\u0151", "\u0153", "\u0155", "\u0157", "\u0159", "\u015B", "\u015D", "\u015F", "\u0161", "\u0163", "\u0165", "\u0167", "\u0169", "\u016B", "\u016D", "\u016F", "\u0171", "\u0173", "\u0175", "\u0177", "\u017A", "\u017C", ["\u017E", "\u0180"], "\u0183", "\u0185", "\u0188", ["\u018C", "\u018D"], "\u0192", "\u0195", ["\u0199", "\u019B"], "\u019E", "\u01A1", "\u01A3", "\u01A5", "\u01A8", ["\u01AA", "\u01AB"], "\u01AD", "\u01B0", "\u01B4", "\u01B6", ["\u01B9", "\u01BA"], ["\u01BD", "\u01BF"], "\u01C6", "\u01C9", "\u01CC", "\u01CE", "\u01D0", "\u01D2", "\u01D4", "\u01D6", "\u01D8", "\u01DA", ["\u01DC", "\u01DD"], "\u01DF", "\u01E1", "\u01E3", "\u01E5", "\u01E7", "\u01E9", "\u01EB", "\u01ED", ["\u01EF", "\u01F0"], "\u01F3", "\u01F5", "\u01F9", "\u01FB", "\u01FD", "\u01FF", "\u0201", "\u0203", "\u0205", "\u0207", "\u0209", "\u020B", "\u020D", "\u020F", "\u0211", "\u0213", "\u0215", "\u0217", "\u0219", "\u021B", "\u021D", "\u021F", "\u0221", "\u0223", "\u0225", "\u0227", "\u0229", "\u022B", "\u022D", "\u022F", "\u0231", ["\u0233", "\u0239"], "\u023C", ["\u023F", "\u0240"], "\u0242", "\u0247", "\u0249", "\u024B", "\u024D", ["\u024F", "\u0293"], ["\u0295", "\u02AF"], "\u0371", "\u0373", "\u0377", ["\u037B", "\u037D"], "\u0390", ["\u03AC", "\u03CE"], ["\u03D0", "\u03D1"], ["\u03D5", "\u03D7"], "\u03D9", "\u03DB", "\u03DD", "\u03DF", "\u03E1", "\u03E3", "\u03E5", "\u03E7", "\u03E9", "\u03EB", "\u03ED", ["\u03EF", "\u03F3"], "\u03F5", "\u03F8", ["\u03FB", "\u03FC"], ["\u0430", "\u045F"], "\u0461", "\u0463", "\u0465", "\u0467", "\u0469", "\u046B", "\u046D", "\u046F", "\u0471", "\u0473", "\u0475", "\u0477", "\u0479", "\u047B", "\u047D", "\u047F", "\u0481", "\u048B", "\u048D", "\u048F", "\u0491", "\u0493", "\u0495", "\u0497", "\u0499", "\u049B", "\u049D", "\u049F", "\u04A1", "\u04A3", "\u04A5", "\u04A7", "\u04A9", "\u04AB", "\u04AD", "\u04AF", "\u04B1", "\u04B3", "\u04B5", "\u04B7", "\u04B9", "\u04BB", "\u04BD", "\u04BF", "\u04C2", "\u04C4", "\u04C6", "\u04C8", "\u04CA", "\u04CC", ["\u04CE", "\u04CF"], "\u04D1", "\u04D3", "\u04D5", "\u04D7", "\u04D9", "\u04DB", "\u04DD", "\u04DF", "\u04E1", "\u04E3", "\u04E5", "\u04E7", "\u04E9", "\u04EB", "\u04ED", "\u04EF", "\u04F1", "\u04F3", "\u04F5", "\u04F7", "\u04F9", "\u04FB", "\u04FD", "\u04FF", "\u0501", "\u0503", "\u0505", "\u0507", "\u0509", "\u050B", "\u050D", "\u050F", "\u0511", "\u0513", "\u0515", "\u0517", "\u0519", "\u051B", "\u051D", "\u051F", "\u0521", "\u0523", "\u0525", "\u0527", "\u0529", "\u052B", "\u052D", "\u052F", ["\u0561", "\u0587"], ["\u13F8", "\u13FD"], ["\u1D00", "\u1D2B"], ["\u1D6B", "\u1D77"], ["\u1D79", "\u1D9A"], "\u1E01", "\u1E03", "\u1E05", "\u1E07", "\u1E09", "\u1E0B", "\u1E0D", "\u1E0F", "\u1E11", "\u1E13", "\u1E15", "\u1E17", "\u1E19", "\u1E1B", "\u1E1D", "\u1E1F", "\u1E21", "\u1E23", "\u1E25", "\u1E27", "\u1E29", "\u1E2B", "\u1E2D", "\u1E2F", "\u1E31", "\u1E33", "\u1E35", "\u1E37", "\u1E39", "\u1E3B", "\u1E3D", "\u1E3F", "\u1E41", "\u1E43", "\u1E45", "\u1E47", "\u1E49", "\u1E4B", "\u1E4D", "\u1E4F", "\u1E51", "\u1E53", "\u1E55", "\u1E57", "\u1E59", "\u1E5B", "\u1E5D", "\u1E5F", "\u1E61", "\u1E63", "\u1E65", "\u1E67", "\u1E69", "\u1E6B", "\u1E6D", "\u1E6F", "\u1E71", "\u1E73", "\u1E75", "\u1E77", "\u1E79", "\u1E7B", "\u1E7D", "\u1E7F", "\u1E81", "\u1E83", "\u1E85", "\u1E87", "\u1E89", "\u1E8B", "\u1E8D", "\u1E8F", "\u1E91", "\u1E93", ["\u1E95", "\u1E9D"], "\u1E9F", "\u1EA1", "\u1EA3", "\u1EA5", "\u1EA7", "\u1EA9", "\u1EAB", "\u1EAD", "\u1EAF", "\u1EB1", "\u1EB3", "\u1EB5", "\u1EB7", "\u1EB9", "\u1EBB", "\u1EBD", "\u1EBF", "\u1EC1", "\u1EC3", "\u1EC5", "\u1EC7", "\u1EC9", "\u1ECB", "\u1ECD", "\u1ECF", "\u1ED1", "\u1ED3", "\u1ED5", "\u1ED7", "\u1ED9", "\u1EDB", "\u1EDD", "\u1EDF", "\u1EE1", "\u1EE3", "\u1EE5", "\u1EE7", "\u1EE9", "\u1EEB", "\u1EED", "\u1EEF", "\u1EF1", "\u1EF3", "\u1EF5", "\u1EF7", "\u1EF9", "\u1EFB", "\u1EFD", ["\u1EFF", "\u1F07"], ["\u1F10", "\u1F15"], ["\u1F20", "\u1F27"], ["\u1F30", "\u1F37"], ["\u1F40", "\u1F45"], ["\u1F50", "\u1F57"], ["\u1F60", "\u1F67"], ["\u1F70", "\u1F7D"], ["\u1F80", "\u1F87"], ["\u1F90", "\u1F97"], ["\u1FA0", "\u1FA7"], ["\u1FB0", "\u1FB4"], ["\u1FB6", "\u1FB7"], "\u1FBE", ["\u1FC2", "\u1FC4"], ["\u1FC6", "\u1FC7"], ["\u1FD0", "\u1FD3"], ["\u1FD6", "\u1FD7"], ["\u1FE0", "\u1FE7"], ["\u1FF2", "\u1FF4"], ["\u1FF6", "\u1FF7"], "\u210A", ["\u210E", "\u210F"], "\u2113", "\u212F", "\u2134", "\u2139", ["\u213C", "\u213D"], ["\u2146", "\u2149"], "\u214E", "\u2184", ["\u2C30", "\u2C5E"], "\u2C61", ["\u2C65", "\u2C66"], "\u2C68", "\u2C6A", "\u2C6C", "\u2C71", ["\u2C73", "\u2C74"], ["\u2C76", "\u2C7B"], "\u2C81", "\u2C83", "\u2C85", "\u2C87", "\u2C89", "\u2C8B", "\u2C8D", "\u2C8F", "\u2C91", "\u2C93", "\u2C95", "\u2C97", "\u2C99", "\u2C9B", "\u2C9D", "\u2C9F", "\u2CA1", "\u2CA3", "\u2CA5", "\u2CA7", "\u2CA9", "\u2CAB", "\u2CAD", "\u2CAF", "\u2CB1", "\u2CB3", "\u2CB5", "\u2CB7", "\u2CB9", "\u2CBB", "\u2CBD", "\u2CBF", "\u2CC1", "\u2CC3", "\u2CC5", "\u2CC7", "\u2CC9", "\u2CCB", "\u2CCD", "\u2CCF", "\u2CD1", "\u2CD3", "\u2CD5", "\u2CD7", "\u2CD9", "\u2CDB", "\u2CDD", "\u2CDF", "\u2CE1", ["\u2CE3", "\u2CE4"], "\u2CEC", "\u2CEE", "\u2CF3", ["\u2D00", "\u2D25"], "\u2D27", "\u2D2D", "\uA641", "\uA643", "\uA645", "\uA647", "\uA649", "\uA64B", "\uA64D", "\uA64F", "\uA651", "\uA653", "\uA655", "\uA657", "\uA659", "\uA65B", "\uA65D", "\uA65F", "\uA661", "\uA663", "\uA665", "\uA667", "\uA669", "\uA66B", "\uA66D", "\uA681", "\uA683", "\uA685", "\uA687", "\uA689", "\uA68B", "\uA68D", "\uA68F", "\uA691", "\uA693", "\uA695", "\uA697", "\uA699", "\uA69B", "\uA723", "\uA725", "\uA727", "\uA729", "\uA72B", "\uA72D", ["\uA72F", "\uA731"], "\uA733", "\uA735", "\uA737", "\uA739", "\uA73B", "\uA73D", "\uA73F", "\uA741", "\uA743", "\uA745", "\uA747", "\uA749", "\uA74B", "\uA74D", "\uA74F", "\uA751", "\uA753", "\uA755", "\uA757", "\uA759", "\uA75B", "\uA75D", "\uA75F", "\uA761", "\uA763", "\uA765", "\uA767", "\uA769", "\uA76B", "\uA76D", "\uA76F", ["\uA771", "\uA778"], "\uA77A", "\uA77C", "\uA77F", "\uA781", "\uA783", "\uA785", "\uA787", "\uA78C", "\uA78E", "\uA791", ["\uA793", "\uA795"], "\uA797", "\uA799", "\uA79B", "\uA79D", "\uA79F", "\uA7A1", "\uA7A3", "\uA7A5", "\uA7A7", "\uA7A9", "\uA7B5", "\uA7B7", "\uA7FA", ["\uAB30", "\uAB5A"], ["\uAB60", "\uAB65"], ["\uAB70", "\uABBF"], ["\uFB00", "\uFB06"], ["\uFB13", "\uFB17"], ["\uFF41", "\uFF5A"]], false, false),
402 peg$c146 = /^[\u02B0-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0374\u037A\u0559\u0640\u06E5-\u06E6\u07F4-\u07F5\u07FA\u081A\u0824\u0828\u0971\u0E46\u0EC6\u10FC\u17D7\u1843\u1AA7\u1C78-\u1C7D\u1D2C-\u1D6A\u1D78\u1D9B-\u1DBF\u2071\u207F\u2090-\u209C\u2C7C-\u2C7D\u2D6F\u2E2F\u3005\u3031-\u3035\u303B\u309D-\u309E\u30FC-\u30FE\uA015\uA4F8-\uA4FD\uA60C\uA67F\uA69C-\uA69D\uA717-\uA71F\uA770\uA788\uA7F8-\uA7F9\uA9CF\uA9E6\uAA70\uAADD\uAAF3-\uAAF4\uAB5C-\uAB5F\uFF70\uFF9E-\uFF9F]/,
403 peg$c147 = peg$classExpectation([["\u02B0", "\u02C1"], ["\u02C6", "\u02D1"], ["\u02E0", "\u02E4"], "\u02EC", "\u02EE", "\u0374", "\u037A", "\u0559", "\u0640", ["\u06E5", "\u06E6"], ["\u07F4", "\u07F5"], "\u07FA", "\u081A", "\u0824", "\u0828", "\u0971", "\u0E46", "\u0EC6", "\u10FC", "\u17D7", "\u1843", "\u1AA7", ["\u1C78", "\u1C7D"], ["\u1D2C", "\u1D6A"], "\u1D78", ["\u1D9B", "\u1DBF"], "\u2071", "\u207F", ["\u2090", "\u209C"], ["\u2C7C", "\u2C7D"], "\u2D6F", "\u2E2F", "\u3005", ["\u3031", "\u3035"], "\u303B", ["\u309D", "\u309E"], ["\u30FC", "\u30FE"], "\uA015", ["\uA4F8", "\uA4FD"], "\uA60C", "\uA67F", ["\uA69C", "\uA69D"], ["\uA717", "\uA71F"], "\uA770", "\uA788", ["\uA7F8", "\uA7F9"], "\uA9CF", "\uA9E6", "\uAA70", "\uAADD", ["\uAAF3", "\uAAF4"], ["\uAB5C", "\uAB5F"], "\uFF70", ["\uFF9E", "\uFF9F"]], false, false),
404 peg$c148 = /^[\xAA\xBA\u01BB\u01C0-\u01C3\u0294\u05D0-\u05EA\u05F0-\u05F2\u0620-\u063F\u0641-\u064A\u066E-\u066F\u0671-\u06D3\u06D5\u06EE-\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u0800-\u0815\u0840-\u0858\u08A0-\u08B4\u0904-\u0939\u093D\u0950\u0958-\u0961\u0972-\u0980\u0985-\u098C\u098F-\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC-\u09DD\u09DF-\u09E1\u09F0-\u09F1\u0A05-\u0A0A\u0A0F-\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32-\u0A33\u0A35-\u0A36\u0A38-\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2-\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0-\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F-\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32-\u0B33\u0B35-\u0B39\u0B3D\u0B5C-\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99-\u0B9A\u0B9C\u0B9E-\u0B9F\u0BA3-\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60-\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0-\u0CE1\u0CF1-\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32-\u0E33\u0E40-\u0E45\u0E81-\u0E82\u0E84\u0E87-\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA-\u0EAB\u0EAD-\u0EB0\u0EB2-\u0EB3\u0EBD\u0EC0-\u0EC4\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065-\u1066\u106E-\u1070\u1075-\u1081\u108E\u10D0-\u10FA\u10FD-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17DC\u1820-\u1842\u1844-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE-\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C77\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5-\u1CF6\u2135-\u2138\u2D30-\u2D67\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3006\u303C\u3041-\u3096\u309F\u30A1-\u30FA\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA014\uA016-\uA48C\uA4D0-\uA4F7\uA500-\uA60B\uA610-\uA61F\uA62A-\uA62B\uA66E\uA6A0-\uA6E5\uA78F\uA7F7\uA7FB-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9E0-\uA9E4\uA9E7-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA6F\uAA71-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5-\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADC\uAAE0-\uAAEA\uAAF2\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40-\uFB41\uFB43-\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF66-\uFF6F\uFF71-\uFF9D\uFFA0-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]/,
405 peg$c149 = peg$classExpectation(["\xAA", "\xBA", "\u01BB", ["\u01C0", "\u01C3"], "\u0294", ["\u05D0", "\u05EA"], ["\u05F0", "\u05F2"], ["\u0620", "\u063F"], ["\u0641", "\u064A"], ["\u066E", "\u066F"], ["\u0671", "\u06D3"], "\u06D5", ["\u06EE", "\u06EF"], ["\u06FA", "\u06FC"], "\u06FF", "\u0710", ["\u0712", "\u072F"], ["\u074D", "\u07A5"], "\u07B1", ["\u07CA", "\u07EA"], ["\u0800", "\u0815"], ["\u0840", "\u0858"], ["\u08A0", "\u08B4"], ["\u0904", "\u0939"], "\u093D", "\u0950", ["\u0958", "\u0961"], ["\u0972", "\u0980"], ["\u0985", "\u098C"], ["\u098F", "\u0990"], ["\u0993", "\u09A8"], ["\u09AA", "\u09B0"], "\u09B2", ["\u09B6", "\u09B9"], "\u09BD", "\u09CE", ["\u09DC", "\u09DD"], ["\u09DF", "\u09E1"], ["\u09F0", "\u09F1"], ["\u0A05", "\u0A0A"], ["\u0A0F", "\u0A10"], ["\u0A13", "\u0A28"], ["\u0A2A", "\u0A30"], ["\u0A32", "\u0A33"], ["\u0A35", "\u0A36"], ["\u0A38", "\u0A39"], ["\u0A59", "\u0A5C"], "\u0A5E", ["\u0A72", "\u0A74"], ["\u0A85", "\u0A8D"], ["\u0A8F", "\u0A91"], ["\u0A93", "\u0AA8"], ["\u0AAA", "\u0AB0"], ["\u0AB2", "\u0AB3"], ["\u0AB5", "\u0AB9"], "\u0ABD", "\u0AD0", ["\u0AE0", "\u0AE1"], "\u0AF9", ["\u0B05", "\u0B0C"], ["\u0B0F", "\u0B10"], ["\u0B13", "\u0B28"], ["\u0B2A", "\u0B30"], ["\u0B32", "\u0B33"], ["\u0B35", "\u0B39"], "\u0B3D", ["\u0B5C", "\u0B5D"], ["\u0B5F", "\u0B61"], "\u0B71", "\u0B83", ["\u0B85", "\u0B8A"], ["\u0B8E", "\u0B90"], ["\u0B92", "\u0B95"], ["\u0B99", "\u0B9A"], "\u0B9C", ["\u0B9E", "\u0B9F"], ["\u0BA3", "\u0BA4"], ["\u0BA8", "\u0BAA"], ["\u0BAE", "\u0BB9"], "\u0BD0", ["\u0C05", "\u0C0C"], ["\u0C0E", "\u0C10"], ["\u0C12", "\u0C28"], ["\u0C2A", "\u0C39"], "\u0C3D", ["\u0C58", "\u0C5A"], ["\u0C60", "\u0C61"], ["\u0C85", "\u0C8C"], ["\u0C8E", "\u0C90"], ["\u0C92", "\u0CA8"], ["\u0CAA", "\u0CB3"], ["\u0CB5", "\u0CB9"], "\u0CBD", "\u0CDE", ["\u0CE0", "\u0CE1"], ["\u0CF1", "\u0CF2"], ["\u0D05", "\u0D0C"], ["\u0D0E", "\u0D10"], ["\u0D12", "\u0D3A"], "\u0D3D", "\u0D4E", ["\u0D5F", "\u0D61"], ["\u0D7A", "\u0D7F"], ["\u0D85", "\u0D96"], ["\u0D9A", "\u0DB1"], ["\u0DB3", "\u0DBB"], "\u0DBD", ["\u0DC0", "\u0DC6"], ["\u0E01", "\u0E30"], ["\u0E32", "\u0E33"], ["\u0E40", "\u0E45"], ["\u0E81", "\u0E82"], "\u0E84", ["\u0E87", "\u0E88"], "\u0E8A", "\u0E8D", ["\u0E94", "\u0E97"], ["\u0E99", "\u0E9F"], ["\u0EA1", "\u0EA3"], "\u0EA5", "\u0EA7", ["\u0EAA", "\u0EAB"], ["\u0EAD", "\u0EB0"], ["\u0EB2", "\u0EB3"], "\u0EBD", ["\u0EC0", "\u0EC4"], ["\u0EDC", "\u0EDF"], "\u0F00", ["\u0F40", "\u0F47"], ["\u0F49", "\u0F6C"], ["\u0F88", "\u0F8C"], ["\u1000", "\u102A"], "\u103F", ["\u1050", "\u1055"], ["\u105A", "\u105D"], "\u1061", ["\u1065", "\u1066"], ["\u106E", "\u1070"], ["\u1075", "\u1081"], "\u108E", ["\u10D0", "\u10FA"], ["\u10FD", "\u1248"], ["\u124A", "\u124D"], ["\u1250", "\u1256"], "\u1258", ["\u125A", "\u125D"], ["\u1260", "\u1288"], ["\u128A", "\u128D"], ["\u1290", "\u12B0"], ["\u12B2", "\u12B5"], ["\u12B8", "\u12BE"], "\u12C0", ["\u12C2", "\u12C5"], ["\u12C8", "\u12D6"], ["\u12D8", "\u1310"], ["\u1312", "\u1315"], ["\u1318", "\u135A"], ["\u1380", "\u138F"], ["\u1401", "\u166C"], ["\u166F", "\u167F"], ["\u1681", "\u169A"], ["\u16A0", "\u16EA"], ["\u16F1", "\u16F8"], ["\u1700", "\u170C"], ["\u170E", "\u1711"], ["\u1720", "\u1731"], ["\u1740", "\u1751"], ["\u1760", "\u176C"], ["\u176E", "\u1770"], ["\u1780", "\u17B3"], "\u17DC", ["\u1820", "\u1842"], ["\u1844", "\u1877"], ["\u1880", "\u18A8"], "\u18AA", ["\u18B0", "\u18F5"], ["\u1900", "\u191E"], ["\u1950", "\u196D"], ["\u1970", "\u1974"], ["\u1980", "\u19AB"], ["\u19B0", "\u19C9"], ["\u1A00", "\u1A16"], ["\u1A20", "\u1A54"], ["\u1B05", "\u1B33"], ["\u1B45", "\u1B4B"], ["\u1B83", "\u1BA0"], ["\u1BAE", "\u1BAF"], ["\u1BBA", "\u1BE5"], ["\u1C00", "\u1C23"], ["\u1C4D", "\u1C4F"], ["\u1C5A", "\u1C77"], ["\u1CE9", "\u1CEC"], ["\u1CEE", "\u1CF1"], ["\u1CF5", "\u1CF6"], ["\u2135", "\u2138"], ["\u2D30", "\u2D67"], ["\u2D80", "\u2D96"], ["\u2DA0", "\u2DA6"], ["\u2DA8", "\u2DAE"], ["\u2DB0", "\u2DB6"], ["\u2DB8", "\u2DBE"], ["\u2DC0", "\u2DC6"], ["\u2DC8", "\u2DCE"], ["\u2DD0", "\u2DD6"], ["\u2DD8", "\u2DDE"], "\u3006", "\u303C", ["\u3041", "\u3096"], "\u309F", ["\u30A1", "\u30FA"], "\u30FF", ["\u3105", "\u312D"], ["\u3131", "\u318E"], ["\u31A0", "\u31BA"], ["\u31F0", "\u31FF"], ["\u3400", "\u4DB5"], ["\u4E00", "\u9FD5"], ["\uA000", "\uA014"], ["\uA016", "\uA48C"], ["\uA4D0", "\uA4F7"], ["\uA500", "\uA60B"], ["\uA610", "\uA61F"], ["\uA62A", "\uA62B"], "\uA66E", ["\uA6A0", "\uA6E5"], "\uA78F", "\uA7F7", ["\uA7FB", "\uA801"], ["\uA803", "\uA805"], ["\uA807", "\uA80A"], ["\uA80C", "\uA822"], ["\uA840", "\uA873"], ["\uA882", "\uA8B3"], ["\uA8F2", "\uA8F7"], "\uA8FB", "\uA8FD", ["\uA90A", "\uA925"], ["\uA930", "\uA946"], ["\uA960", "\uA97C"], ["\uA984", "\uA9B2"], ["\uA9E0", "\uA9E4"], ["\uA9E7", "\uA9EF"], ["\uA9FA", "\uA9FE"], ["\uAA00", "\uAA28"], ["\uAA40", "\uAA42"], ["\uAA44", "\uAA4B"], ["\uAA60", "\uAA6F"], ["\uAA71", "\uAA76"], "\uAA7A", ["\uAA7E", "\uAAAF"], "\uAAB1", ["\uAAB5", "\uAAB6"], ["\uAAB9", "\uAABD"], "\uAAC0", "\uAAC2", ["\uAADB", "\uAADC"], ["\uAAE0", "\uAAEA"], "\uAAF2", ["\uAB01", "\uAB06"], ["\uAB09", "\uAB0E"], ["\uAB11", "\uAB16"], ["\uAB20", "\uAB26"], ["\uAB28", "\uAB2E"], ["\uABC0", "\uABE2"], ["\uAC00", "\uD7A3"], ["\uD7B0", "\uD7C6"], ["\uD7CB", "\uD7FB"], ["\uF900", "\uFA6D"], ["\uFA70", "\uFAD9"], "\uFB1D", ["\uFB1F", "\uFB28"], ["\uFB2A", "\uFB36"], ["\uFB38", "\uFB3C"], "\uFB3E", ["\uFB40", "\uFB41"], ["\uFB43", "\uFB44"], ["\uFB46", "\uFBB1"], ["\uFBD3", "\uFD3D"], ["\uFD50", "\uFD8F"], ["\uFD92", "\uFDC7"], ["\uFDF0", "\uFDFB"], ["\uFE70", "\uFE74"], ["\uFE76", "\uFEFC"], ["\uFF66", "\uFF6F"], ["\uFF71", "\uFF9D"], ["\uFFA0", "\uFFBE"], ["\uFFC2", "\uFFC7"], ["\uFFCA", "\uFFCF"], ["\uFFD2", "\uFFD7"], ["\uFFDA", "\uFFDC"]], false, false),
406 peg$c150 = /^[\u01C5\u01C8\u01CB\u01F2\u1F88-\u1F8F\u1F98-\u1F9F\u1FA8-\u1FAF\u1FBC\u1FCC\u1FFC]/,
407 peg$c151 = peg$classExpectation(["\u01C5", "\u01C8", "\u01CB", "\u01F2", ["\u1F88", "\u1F8F"], ["\u1F98", "\u1F9F"], ["\u1FA8", "\u1FAF"], "\u1FBC", "\u1FCC", "\u1FFC"], false, false),
408 peg$c152 = /^[A-Z\xC0-\xD6\xD8-\xDE\u0100\u0102\u0104\u0106\u0108\u010A\u010C\u010E\u0110\u0112\u0114\u0116\u0118\u011A\u011C\u011E\u0120\u0122\u0124\u0126\u0128\u012A\u012C\u012E\u0130\u0132\u0134\u0136\u0139\u013B\u013D\u013F\u0141\u0143\u0145\u0147\u014A\u014C\u014E\u0150\u0152\u0154\u0156\u0158\u015A\u015C\u015E\u0160\u0162\u0164\u0166\u0168\u016A\u016C\u016E\u0170\u0172\u0174\u0176\u0178-\u0179\u017B\u017D\u0181-\u0182\u0184\u0186-\u0187\u0189-\u018B\u018E-\u0191\u0193-\u0194\u0196-\u0198\u019C-\u019D\u019F-\u01A0\u01A2\u01A4\u01A6-\u01A7\u01A9\u01AC\u01AE-\u01AF\u01B1-\u01B3\u01B5\u01B7-\u01B8\u01BC\u01C4\u01C7\u01CA\u01CD\u01CF\u01D1\u01D3\u01D5\u01D7\u01D9\u01DB\u01DE\u01E0\u01E2\u01E4\u01E6\u01E8\u01EA\u01EC\u01EE\u01F1\u01F4\u01F6-\u01F8\u01FA\u01FC\u01FE\u0200\u0202\u0204\u0206\u0208\u020A\u020C\u020E\u0210\u0212\u0214\u0216\u0218\u021A\u021C\u021E\u0220\u0222\u0224\u0226\u0228\u022A\u022C\u022E\u0230\u0232\u023A-\u023B\u023D-\u023E\u0241\u0243-\u0246\u0248\u024A\u024C\u024E\u0370\u0372\u0376\u037F\u0386\u0388-\u038A\u038C\u038E-\u038F\u0391-\u03A1\u03A3-\u03AB\u03CF\u03D2-\u03D4\u03D8\u03DA\u03DC\u03DE\u03E0\u03E2\u03E4\u03E6\u03E8\u03EA\u03EC\u03EE\u03F4\u03F7\u03F9-\u03FA\u03FD-\u042F\u0460\u0462\u0464\u0466\u0468\u046A\u046C\u046E\u0470\u0472\u0474\u0476\u0478\u047A\u047C\u047E\u0480\u048A\u048C\u048E\u0490\u0492\u0494\u0496\u0498\u049A\u049C\u049E\u04A0\u04A2\u04A4\u04A6\u04A8\u04AA\u04AC\u04AE\u04B0\u04B2\u04B4\u04B6\u04B8\u04BA\u04BC\u04BE\u04C0-\u04C1\u04C3\u04C5\u04C7\u04C9\u04CB\u04CD\u04D0\u04D2\u04D4\u04D6\u04D8\u04DA\u04DC\u04DE\u04E0\u04E2\u04E4\u04E6\u04E8\u04EA\u04EC\u04EE\u04F0\u04F2\u04F4\u04F6\u04F8\u04FA\u04FC\u04FE\u0500\u0502\u0504\u0506\u0508\u050A\u050C\u050E\u0510\u0512\u0514\u0516\u0518\u051A\u051C\u051E\u0520\u0522\u0524\u0526\u0528\u052A\u052C\u052E\u0531-\u0556\u10A0-\u10C5\u10C7\u10CD\u13A0-\u13F5\u1E00\u1E02\u1E04\u1E06\u1E08\u1E0A\u1E0C\u1E0E\u1E10\u1E12\u1E14\u1E16\u1E18\u1E1A\u1E1C\u1E1E\u1E20\u1E22\u1E24\u1E26\u1E28\u1E2A\u1E2C\u1E2E\u1E30\u1E32\u1E34\u1E36\u1E38\u1E3A\u1E3C\u1E3E\u1E40\u1E42\u1E44\u1E46\u1E48\u1E4A\u1E4C\u1E4E\u1E50\u1E52\u1E54\u1E56\u1E58\u1E5A\u1E5C\u1E5E\u1E60\u1E62\u1E64\u1E66\u1E68\u1E6A\u1E6C\u1E6E\u1E70\u1E72\u1E74\u1E76\u1E78\u1E7A\u1E7C\u1E7E\u1E80\u1E82\u1E84\u1E86\u1E88\u1E8A\u1E8C\u1E8E\u1E90\u1E92\u1E94\u1E9E\u1EA0\u1EA2\u1EA4\u1EA6\u1EA8\u1EAA\u1EAC\u1EAE\u1EB0\u1EB2\u1EB4\u1EB6\u1EB8\u1EBA\u1EBC\u1EBE\u1EC0\u1EC2\u1EC4\u1EC6\u1EC8\u1ECA\u1ECC\u1ECE\u1ED0\u1ED2\u1ED4\u1ED6\u1ED8\u1EDA\u1EDC\u1EDE\u1EE0\u1EE2\u1EE4\u1EE6\u1EE8\u1EEA\u1EEC\u1EEE\u1EF0\u1EF2\u1EF4\u1EF6\u1EF8\u1EFA\u1EFC\u1EFE\u1F08-\u1F0F\u1F18-\u1F1D\u1F28-\u1F2F\u1F38-\u1F3F\u1F48-\u1F4D\u1F59\u1F5B\u1F5D\u1F5F\u1F68-\u1F6F\u1FB8-\u1FBB\u1FC8-\u1FCB\u1FD8-\u1FDB\u1FE8-\u1FEC\u1FF8-\u1FFB\u2102\u2107\u210B-\u210D\u2110-\u2112\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u2130-\u2133\u213E-\u213F\u2145\u2183\u2C00-\u2C2E\u2C60\u2C62-\u2C64\u2C67\u2C69\u2C6B\u2C6D-\u2C70\u2C72\u2C75\u2C7E-\u2C80\u2C82\u2C84\u2C86\u2C88\u2C8A\u2C8C\u2C8E\u2C90\u2C92\u2C94\u2C96\u2C98\u2C9A\u2C9C\u2C9E\u2CA0\u2CA2\u2CA4\u2CA6\u2CA8\u2CAA\u2CAC\u2CAE\u2CB0\u2CB2\u2CB4\u2CB6\u2CB8\u2CBA\u2CBC\u2CBE\u2CC0\u2CC2\u2CC4\u2CC6\u2CC8\u2CCA\u2CCC\u2CCE\u2CD0\u2CD2\u2CD4\u2CD6\u2CD8\u2CDA\u2CDC\u2CDE\u2CE0\u2CE2\u2CEB\u2CED\u2CF2\uA640\uA642\uA644\uA646\uA648\uA64A\uA64C\uA64E\uA650\uA652\uA654\uA656\uA658\uA65A\uA65C\uA65E\uA660\uA662\uA664\uA666\uA668\uA66A\uA66C\uA680\uA682\uA684\uA686\uA688\uA68A\uA68C\uA68E\uA690\uA692\uA694\uA696\uA698\uA69A\uA722\uA724\uA726\uA728\uA72A\uA72C\uA72E\uA732\uA734\uA736\uA738\uA73A\uA73C\uA73E\uA740\uA742\uA744\uA746\uA748\uA74A\uA74C\uA74E\uA750\uA752\uA754\uA756\uA758\uA75A\uA75C\uA75E\uA760\uA762\uA764\uA766\uA768\uA76A\uA76C\uA76E\uA779\uA77B\uA77D-\uA77E\uA780\uA782\uA784\uA786\uA78B\uA78D\uA790\uA792\uA796\uA798\uA79A\uA79C\uA79E\uA7A0\uA7A2\uA7A4\uA7A6\uA7A8\uA7AA-\uA7AD\uA7B0-\uA7B4\uA7B6\uFF21-\uFF3A]/,
409 peg$c153 = peg$classExpectation([["A", "Z"], ["\xC0", "\xD6"], ["\xD8", "\xDE"], "\u0100", "\u0102", "\u0104", "\u0106", "\u0108", "\u010A", "\u010C", "\u010E", "\u0110", "\u0112", "\u0114", "\u0116", "\u0118", "\u011A", "\u011C", "\u011E", "\u0120", "\u0122", "\u0124", "\u0126", "\u0128", "\u012A", "\u012C", "\u012E", "\u0130", "\u0132", "\u0134", "\u0136", "\u0139", "\u013B", "\u013D", "\u013F", "\u0141", "\u0143", "\u0145", "\u0147", "\u014A", "\u014C", "\u014E", "\u0150", "\u0152", "\u0154", "\u0156", "\u0158", "\u015A", "\u015C", "\u015E", "\u0160", "\u0162", "\u0164", "\u0166", "\u0168", "\u016A", "\u016C", "\u016E", "\u0170", "\u0172", "\u0174", "\u0176", ["\u0178", "\u0179"], "\u017B", "\u017D", ["\u0181", "\u0182"], "\u0184", ["\u0186", "\u0187"], ["\u0189", "\u018B"], ["\u018E", "\u0191"], ["\u0193", "\u0194"], ["\u0196", "\u0198"], ["\u019C", "\u019D"], ["\u019F", "\u01A0"], "\u01A2", "\u01A4", ["\u01A6", "\u01A7"], "\u01A9", "\u01AC", ["\u01AE", "\u01AF"], ["\u01B1", "\u01B3"], "\u01B5", ["\u01B7", "\u01B8"], "\u01BC", "\u01C4", "\u01C7", "\u01CA", "\u01CD", "\u01CF", "\u01D1", "\u01D3", "\u01D5", "\u01D7", "\u01D9", "\u01DB", "\u01DE", "\u01E0", "\u01E2", "\u01E4", "\u01E6", "\u01E8", "\u01EA", "\u01EC", "\u01EE", "\u01F1", "\u01F4", ["\u01F6", "\u01F8"], "\u01FA", "\u01FC", "\u01FE", "\u0200", "\u0202", "\u0204", "\u0206", "\u0208", "\u020A", "\u020C", "\u020E", "\u0210", "\u0212", "\u0214", "\u0216", "\u0218", "\u021A", "\u021C", "\u021E", "\u0220", "\u0222", "\u0224", "\u0226", "\u0228", "\u022A", "\u022C", "\u022E", "\u0230", "\u0232", ["\u023A", "\u023B"], ["\u023D", "\u023E"], "\u0241", ["\u0243", "\u0246"], "\u0248", "\u024A", "\u024C", "\u024E", "\u0370", "\u0372", "\u0376", "\u037F", "\u0386", ["\u0388", "\u038A"], "\u038C", ["\u038E", "\u038F"], ["\u0391", "\u03A1"], ["\u03A3", "\u03AB"], "\u03CF", ["\u03D2", "\u03D4"], "\u03D8", "\u03DA", "\u03DC", "\u03DE", "\u03E0", "\u03E2", "\u03E4", "\u03E6", "\u03E8", "\u03EA", "\u03EC", "\u03EE", "\u03F4", "\u03F7", ["\u03F9", "\u03FA"], ["\u03FD", "\u042F"], "\u0460", "\u0462", "\u0464", "\u0466", "\u0468", "\u046A", "\u046C", "\u046E", "\u0470", "\u0472", "\u0474", "\u0476", "\u0478", "\u047A", "\u047C", "\u047E", "\u0480", "\u048A", "\u048C", "\u048E", "\u0490", "\u0492", "\u0494", "\u0496", "\u0498", "\u049A", "\u049C", "\u049E", "\u04A0", "\u04A2", "\u04A4", "\u04A6", "\u04A8", "\u04AA", "\u04AC", "\u04AE", "\u04B0", "\u04B2", "\u04B4", "\u04B6", "\u04B8", "\u04BA", "\u04BC", "\u04BE", ["\u04C0", "\u04C1"], "\u04C3", "\u04C5", "\u04C7", "\u04C9", "\u04CB", "\u04CD", "\u04D0", "\u04D2", "\u04D4", "\u04D6", "\u04D8", "\u04DA", "\u04DC", "\u04DE", "\u04E0", "\u04E2", "\u04E4", "\u04E6", "\u04E8", "\u04EA", "\u04EC", "\u04EE", "\u04F0", "\u04F2", "\u04F4", "\u04F6", "\u04F8", "\u04FA", "\u04FC", "\u04FE", "\u0500", "\u0502", "\u0504", "\u0506", "\u0508", "\u050A", "\u050C", "\u050E", "\u0510", "\u0512", "\u0514", "\u0516", "\u0518", "\u051A", "\u051C", "\u051E", "\u0520", "\u0522", "\u0524", "\u0526", "\u0528", "\u052A", "\u052C", "\u052E", ["\u0531", "\u0556"], ["\u10A0", "\u10C5"], "\u10C7", "\u10CD", ["\u13A0", "\u13F5"], "\u1E00", "\u1E02", "\u1E04", "\u1E06", "\u1E08", "\u1E0A", "\u1E0C", "\u1E0E", "\u1E10", "\u1E12", "\u1E14", "\u1E16", "\u1E18", "\u1E1A", "\u1E1C", "\u1E1E", "\u1E20", "\u1E22", "\u1E24", "\u1E26", "\u1E28", "\u1E2A", "\u1E2C", "\u1E2E", "\u1E30", "\u1E32", "\u1E34", "\u1E36", "\u1E38", "\u1E3A", "\u1E3C", "\u1E3E", "\u1E40", "\u1E42", "\u1E44", "\u1E46", "\u1E48", "\u1E4A", "\u1E4C", "\u1E4E", "\u1E50", "\u1E52", "\u1E54", "\u1E56", "\u1E58", "\u1E5A", "\u1E5C", "\u1E5E", "\u1E60", "\u1E62", "\u1E64", "\u1E66", "\u1E68", "\u1E6A", "\u1E6C", "\u1E6E", "\u1E70", "\u1E72", "\u1E74", "\u1E76", "\u1E78", "\u1E7A", "\u1E7C", "\u1E7E", "\u1E80", "\u1E82", "\u1E84", "\u1E86", "\u1E88", "\u1E8A", "\u1E8C", "\u1E8E", "\u1E90", "\u1E92", "\u1E94", "\u1E9E", "\u1EA0", "\u1EA2", "\u1EA4", "\u1EA6", "\u1EA8", "\u1EAA", "\u1EAC", "\u1EAE", "\u1EB0", "\u1EB2", "\u1EB4", "\u1EB6", "\u1EB8", "\u1EBA", "\u1EBC", "\u1EBE", "\u1EC0", "\u1EC2", "\u1EC4", "\u1EC6", "\u1EC8", "\u1ECA", "\u1ECC", "\u1ECE", "\u1ED0", "\u1ED2", "\u1ED4", "\u1ED6", "\u1ED8", "\u1EDA", "\u1EDC", "\u1EDE", "\u1EE0", "\u1EE2", "\u1EE4", "\u1EE6", "\u1EE8", "\u1EEA", "\u1EEC", "\u1EEE", "\u1EF0", "\u1EF2", "\u1EF4", "\u1EF6", "\u1EF8", "\u1EFA", "\u1EFC", "\u1EFE", ["\u1F08", "\u1F0F"], ["\u1F18", "\u1F1D"], ["\u1F28", "\u1F2F"], ["\u1F38", "\u1F3F"], ["\u1F48", "\u1F4D"], "\u1F59", "\u1F5B", "\u1F5D", "\u1F5F", ["\u1F68", "\u1F6F"], ["\u1FB8", "\u1FBB"], ["\u1FC8", "\u1FCB"], ["\u1FD8", "\u1FDB"], ["\u1FE8", "\u1FEC"], ["\u1FF8", "\u1FFB"], "\u2102", "\u2107", ["\u210B", "\u210D"], ["\u2110", "\u2112"], "\u2115", ["\u2119", "\u211D"], "\u2124", "\u2126", "\u2128", ["\u212A", "\u212D"], ["\u2130", "\u2133"], ["\u213E", "\u213F"], "\u2145", "\u2183", ["\u2C00", "\u2C2E"], "\u2C60", ["\u2C62", "\u2C64"], "\u2C67", "\u2C69", "\u2C6B", ["\u2C6D", "\u2C70"], "\u2C72", "\u2C75", ["\u2C7E", "\u2C80"], "\u2C82", "\u2C84", "\u2C86", "\u2C88", "\u2C8A", "\u2C8C", "\u2C8E", "\u2C90", "\u2C92", "\u2C94", "\u2C96", "\u2C98", "\u2C9A", "\u2C9C", "\u2C9E", "\u2CA0", "\u2CA2", "\u2CA4", "\u2CA6", "\u2CA8", "\u2CAA", "\u2CAC", "\u2CAE", "\u2CB0", "\u2CB2", "\u2CB4", "\u2CB6", "\u2CB8", "\u2CBA", "\u2CBC", "\u2CBE", "\u2CC0", "\u2CC2", "\u2CC4", "\u2CC6", "\u2CC8", "\u2CCA", "\u2CCC", "\u2CCE", "\u2CD0", "\u2CD2", "\u2CD4", "\u2CD6", "\u2CD8", "\u2CDA", "\u2CDC", "\u2CDE", "\u2CE0", "\u2CE2", "\u2CEB", "\u2CED", "\u2CF2", "\uA640", "\uA642", "\uA644", "\uA646", "\uA648", "\uA64A", "\uA64C", "\uA64E", "\uA650", "\uA652", "\uA654", "\uA656", "\uA658", "\uA65A", "\uA65C", "\uA65E", "\uA660", "\uA662", "\uA664", "\uA666", "\uA668", "\uA66A", "\uA66C", "\uA680", "\uA682", "\uA684", "\uA686", "\uA688", "\uA68A", "\uA68C", "\uA68E", "\uA690", "\uA692", "\uA694", "\uA696", "\uA698", "\uA69A", "\uA722", "\uA724", "\uA726", "\uA728", "\uA72A", "\uA72C", "\uA72E", "\uA732", "\uA734", "\uA736", "\uA738", "\uA73A", "\uA73C", "\uA73E", "\uA740", "\uA742", "\uA744", "\uA746", "\uA748", "\uA74A", "\uA74C", "\uA74E", "\uA750", "\uA752", "\uA754", "\uA756", "\uA758", "\uA75A", "\uA75C", "\uA75E", "\uA760", "\uA762", "\uA764", "\uA766", "\uA768", "\uA76A", "\uA76C", "\uA76E", "\uA779", "\uA77B", ["\uA77D", "\uA77E"], "\uA780", "\uA782", "\uA784", "\uA786", "\uA78B", "\uA78D", "\uA790", "\uA792", "\uA796", "\uA798", "\uA79A", "\uA79C", "\uA79E", "\uA7A0", "\uA7A2", "\uA7A4", "\uA7A6", "\uA7A8", ["\uA7AA", "\uA7AD"], ["\uA7B0", "\uA7B4"], "\uA7B6", ["\uFF21", "\uFF3A"]], false, false),
410 peg$c154 = /^[\u0903\u093B\u093E-\u0940\u0949-\u094C\u094E-\u094F\u0982-\u0983\u09BE-\u09C0\u09C7-\u09C8\u09CB-\u09CC\u09D7\u0A03\u0A3E-\u0A40\u0A83\u0ABE-\u0AC0\u0AC9\u0ACB-\u0ACC\u0B02-\u0B03\u0B3E\u0B40\u0B47-\u0B48\u0B4B-\u0B4C\u0B57\u0BBE-\u0BBF\u0BC1-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCC\u0BD7\u0C01-\u0C03\u0C41-\u0C44\u0C82-\u0C83\u0CBE\u0CC0-\u0CC4\u0CC7-\u0CC8\u0CCA-\u0CCB\u0CD5-\u0CD6\u0D02-\u0D03\u0D3E-\u0D40\u0D46-\u0D48\u0D4A-\u0D4C\u0D57\u0D82-\u0D83\u0DCF-\u0DD1\u0DD8-\u0DDF\u0DF2-\u0DF3\u0F3E-\u0F3F\u0F7F\u102B-\u102C\u1031\u1038\u103B-\u103C\u1056-\u1057\u1062-\u1064\u1067-\u106D\u1083-\u1084\u1087-\u108C\u108F\u109A-\u109C\u17B6\u17BE-\u17C5\u17C7-\u17C8\u1923-\u1926\u1929-\u192B\u1930-\u1931\u1933-\u1938\u1A19-\u1A1A\u1A55\u1A57\u1A61\u1A63-\u1A64\u1A6D-\u1A72\u1B04\u1B35\u1B3B\u1B3D-\u1B41\u1B43-\u1B44\u1B82\u1BA1\u1BA6-\u1BA7\u1BAA\u1BE7\u1BEA-\u1BEC\u1BEE\u1BF2-\u1BF3\u1C24-\u1C2B\u1C34-\u1C35\u1CE1\u1CF2-\u1CF3\u302E-\u302F\uA823-\uA824\uA827\uA880-\uA881\uA8B4-\uA8C3\uA952-\uA953\uA983\uA9B4-\uA9B5\uA9BA-\uA9BB\uA9BD-\uA9C0\uAA2F-\uAA30\uAA33-\uAA34\uAA4D\uAA7B\uAA7D\uAAEB\uAAEE-\uAAEF\uAAF5\uABE3-\uABE4\uABE6-\uABE7\uABE9-\uABEA\uABEC]/,
411 peg$c155 = peg$classExpectation(["\u0903", "\u093B", ["\u093E", "\u0940"], ["\u0949", "\u094C"], ["\u094E", "\u094F"], ["\u0982", "\u0983"], ["\u09BE", "\u09C0"], ["\u09C7", "\u09C8"], ["\u09CB", "\u09CC"], "\u09D7", "\u0A03", ["\u0A3E", "\u0A40"], "\u0A83", ["\u0ABE", "\u0AC0"], "\u0AC9", ["\u0ACB", "\u0ACC"], ["\u0B02", "\u0B03"], "\u0B3E", "\u0B40", ["\u0B47", "\u0B48"], ["\u0B4B", "\u0B4C"], "\u0B57", ["\u0BBE", "\u0BBF"], ["\u0BC1", "\u0BC2"], ["\u0BC6", "\u0BC8"], ["\u0BCA", "\u0BCC"], "\u0BD7", ["\u0C01", "\u0C03"], ["\u0C41", "\u0C44"], ["\u0C82", "\u0C83"], "\u0CBE", ["\u0CC0", "\u0CC4"], ["\u0CC7", "\u0CC8"], ["\u0CCA", "\u0CCB"], ["\u0CD5", "\u0CD6"], ["\u0D02", "\u0D03"], ["\u0D3E", "\u0D40"], ["\u0D46", "\u0D48"], ["\u0D4A", "\u0D4C"], "\u0D57", ["\u0D82", "\u0D83"], ["\u0DCF", "\u0DD1"], ["\u0DD8", "\u0DDF"], ["\u0DF2", "\u0DF3"], ["\u0F3E", "\u0F3F"], "\u0F7F", ["\u102B", "\u102C"], "\u1031", "\u1038", ["\u103B", "\u103C"], ["\u1056", "\u1057"], ["\u1062", "\u1064"], ["\u1067", "\u106D"], ["\u1083", "\u1084"], ["\u1087", "\u108C"], "\u108F", ["\u109A", "\u109C"], "\u17B6", ["\u17BE", "\u17C5"], ["\u17C7", "\u17C8"], ["\u1923", "\u1926"], ["\u1929", "\u192B"], ["\u1930", "\u1931"], ["\u1933", "\u1938"], ["\u1A19", "\u1A1A"], "\u1A55", "\u1A57", "\u1A61", ["\u1A63", "\u1A64"], ["\u1A6D", "\u1A72"], "\u1B04", "\u1B35", "\u1B3B", ["\u1B3D", "\u1B41"], ["\u1B43", "\u1B44"], "\u1B82", "\u1BA1", ["\u1BA6", "\u1BA7"], "\u1BAA", "\u1BE7", ["\u1BEA", "\u1BEC"], "\u1BEE", ["\u1BF2", "\u1BF3"], ["\u1C24", "\u1C2B"], ["\u1C34", "\u1C35"], "\u1CE1", ["\u1CF2", "\u1CF3"], ["\u302E", "\u302F"], ["\uA823", "\uA824"], "\uA827", ["\uA880", "\uA881"], ["\uA8B4", "\uA8C3"], ["\uA952", "\uA953"], "\uA983", ["\uA9B4", "\uA9B5"], ["\uA9BA", "\uA9BB"], ["\uA9BD", "\uA9C0"], ["\uAA2F", "\uAA30"], ["\uAA33", "\uAA34"], "\uAA4D", "\uAA7B", "\uAA7D", "\uAAEB", ["\uAAEE", "\uAAEF"], "\uAAF5", ["\uABE3", "\uABE4"], ["\uABE6", "\uABE7"], ["\uABE9", "\uABEA"], "\uABEC"], false, false),
412 peg$c156 = /^[\u0300-\u036F\u0483-\u0487\u0591-\u05BD\u05BF\u05C1-\u05C2\u05C4-\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7-\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08E3-\u0902\u093A\u093C\u0941-\u0948\u094D\u0951-\u0957\u0962-\u0963\u0981\u09BC\u09C1-\u09C4\u09CD\u09E2-\u09E3\u0A01-\u0A02\u0A3C\u0A41-\u0A42\u0A47-\u0A48\u0A4B-\u0A4D\u0A51\u0A70-\u0A71\u0A75\u0A81-\u0A82\u0ABC\u0AC1-\u0AC5\u0AC7-\u0AC8\u0ACD\u0AE2-\u0AE3\u0B01\u0B3C\u0B3F\u0B41-\u0B44\u0B4D\u0B56\u0B62-\u0B63\u0B82\u0BC0\u0BCD\u0C00\u0C3E-\u0C40\u0C46-\u0C48\u0C4A-\u0C4D\u0C55-\u0C56\u0C62-\u0C63\u0C81\u0CBC\u0CBF\u0CC6\u0CCC-\u0CCD\u0CE2-\u0CE3\u0D01\u0D41-\u0D44\u0D4D\u0D62-\u0D63\u0DCA\u0DD2-\u0DD4\u0DD6\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB-\u0EBC\u0EC8-\u0ECD\u0F18-\u0F19\u0F35\u0F37\u0F39\u0F71-\u0F7E\u0F80-\u0F84\u0F86-\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102D-\u1030\u1032-\u1037\u1039-\u103A\u103D-\u103E\u1058-\u1059\u105E-\u1060\u1071-\u1074\u1082\u1085-\u1086\u108D\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752-\u1753\u1772-\u1773\u17B4-\u17B5\u17B7-\u17BD\u17C6\u17C9-\u17D3\u17DD\u180B-\u180D\u18A9\u1920-\u1922\u1927-\u1928\u1932\u1939-\u193B\u1A17-\u1A18\u1A1B\u1A56\u1A58-\u1A5E\u1A60\u1A62\u1A65-\u1A6C\u1A73-\u1A7C\u1A7F\u1AB0-\u1ABD\u1B00-\u1B03\u1B34\u1B36-\u1B3A\u1B3C\u1B42\u1B6B-\u1B73\u1B80-\u1B81\u1BA2-\u1BA5\u1BA8-\u1BA9\u1BAB-\u1BAD\u1BE6\u1BE8-\u1BE9\u1BED\u1BEF-\u1BF1\u1C2C-\u1C33\u1C36-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE0\u1CE2-\u1CE8\u1CED\u1CF4\u1CF8-\u1CF9\u1DC0-\u1DF5\u1DFC-\u1DFF\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302D\u3099-\u309A\uA66F\uA674-\uA67D\uA69E-\uA69F\uA6F0-\uA6F1\uA802\uA806\uA80B\uA825-\uA826\uA8C4\uA8E0-\uA8F1\uA926-\uA92D\uA947-\uA951\uA980-\uA982\uA9B3\uA9B6-\uA9B9\uA9BC\uA9E5\uAA29-\uAA2E\uAA31-\uAA32\uAA35-\uAA36\uAA43\uAA4C\uAA7C\uAAB0\uAAB2-\uAAB4\uAAB7-\uAAB8\uAABE-\uAABF\uAAC1\uAAEC-\uAAED\uAAF6\uABE5\uABE8\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2F]/,
413 peg$c157 = peg$classExpectation([["\u0300", "\u036F"], ["\u0483", "\u0487"], ["\u0591", "\u05BD"], "\u05BF", ["\u05C1", "\u05C2"], ["\u05C4", "\u05C5"], "\u05C7", ["\u0610", "\u061A"], ["\u064B", "\u065F"], "\u0670", ["\u06D6", "\u06DC"], ["\u06DF", "\u06E4"], ["\u06E7", "\u06E8"], ["\u06EA", "\u06ED"], "\u0711", ["\u0730", "\u074A"], ["\u07A6", "\u07B0"], ["\u07EB", "\u07F3"], ["\u0816", "\u0819"], ["\u081B", "\u0823"], ["\u0825", "\u0827"], ["\u0829", "\u082D"], ["\u0859", "\u085B"], ["\u08E3", "\u0902"], "\u093A", "\u093C", ["\u0941", "\u0948"], "\u094D", ["\u0951", "\u0957"], ["\u0962", "\u0963"], "\u0981", "\u09BC", ["\u09C1", "\u09C4"], "\u09CD", ["\u09E2", "\u09E3"], ["\u0A01", "\u0A02"], "\u0A3C", ["\u0A41", "\u0A42"], ["\u0A47", "\u0A48"], ["\u0A4B", "\u0A4D"], "\u0A51", ["\u0A70", "\u0A71"], "\u0A75", ["\u0A81", "\u0A82"], "\u0ABC", ["\u0AC1", "\u0AC5"], ["\u0AC7", "\u0AC8"], "\u0ACD", ["\u0AE2", "\u0AE3"], "\u0B01", "\u0B3C", "\u0B3F", ["\u0B41", "\u0B44"], "\u0B4D", "\u0B56", ["\u0B62", "\u0B63"], "\u0B82", "\u0BC0", "\u0BCD", "\u0C00", ["\u0C3E", "\u0C40"], ["\u0C46", "\u0C48"], ["\u0C4A", "\u0C4D"], ["\u0C55", "\u0C56"], ["\u0C62", "\u0C63"], "\u0C81", "\u0CBC", "\u0CBF", "\u0CC6", ["\u0CCC", "\u0CCD"], ["\u0CE2", "\u0CE3"], "\u0D01", ["\u0D41", "\u0D44"], "\u0D4D", ["\u0D62", "\u0D63"], "\u0DCA", ["\u0DD2", "\u0DD4"], "\u0DD6", "\u0E31", ["\u0E34", "\u0E3A"], ["\u0E47", "\u0E4E"], "\u0EB1", ["\u0EB4", "\u0EB9"], ["\u0EBB", "\u0EBC"], ["\u0EC8", "\u0ECD"], ["\u0F18", "\u0F19"], "\u0F35", "\u0F37", "\u0F39", ["\u0F71", "\u0F7E"], ["\u0F80", "\u0F84"], ["\u0F86", "\u0F87"], ["\u0F8D", "\u0F97"], ["\u0F99", "\u0FBC"], "\u0FC6", ["\u102D", "\u1030"], ["\u1032", "\u1037"], ["\u1039", "\u103A"], ["\u103D", "\u103E"], ["\u1058", "\u1059"], ["\u105E", "\u1060"], ["\u1071", "\u1074"], "\u1082", ["\u1085", "\u1086"], "\u108D", "\u109D", ["\u135D", "\u135F"], ["\u1712", "\u1714"], ["\u1732", "\u1734"], ["\u1752", "\u1753"], ["\u1772", "\u1773"], ["\u17B4", "\u17B5"], ["\u17B7", "\u17BD"], "\u17C6", ["\u17C9", "\u17D3"], "\u17DD", ["\u180B", "\u180D"], "\u18A9", ["\u1920", "\u1922"], ["\u1927", "\u1928"], "\u1932", ["\u1939", "\u193B"], ["\u1A17", "\u1A18"], "\u1A1B", "\u1A56", ["\u1A58", "\u1A5E"], "\u1A60", "\u1A62", ["\u1A65", "\u1A6C"], ["\u1A73", "\u1A7C"], "\u1A7F", ["\u1AB0", "\u1ABD"], ["\u1B00", "\u1B03"], "\u1B34", ["\u1B36", "\u1B3A"], "\u1B3C", "\u1B42", ["\u1B6B", "\u1B73"], ["\u1B80", "\u1B81"], ["\u1BA2", "\u1BA5"], ["\u1BA8", "\u1BA9"], ["\u1BAB", "\u1BAD"], "\u1BE6", ["\u1BE8", "\u1BE9"], "\u1BED", ["\u1BEF", "\u1BF1"], ["\u1C2C", "\u1C33"], ["\u1C36", "\u1C37"], ["\u1CD0", "\u1CD2"], ["\u1CD4", "\u1CE0"], ["\u1CE2", "\u1CE8"], "\u1CED", "\u1CF4", ["\u1CF8", "\u1CF9"], ["\u1DC0", "\u1DF5"], ["\u1DFC", "\u1DFF"], ["\u20D0", "\u20DC"], "\u20E1", ["\u20E5", "\u20F0"], ["\u2CEF", "\u2CF1"], "\u2D7F", ["\u2DE0", "\u2DFF"], ["\u302A", "\u302D"], ["\u3099", "\u309A"], "\uA66F", ["\uA674", "\uA67D"], ["\uA69E", "\uA69F"], ["\uA6F0", "\uA6F1"], "\uA802", "\uA806", "\uA80B", ["\uA825", "\uA826"], "\uA8C4", ["\uA8E0", "\uA8F1"], ["\uA926", "\uA92D"], ["\uA947", "\uA951"], ["\uA980", "\uA982"], "\uA9B3", ["\uA9B6", "\uA9B9"], "\uA9BC", "\uA9E5", ["\uAA29", "\uAA2E"], ["\uAA31", "\uAA32"], ["\uAA35", "\uAA36"], "\uAA43", "\uAA4C", "\uAA7C", "\uAAB0", ["\uAAB2", "\uAAB4"], ["\uAAB7", "\uAAB8"], ["\uAABE", "\uAABF"], "\uAAC1", ["\uAAEC", "\uAAED"], "\uAAF6", "\uABE5", "\uABE8", "\uABED", "\uFB1E", ["\uFE00", "\uFE0F"], ["\uFE20", "\uFE2F"]], false, false),
414 peg$c158 = /^[0-9\u0660-\u0669\u06F0-\u06F9\u07C0-\u07C9\u0966-\u096F\u09E6-\u09EF\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0BE6-\u0BEF\u0C66-\u0C6F\u0CE6-\u0CEF\u0D66-\u0D6F\u0DE6-\u0DEF\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F29\u1040-\u1049\u1090-\u1099\u17E0-\u17E9\u1810-\u1819\u1946-\u194F\u19D0-\u19D9\u1A80-\u1A89\u1A90-\u1A99\u1B50-\u1B59\u1BB0-\u1BB9\u1C40-\u1C49\u1C50-\u1C59\uA620-\uA629\uA8D0-\uA8D9\uA900-\uA909\uA9D0-\uA9D9\uA9F0-\uA9F9\uAA50-\uAA59\uABF0-\uABF9\uFF10-\uFF19]/,
415 peg$c159 = peg$classExpectation([["0", "9"], ["\u0660", "\u0669"], ["\u06F0", "\u06F9"], ["\u07C0", "\u07C9"], ["\u0966", "\u096F"], ["\u09E6", "\u09EF"], ["\u0A66", "\u0A6F"], ["\u0AE6", "\u0AEF"], ["\u0B66", "\u0B6F"], ["\u0BE6", "\u0BEF"], ["\u0C66", "\u0C6F"], ["\u0CE6", "\u0CEF"], ["\u0D66", "\u0D6F"], ["\u0DE6", "\u0DEF"], ["\u0E50", "\u0E59"], ["\u0ED0", "\u0ED9"], ["\u0F20", "\u0F29"], ["\u1040", "\u1049"], ["\u1090", "\u1099"], ["\u17E0", "\u17E9"], ["\u1810", "\u1819"], ["\u1946", "\u194F"], ["\u19D0", "\u19D9"], ["\u1A80", "\u1A89"], ["\u1A90", "\u1A99"], ["\u1B50", "\u1B59"], ["\u1BB0", "\u1BB9"], ["\u1C40", "\u1C49"], ["\u1C50", "\u1C59"], ["\uA620", "\uA629"], ["\uA8D0", "\uA8D9"], ["\uA900", "\uA909"], ["\uA9D0", "\uA9D9"], ["\uA9F0", "\uA9F9"], ["\uAA50", "\uAA59"], ["\uABF0", "\uABF9"], ["\uFF10", "\uFF19"]], false, false),
416 peg$c160 = /^[\u16EE-\u16F0\u2160-\u2182\u2185-\u2188\u3007\u3021-\u3029\u3038-\u303A\uA6E6-\uA6EF]/,
417 peg$c161 = peg$classExpectation([["\u16EE", "\u16F0"], ["\u2160", "\u2182"], ["\u2185", "\u2188"], "\u3007", ["\u3021", "\u3029"], ["\u3038", "\u303A"], ["\uA6E6", "\uA6EF"]], false, false),
418 peg$c162 = /^[_\u203F-\u2040\u2054\uFE33-\uFE34\uFE4D-\uFE4F\uFF3F]/,
419 peg$c163 = peg$classExpectation(["_", ["\u203F", "\u2040"], "\u2054", ["\uFE33", "\uFE34"], ["\uFE4D", "\uFE4F"], "\uFF3F"], false, false),
420 peg$c164 = /^[ \xA0\u1680\u2000-\u200A\u202F\u205F\u3000]/,
421 peg$c165 = peg$classExpectation([" ", "\xA0", "\u1680", ["\u2000", "\u200A"], "\u202F", "\u205F", "\u3000"], false, false),
422 peg$c166 = "break",
423 peg$c167 = peg$literalExpectation("break", false),
424 peg$c168 = "case",
425 peg$c169 = peg$literalExpectation("case", false),
426 peg$c170 = "catch",
427 peg$c171 = peg$literalExpectation("catch", false),
428 peg$c172 = "class",
429 peg$c173 = peg$literalExpectation("class", false),
430 peg$c174 = "const",
431 peg$c175 = peg$literalExpectation("const", false),
432 peg$c176 = "continue",
433 peg$c177 = peg$literalExpectation("continue", false),
434 peg$c178 = "debugger",
435 peg$c179 = peg$literalExpectation("debugger", false),
436 peg$c180 = "default",
437 peg$c181 = peg$literalExpectation("default", false),
438 peg$c182 = "delete",
439 peg$c183 = peg$literalExpectation("delete", false),
440 peg$c184 = "do",
441 peg$c185 = peg$literalExpectation("do", false),
442 peg$c186 = "else",
443 peg$c187 = peg$literalExpectation("else", false),
444 peg$c188 = "enum",
445 peg$c189 = peg$literalExpectation("enum", false),
446 peg$c190 = "export",
447 peg$c191 = peg$literalExpectation("export", false),
448 peg$c192 = "extends",
449 peg$c193 = peg$literalExpectation("extends", false),
450 peg$c194 = "false",
451 peg$c195 = peg$literalExpectation("false", false),
452 peg$c196 = "finally",
453 peg$c197 = peg$literalExpectation("finally", false),
454 peg$c198 = "for",
455 peg$c199 = peg$literalExpectation("for", false),
456 peg$c200 = "function",
457 peg$c201 = peg$literalExpectation("function", false),
458 peg$c202 = "if",
459 peg$c203 = peg$literalExpectation("if", false),
460 peg$c204 = "import",
461 peg$c205 = peg$literalExpectation("import", false),
462 peg$c206 = "instanceof",
463 peg$c207 = peg$literalExpectation("instanceof", false),
464 peg$c208 = "in",
465 peg$c209 = peg$literalExpectation("in", false),
466 peg$c210 = "new",
467 peg$c211 = peg$literalExpectation("new", false),
468 peg$c212 = "null",
469 peg$c213 = peg$literalExpectation("null", false),
470 peg$c214 = "return",
471 peg$c215 = peg$literalExpectation("return", false),
472 peg$c216 = "super",
473 peg$c217 = peg$literalExpectation("super", false),
474 peg$c218 = "switch",
475 peg$c219 = peg$literalExpectation("switch", false),
476 peg$c220 = "this",
477 peg$c221 = peg$literalExpectation("this", false),
478 peg$c222 = "throw",
479 peg$c223 = peg$literalExpectation("throw", false),
480 peg$c224 = "true",
481 peg$c225 = peg$literalExpectation("true", false),
482 peg$c226 = "try",
483 peg$c227 = peg$literalExpectation("try", false),
484 peg$c228 = "typeof",
485 peg$c229 = peg$literalExpectation("typeof", false),
486 peg$c230 = "var",
487 peg$c231 = peg$literalExpectation("var", false),
488 peg$c232 = "void",
489 peg$c233 = peg$literalExpectation("void", false),
490 peg$c234 = "while",
491 peg$c235 = peg$literalExpectation("while", false),
492 peg$c236 = "with",
493 peg$c237 = peg$literalExpectation("with", false),
494 peg$c238 = ";",
495 peg$c239 = peg$literalExpectation(";", false),
496
497 peg$currPos = 0,
498 peg$savedPos = 0,
499 peg$posDetailsCache = [{ line: 1, column: 1 }],
500 peg$maxFailPos = 0,
501 peg$maxFailExpected = [],
502 peg$silentFails = 0,
503
504 peg$result;
505
506 if ("startRule" in options) {
507 if (!(options.startRule in peg$startRuleFunctions)) {
508 throw new Error("Can't start parsing from rule \"" + options.startRule + "\".");
509 }
510
511 peg$startRuleFunction = peg$startRuleFunctions[options.startRule];
512 }
513
514 function text() {
515 return input.substring(peg$savedPos, peg$currPos);
516 }
517
518 function location() {
519 return peg$computeLocation(peg$savedPos, peg$currPos);
520 }
521
522 function expected(description, location) {
523 location = location !== void 0 ? location : peg$computeLocation(peg$savedPos, peg$currPos)
524
525 throw peg$buildStructuredError(
526 [peg$otherExpectation(description)],
527 input.substring(peg$savedPos, peg$currPos),
528 location
529 );
530 }
531
532 function error(message, location) {
533 location = location !== void 0 ? location : peg$computeLocation(peg$savedPos, peg$currPos)
534
535 throw peg$buildSimpleError(message, location);
536 }
537
538 function peg$literalExpectation(text, ignoreCase) {
539 return { type: "literal", text: text, ignoreCase: ignoreCase };
540 }
541
542 function peg$classExpectation(parts, inverted, ignoreCase) {
543 return { type: "class", parts: parts, inverted: inverted, ignoreCase: ignoreCase };
544 }
545
546 function peg$anyExpectation() {
547 return { type: "any" };
548 }
549
550 function peg$endExpectation() {
551 return { type: "end" };
552 }
553
554 function peg$otherExpectation(description) {
555 return { type: "other", description: description };
556 }
557
558 function peg$computePosDetails(pos) {
559 var details = peg$posDetailsCache[pos], p;
560
561 if (details) {
562 return details;
563 } else {
564 p = pos - 1;
565 while (!peg$posDetailsCache[p]) {
566 p--;
567 }
568
569 details = peg$posDetailsCache[p];
570 details = {
571 line: details.line,
572 column: details.column
573 };
574
575 while (p < pos) {
576 if (input.charCodeAt(p) === 10) {
577 details.line++;
578 details.column = 1;
579 } else {
580 details.column++;
581 }
582
583 p++;
584 }
585
586 peg$posDetailsCache[pos] = details;
587 return details;
588 }
589 }
590
591 function peg$computeLocation(startPos, endPos) {
592 var startPosDetails = peg$computePosDetails(startPos),
593 endPosDetails = peg$computePosDetails(endPos);
594
595 return {
596 start: {
597 offset: startPos,
598 line: startPosDetails.line,
599 column: startPosDetails.column
600 },
601 end: {
602 offset: endPos,
603 line: endPosDetails.line,
604 column: endPosDetails.column
605 }
606 };
607 }
608
609 function peg$fail(expected) {
610 if (peg$currPos < peg$maxFailPos) { return; }
611
612 if (peg$currPos > peg$maxFailPos) {
613 peg$maxFailPos = peg$currPos;
614 peg$maxFailExpected = [];
615 }
616
617 peg$maxFailExpected.push(expected);
618 }
619
620 function peg$buildSimpleError(message, location) {
621 return new peg$SyntaxError(message, null, null, location);
622 }
623
624 function peg$buildStructuredError(expected, found, location) {
625 return new peg$SyntaxError(
626 peg$SyntaxError.buildMessage(expected, found),
627 expected,
628 found,
629 location
630 );
631 }
632
633 function peg$parseGrammar() {
634 var s0, s1, s2, s3, s4, s5, s6;
635
636 s0 = peg$currPos;
637 s1 = peg$parse__();
638 if (s1 !== peg$FAILED) {
639 s2 = peg$currPos;
640 s3 = peg$parseInitializer();
641 if (s3 !== peg$FAILED) {
642 s4 = peg$parse__();
643 if (s4 !== peg$FAILED) {
644 s3 = [s3, s4];
645 s2 = s3;
646 } else {
647 peg$currPos = s2;
648 s2 = peg$FAILED;
649 }
650 } else {
651 peg$currPos = s2;
652 s2 = peg$FAILED;
653 }
654 if (s2 === peg$FAILED) {
655 s2 = null;
656 }
657 if (s2 !== peg$FAILED) {
658 s3 = [];
659 s4 = peg$currPos;
660 s5 = peg$parseRule();
661 if (s5 !== peg$FAILED) {
662 s6 = peg$parse__();
663 if (s6 !== peg$FAILED) {
664 s5 = [s5, s6];
665 s4 = s5;
666 } else {
667 peg$currPos = s4;
668 s4 = peg$FAILED;
669 }
670 } else {
671 peg$currPos = s4;
672 s4 = peg$FAILED;
673 }
674 if (s4 !== peg$FAILED) {
675 while (s4 !== peg$FAILED) {
676 s3.push(s4);
677 s4 = peg$currPos;
678 s5 = peg$parseRule();
679 if (s5 !== peg$FAILED) {
680 s6 = peg$parse__();
681 if (s6 !== peg$FAILED) {
682 s5 = [s5, s6];
683 s4 = s5;
684 } else {
685 peg$currPos = s4;
686 s4 = peg$FAILED;
687 }
688 } else {
689 peg$currPos = s4;
690 s4 = peg$FAILED;
691 }
692 }
693 } else {
694 s3 = peg$FAILED;
695 }
696 if (s3 !== peg$FAILED) {
697 peg$savedPos = s0;
698 s1 = peg$c0(s2, s3);
699 s0 = s1;
700 } else {
701 peg$currPos = s0;
702 s0 = peg$FAILED;
703 }
704 } else {
705 peg$currPos = s0;
706 s0 = peg$FAILED;
707 }
708 } else {
709 peg$currPos = s0;
710 s0 = peg$FAILED;
711 }
712
713 return s0;
714 }
715
716 function peg$parseInitializer() {
717 var s0, s1, s2;
718
719 s0 = peg$currPos;
720 s1 = peg$parseCodeBlock();
721 if (s1 !== peg$FAILED) {
722 s2 = peg$parseEOS();
723 if (s2 !== peg$FAILED) {
724 peg$savedPos = s0;
725 s1 = peg$c1(s1);
726 s0 = s1;
727 } else {
728 peg$currPos = s0;
729 s0 = peg$FAILED;
730 }
731 } else {
732 peg$currPos = s0;
733 s0 = peg$FAILED;
734 }
735
736 return s0;
737 }
738
739 function peg$parseRule() {
740 var s0, s1, s2, s3, s4, s5, s6, s7;
741
742 s0 = peg$currPos;
743 s1 = peg$parseIdentifierName();
744 if (s1 !== peg$FAILED) {
745 s2 = peg$parse__();
746 if (s2 !== peg$FAILED) {
747 s3 = peg$currPos;
748 s4 = peg$parseStringLiteral();
749 if (s4 !== peg$FAILED) {
750 s5 = peg$parse__();
751 if (s5 !== peg$FAILED) {
752 s4 = [s4, s5];
753 s3 = s4;
754 } else {
755 peg$currPos = s3;
756 s3 = peg$FAILED;
757 }
758 } else {
759 peg$currPos = s3;
760 s3 = peg$FAILED;
761 }
762 if (s3 === peg$FAILED) {
763 s3 = null;
764 }
765 if (s3 !== peg$FAILED) {
766 if (input.charCodeAt(peg$currPos) === 61) {
767 s4 = peg$c2;
768 peg$currPos++;
769 } else {
770 s4 = peg$FAILED;
771 if (peg$silentFails === 0) { peg$fail(peg$c3); }
772 }
773 if (s4 !== peg$FAILED) {
774 s5 = peg$parse__();
775 if (s5 !== peg$FAILED) {
776 s6 = peg$parseChoiceExpression();
777 if (s6 !== peg$FAILED) {
778 s7 = peg$parseEOS();
779 if (s7 !== peg$FAILED) {
780 peg$savedPos = s0;
781 s1 = peg$c4(s1, s3, s6);
782 s0 = s1;
783 } else {
784 peg$currPos = s0;
785 s0 = peg$FAILED;
786 }
787 } else {
788 peg$currPos = s0;
789 s0 = peg$FAILED;
790 }
791 } else {
792 peg$currPos = s0;
793 s0 = peg$FAILED;
794 }
795 } else {
796 peg$currPos = s0;
797 s0 = peg$FAILED;
798 }
799 } else {
800 peg$currPos = s0;
801 s0 = peg$FAILED;
802 }
803 } else {
804 peg$currPos = s0;
805 s0 = peg$FAILED;
806 }
807 } else {
808 peg$currPos = s0;
809 s0 = peg$FAILED;
810 }
811
812 return s0;
813 }
814
815 function peg$parseChoiceExpression() {
816 var s0, s1, s2, s3, s4, s5, s6, s7;
817
818 s0 = peg$currPos;
819 s1 = peg$parseActionExpression();
820 if (s1 !== peg$FAILED) {
821 s2 = [];
822 s3 = peg$currPos;
823 s4 = peg$parse__();
824 if (s4 !== peg$FAILED) {
825 if (input.charCodeAt(peg$currPos) === 47) {
826 s5 = peg$c5;
827 peg$currPos++;
828 } else {
829 s5 = peg$FAILED;
830 if (peg$silentFails === 0) { peg$fail(peg$c6); }
831 }
832 if (s5 !== peg$FAILED) {
833 s6 = peg$parse__();
834 if (s6 !== peg$FAILED) {
835 s7 = peg$parseActionExpression();
836 if (s7 !== peg$FAILED) {
837 s4 = [s4, s5, s6, s7];
838 s3 = s4;
839 } else {
840 peg$currPos = s3;
841 s3 = peg$FAILED;
842 }
843 } else {
844 peg$currPos = s3;
845 s3 = peg$FAILED;
846 }
847 } else {
848 peg$currPos = s3;
849 s3 = peg$FAILED;
850 }
851 } else {
852 peg$currPos = s3;
853 s3 = peg$FAILED;
854 }
855 while (s3 !== peg$FAILED) {
856 s2.push(s3);
857 s3 = peg$currPos;
858 s4 = peg$parse__();
859 if (s4 !== peg$FAILED) {
860 if (input.charCodeAt(peg$currPos) === 47) {
861 s5 = peg$c5;
862 peg$currPos++;
863 } else {
864 s5 = peg$FAILED;
865 if (peg$silentFails === 0) { peg$fail(peg$c6); }
866 }
867 if (s5 !== peg$FAILED) {
868 s6 = peg$parse__();
869 if (s6 !== peg$FAILED) {
870 s7 = peg$parseActionExpression();
871 if (s7 !== peg$FAILED) {
872 s4 = [s4, s5, s6, s7];
873 s3 = s4;
874 } else {
875 peg$currPos = s3;
876 s3 = peg$FAILED;
877 }
878 } else {
879 peg$currPos = s3;
880 s3 = peg$FAILED;
881 }
882 } else {
883 peg$currPos = s3;
884 s3 = peg$FAILED;
885 }
886 } else {
887 peg$currPos = s3;
888 s3 = peg$FAILED;
889 }
890 }
891 if (s2 !== peg$FAILED) {
892 peg$savedPos = s0;
893 s1 = peg$c7(s1, s2);
894 s0 = s1;
895 } else {
896 peg$currPos = s0;
897 s0 = peg$FAILED;
898 }
899 } else {
900 peg$currPos = s0;
901 s0 = peg$FAILED;
902 }
903
904 return s0;
905 }
906
907 function peg$parseActionExpression() {
908 var s0, s1, s2, s3, s4;
909
910 s0 = peg$currPos;
911 s1 = peg$parseSequenceExpression();
912 if (s1 !== peg$FAILED) {
913 s2 = peg$currPos;
914 s3 = peg$parse__();
915 if (s3 !== peg$FAILED) {
916 s4 = peg$parseCodeBlock();
917 if (s4 !== peg$FAILED) {
918 s3 = [s3, s4];
919 s2 = s3;
920 } else {
921 peg$currPos = s2;
922 s2 = peg$FAILED;
923 }
924 } else {
925 peg$currPos = s2;
926 s2 = peg$FAILED;
927 }
928 if (s2 === peg$FAILED) {
929 s2 = null;
930 }
931 if (s2 !== peg$FAILED) {
932 peg$savedPos = s0;
933 s1 = peg$c8(s1, s2);
934 s0 = s1;
935 } else {
936 peg$currPos = s0;
937 s0 = peg$FAILED;
938 }
939 } else {
940 peg$currPos = s0;
941 s0 = peg$FAILED;
942 }
943
944 return s0;
945 }
946
947 function peg$parseSequenceExpression() {
948 var s0, s1, s2, s3, s4, s5;
949
950 s0 = peg$currPos;
951 s1 = peg$parseLabeledExpression();
952 if (s1 !== peg$FAILED) {
953 s2 = [];
954 s3 = peg$currPos;
955 s4 = peg$parse__();
956 if (s4 !== peg$FAILED) {
957 s5 = peg$parseLabeledExpression();
958 if (s5 !== peg$FAILED) {
959 s4 = [s4, s5];
960 s3 = s4;
961 } else {
962 peg$currPos = s3;
963 s3 = peg$FAILED;
964 }
965 } else {
966 peg$currPos = s3;
967 s3 = peg$FAILED;
968 }
969 while (s3 !== peg$FAILED) {
970 s2.push(s3);
971 s3 = peg$currPos;
972 s4 = peg$parse__();
973 if (s4 !== peg$FAILED) {
974 s5 = peg$parseLabeledExpression();
975 if (s5 !== peg$FAILED) {
976 s4 = [s4, s5];
977 s3 = s4;
978 } else {
979 peg$currPos = s3;
980 s3 = peg$FAILED;
981 }
982 } else {
983 peg$currPos = s3;
984 s3 = peg$FAILED;
985 }
986 }
987 if (s2 !== peg$FAILED) {
988 peg$savedPos = s0;
989 s1 = peg$c9(s1, s2);
990 s0 = s1;
991 } else {
992 peg$currPos = s0;
993 s0 = peg$FAILED;
994 }
995 } else {
996 peg$currPos = s0;
997 s0 = peg$FAILED;
998 }
999
1000 return s0;
1001 }
1002
1003 function peg$parseLabeledExpression() {
1004 var s0, s1, s2, s3, s4, s5;
1005
1006 s0 = peg$currPos;
1007 s1 = peg$parseIdentifier();
1008 if (s1 !== peg$FAILED) {
1009 s2 = peg$parse__();
1010 if (s2 !== peg$FAILED) {
1011 if (input.charCodeAt(peg$currPos) === 58) {
1012 s3 = peg$c10;
1013 peg$currPos++;
1014 } else {
1015 s3 = peg$FAILED;
1016 if (peg$silentFails === 0) { peg$fail(peg$c11); }
1017 }
1018 if (s3 !== peg$FAILED) {
1019 s4 = peg$parse__();
1020 if (s4 !== peg$FAILED) {
1021 s5 = peg$parsePrefixedExpression();
1022 if (s5 !== peg$FAILED) {
1023 peg$savedPos = s0;
1024 s1 = peg$c12(s1, s5);
1025 s0 = s1;
1026 } else {
1027 peg$currPos = s0;
1028 s0 = peg$FAILED;
1029 }
1030 } else {
1031 peg$currPos = s0;
1032 s0 = peg$FAILED;
1033 }
1034 } else {
1035 peg$currPos = s0;
1036 s0 = peg$FAILED;
1037 }
1038 } else {
1039 peg$currPos = s0;
1040 s0 = peg$FAILED;
1041 }
1042 } else {
1043 peg$currPos = s0;
1044 s0 = peg$FAILED;
1045 }
1046 if (s0 === peg$FAILED) {
1047 s0 = peg$parsePrefixedExpression();
1048 }
1049
1050 return s0;
1051 }
1052
1053 function peg$parsePrefixedExpression() {
1054 var s0, s1, s2, s3;
1055
1056 s0 = peg$currPos;
1057 s1 = peg$parsePrefixedOperator();
1058 if (s1 !== peg$FAILED) {
1059 s2 = peg$parse__();
1060 if (s2 !== peg$FAILED) {
1061 s3 = peg$parseSuffixedExpression();
1062 if (s3 !== peg$FAILED) {
1063 peg$savedPos = s0;
1064 s1 = peg$c13(s1, s3);
1065 s0 = s1;
1066 } else {
1067 peg$currPos = s0;
1068 s0 = peg$FAILED;
1069 }
1070 } else {
1071 peg$currPos = s0;
1072 s0 = peg$FAILED;
1073 }
1074 } else {
1075 peg$currPos = s0;
1076 s0 = peg$FAILED;
1077 }
1078 if (s0 === peg$FAILED) {
1079 s0 = peg$parseSuffixedExpression();
1080 }
1081
1082 return s0;
1083 }
1084
1085 function peg$parsePrefixedOperator() {
1086 var s0;
1087
1088 if (input.charCodeAt(peg$currPos) === 36) {
1089 s0 = peg$c14;
1090 peg$currPos++;
1091 } else {
1092 s0 = peg$FAILED;
1093 if (peg$silentFails === 0) { peg$fail(peg$c15); }
1094 }
1095 if (s0 === peg$FAILED) {
1096 if (input.charCodeAt(peg$currPos) === 38) {
1097 s0 = peg$c16;
1098 peg$currPos++;
1099 } else {
1100 s0 = peg$FAILED;
1101 if (peg$silentFails === 0) { peg$fail(peg$c17); }
1102 }
1103 if (s0 === peg$FAILED) {
1104 if (input.charCodeAt(peg$currPos) === 33) {
1105 s0 = peg$c18;
1106 peg$currPos++;
1107 } else {
1108 s0 = peg$FAILED;
1109 if (peg$silentFails === 0) { peg$fail(peg$c19); }
1110 }
1111 }
1112 }
1113
1114 return s0;
1115 }
1116
1117 function peg$parseSuffixedExpression() {
1118 var s0, s1, s2, s3;
1119
1120 s0 = peg$currPos;
1121 s1 = peg$parsePrimaryExpression();
1122 if (s1 !== peg$FAILED) {
1123 s2 = peg$parse__();
1124 if (s2 !== peg$FAILED) {
1125 s3 = peg$parseSuffixedOperator();
1126 if (s3 !== peg$FAILED) {
1127 peg$savedPos = s0;
1128 s1 = peg$c20(s1, s3);
1129 s0 = s1;
1130 } else {
1131 peg$currPos = s0;
1132 s0 = peg$FAILED;
1133 }
1134 } else {
1135 peg$currPos = s0;
1136 s0 = peg$FAILED;
1137 }
1138 } else {
1139 peg$currPos = s0;
1140 s0 = peg$FAILED;
1141 }
1142 if (s0 === peg$FAILED) {
1143 s0 = peg$parsePrimaryExpression();
1144 }
1145
1146 return s0;
1147 }
1148
1149 function peg$parseSuffixedOperator() {
1150 var s0;
1151
1152 if (input.charCodeAt(peg$currPos) === 63) {
1153 s0 = peg$c21;
1154 peg$currPos++;
1155 } else {
1156 s0 = peg$FAILED;
1157 if (peg$silentFails === 0) { peg$fail(peg$c22); }
1158 }
1159 if (s0 === peg$FAILED) {
1160 if (input.charCodeAt(peg$currPos) === 42) {
1161 s0 = peg$c23;
1162 peg$currPos++;
1163 } else {
1164 s0 = peg$FAILED;
1165 if (peg$silentFails === 0) { peg$fail(peg$c24); }
1166 }
1167 if (s0 === peg$FAILED) {
1168 if (input.charCodeAt(peg$currPos) === 43) {
1169 s0 = peg$c25;
1170 peg$currPos++;
1171 } else {
1172 s0 = peg$FAILED;
1173 if (peg$silentFails === 0) { peg$fail(peg$c26); }
1174 }
1175 }
1176 }
1177
1178 return s0;
1179 }
1180
1181 function peg$parsePrimaryExpression() {
1182 var s0, s1, s2, s3, s4, s5;
1183
1184 s0 = peg$parseLiteralMatcher();
1185 if (s0 === peg$FAILED) {
1186 s0 = peg$parseCharacterClassMatcher();
1187 if (s0 === peg$FAILED) {
1188 s0 = peg$parseAnyMatcher();
1189 if (s0 === peg$FAILED) {
1190 s0 = peg$parseRuleReferenceExpression();
1191 if (s0 === peg$FAILED) {
1192 s0 = peg$parseSemanticPredicateExpression();
1193 if (s0 === peg$FAILED) {
1194 s0 = peg$currPos;
1195 if (input.charCodeAt(peg$currPos) === 40) {
1196 s1 = peg$c27;
1197 peg$currPos++;
1198 } else {
1199 s1 = peg$FAILED;
1200 if (peg$silentFails === 0) { peg$fail(peg$c28); }
1201 }
1202 if (s1 !== peg$FAILED) {
1203 s2 = peg$parse__();
1204 if (s2 !== peg$FAILED) {
1205 s3 = peg$parseChoiceExpression();
1206 if (s3 !== peg$FAILED) {
1207 s4 = peg$parse__();
1208 if (s4 !== peg$FAILED) {
1209 if (input.charCodeAt(peg$currPos) === 41) {
1210 s5 = peg$c29;
1211 peg$currPos++;
1212 } else {
1213 s5 = peg$FAILED;
1214 if (peg$silentFails === 0) { peg$fail(peg$c30); }
1215 }
1216 if (s5 !== peg$FAILED) {
1217 peg$savedPos = s0;
1218 s1 = peg$c31(s3);
1219 s0 = s1;
1220 } else {
1221 peg$currPos = s0;
1222 s0 = peg$FAILED;
1223 }
1224 } else {
1225 peg$currPos = s0;
1226 s0 = peg$FAILED;
1227 }
1228 } else {
1229 peg$currPos = s0;
1230 s0 = peg$FAILED;
1231 }
1232 } else {
1233 peg$currPos = s0;
1234 s0 = peg$FAILED;
1235 }
1236 } else {
1237 peg$currPos = s0;
1238 s0 = peg$FAILED;
1239 }
1240 }
1241 }
1242 }
1243 }
1244 }
1245
1246 return s0;
1247 }
1248
1249 function peg$parseRuleReferenceExpression() {
1250 var s0, s1, s2, s3, s4, s5, s6, s7;
1251
1252 s0 = peg$currPos;
1253 s1 = peg$parseIdentifierName();
1254 if (s1 !== peg$FAILED) {
1255 s2 = peg$currPos;
1256 peg$silentFails++;
1257 s3 = peg$currPos;
1258 s4 = peg$parse__();
1259 if (s4 !== peg$FAILED) {
1260 s5 = peg$currPos;
1261 s6 = peg$parseStringLiteral();
1262 if (s6 !== peg$FAILED) {
1263 s7 = peg$parse__();
1264 if (s7 !== peg$FAILED) {
1265 s6 = [s6, s7];
1266 s5 = s6;
1267 } else {
1268 peg$currPos = s5;
1269 s5 = peg$FAILED;
1270 }
1271 } else {
1272 peg$currPos = s5;
1273 s5 = peg$FAILED;
1274 }
1275 if (s5 === peg$FAILED) {
1276 s5 = null;
1277 }
1278 if (s5 !== peg$FAILED) {
1279 if (input.charCodeAt(peg$currPos) === 61) {
1280 s6 = peg$c2;
1281 peg$currPos++;
1282 } else {
1283 s6 = peg$FAILED;
1284 if (peg$silentFails === 0) { peg$fail(peg$c3); }
1285 }
1286 if (s6 !== peg$FAILED) {
1287 s4 = [s4, s5, s6];
1288 s3 = s4;
1289 } else {
1290 peg$currPos = s3;
1291 s3 = peg$FAILED;
1292 }
1293 } else {
1294 peg$currPos = s3;
1295 s3 = peg$FAILED;
1296 }
1297 } else {
1298 peg$currPos = s3;
1299 s3 = peg$FAILED;
1300 }
1301 peg$silentFails--;
1302 if (s3 === peg$FAILED) {
1303 s2 = void 0;
1304 } else {
1305 peg$currPos = s2;
1306 s2 = peg$FAILED;
1307 }
1308 if (s2 !== peg$FAILED) {
1309 peg$savedPos = s0;
1310 s1 = peg$c32(s1);
1311 s0 = s1;
1312 } else {
1313 peg$currPos = s0;
1314 s0 = peg$FAILED;
1315 }
1316 } else {
1317 peg$currPos = s0;
1318 s0 = peg$FAILED;
1319 }
1320
1321 return s0;
1322 }
1323
1324 function peg$parseSemanticPredicateExpression() {
1325 var s0, s1, s2, s3;
1326
1327 s0 = peg$currPos;
1328 s1 = peg$parseSemanticPredicateOperator();
1329 if (s1 !== peg$FAILED) {
1330 s2 = peg$parse__();
1331 if (s2 !== peg$FAILED) {
1332 s3 = peg$parseCodeBlock();
1333 if (s3 !== peg$FAILED) {
1334 peg$savedPos = s0;
1335 s1 = peg$c33(s1, s3);
1336 s0 = s1;
1337 } else {
1338 peg$currPos = s0;
1339 s0 = peg$FAILED;
1340 }
1341 } else {
1342 peg$currPos = s0;
1343 s0 = peg$FAILED;
1344 }
1345 } else {
1346 peg$currPos = s0;
1347 s0 = peg$FAILED;
1348 }
1349
1350 return s0;
1351 }
1352
1353 function peg$parseSemanticPredicateOperator() {
1354 var s0;
1355
1356 if (input.charCodeAt(peg$currPos) === 38) {
1357 s0 = peg$c16;
1358 peg$currPos++;
1359 } else {
1360 s0 = peg$FAILED;
1361 if (peg$silentFails === 0) { peg$fail(peg$c17); }
1362 }
1363 if (s0 === peg$FAILED) {
1364 if (input.charCodeAt(peg$currPos) === 33) {
1365 s0 = peg$c18;
1366 peg$currPos++;
1367 } else {
1368 s0 = peg$FAILED;
1369 if (peg$silentFails === 0) { peg$fail(peg$c19); }
1370 }
1371 }
1372
1373 return s0;
1374 }
1375
1376 function peg$parseSourceCharacter() {
1377 var s0;
1378
1379 if (input.length > peg$currPos) {
1380 s0 = input.charAt(peg$currPos);
1381 peg$currPos++;
1382 } else {
1383 s0 = peg$FAILED;
1384 if (peg$silentFails === 0) { peg$fail(peg$c34); }
1385 }
1386
1387 return s0;
1388 }
1389
1390 function peg$parseWhiteSpace() {
1391 var s0, s1;
1392
1393 peg$silentFails++;
1394 if (input.charCodeAt(peg$currPos) === 9) {
1395 s0 = peg$c36;
1396 peg$currPos++;
1397 } else {
1398 s0 = peg$FAILED;
1399 if (peg$silentFails === 0) { peg$fail(peg$c37); }
1400 }
1401 if (s0 === peg$FAILED) {
1402 if (input.charCodeAt(peg$currPos) === 11) {
1403 s0 = peg$c38;
1404 peg$currPos++;
1405 } else {
1406 s0 = peg$FAILED;
1407 if (peg$silentFails === 0) { peg$fail(peg$c39); }
1408 }
1409 if (s0 === peg$FAILED) {
1410 if (input.charCodeAt(peg$currPos) === 12) {
1411 s0 = peg$c40;
1412 peg$currPos++;
1413 } else {
1414 s0 = peg$FAILED;
1415 if (peg$silentFails === 0) { peg$fail(peg$c41); }
1416 }
1417 if (s0 === peg$FAILED) {
1418 if (input.charCodeAt(peg$currPos) === 32) {
1419 s0 = peg$c42;
1420 peg$currPos++;
1421 } else {
1422 s0 = peg$FAILED;
1423 if (peg$silentFails === 0) { peg$fail(peg$c43); }
1424 }
1425 if (s0 === peg$FAILED) {
1426 if (input.charCodeAt(peg$currPos) === 160) {
1427 s0 = peg$c44;
1428 peg$currPos++;
1429 } else {
1430 s0 = peg$FAILED;
1431 if (peg$silentFails === 0) { peg$fail(peg$c45); }
1432 }
1433 if (s0 === peg$FAILED) {
1434 if (input.charCodeAt(peg$currPos) === 65279) {
1435 s0 = peg$c46;
1436 peg$currPos++;
1437 } else {
1438 s0 = peg$FAILED;
1439 if (peg$silentFails === 0) { peg$fail(peg$c47); }
1440 }
1441 if (s0 === peg$FAILED) {
1442 s0 = peg$parseZs();
1443 }
1444 }
1445 }
1446 }
1447 }
1448 }
1449 peg$silentFails--;
1450 if (s0 === peg$FAILED) {
1451 s1 = peg$FAILED;
1452 if (peg$silentFails === 0) { peg$fail(peg$c35); }
1453 }
1454
1455 return s0;
1456 }
1457
1458 function peg$parseLineTerminator() {
1459 var s0;
1460
1461 if (peg$c48.test(input.charAt(peg$currPos))) {
1462 s0 = input.charAt(peg$currPos);
1463 peg$currPos++;
1464 } else {
1465 s0 = peg$FAILED;
1466 if (peg$silentFails === 0) { peg$fail(peg$c49); }
1467 }
1468
1469 return s0;
1470 }
1471
1472 function peg$parseLineTerminatorSequence() {
1473 var s0, s1;
1474
1475 peg$silentFails++;
1476 if (input.charCodeAt(peg$currPos) === 10) {
1477 s0 = peg$c51;
1478 peg$currPos++;
1479 } else {
1480 s0 = peg$FAILED;
1481 if (peg$silentFails === 0) { peg$fail(peg$c52); }
1482 }
1483 if (s0 === peg$FAILED) {
1484 if (input.substr(peg$currPos, 2) === peg$c53) {
1485 s0 = peg$c53;
1486 peg$currPos += 2;
1487 } else {
1488 s0 = peg$FAILED;
1489 if (peg$silentFails === 0) { peg$fail(peg$c54); }
1490 }
1491 if (s0 === peg$FAILED) {
1492 if (input.charCodeAt(peg$currPos) === 13) {
1493 s0 = peg$c55;
1494 peg$currPos++;
1495 } else {
1496 s0 = peg$FAILED;
1497 if (peg$silentFails === 0) { peg$fail(peg$c56); }
1498 }
1499 if (s0 === peg$FAILED) {
1500 if (input.charCodeAt(peg$currPos) === 8232) {
1501 s0 = peg$c57;
1502 peg$currPos++;
1503 } else {
1504 s0 = peg$FAILED;
1505 if (peg$silentFails === 0) { peg$fail(peg$c58); }
1506 }
1507 if (s0 === peg$FAILED) {
1508 if (input.charCodeAt(peg$currPos) === 8233) {
1509 s0 = peg$c59;
1510 peg$currPos++;
1511 } else {
1512 s0 = peg$FAILED;
1513 if (peg$silentFails === 0) { peg$fail(peg$c60); }
1514 }
1515 }
1516 }
1517 }
1518 }
1519 peg$silentFails--;
1520 if (s0 === peg$FAILED) {
1521 s1 = peg$FAILED;
1522 if (peg$silentFails === 0) { peg$fail(peg$c50); }
1523 }
1524
1525 return s0;
1526 }
1527
1528 function peg$parseComment() {
1529 var s0, s1;
1530
1531 peg$silentFails++;
1532 s0 = peg$parseMultiLineComment();
1533 if (s0 === peg$FAILED) {
1534 s0 = peg$parseSingleLineComment();
1535 }
1536 peg$silentFails--;
1537 if (s0 === peg$FAILED) {
1538 s1 = peg$FAILED;
1539 if (peg$silentFails === 0) { peg$fail(peg$c61); }
1540 }
1541
1542 return s0;
1543 }
1544
1545 function peg$parseMultiLineComment() {
1546 var s0, s1, s2, s3, s4, s5;
1547
1548 s0 = peg$currPos;
1549 if (input.substr(peg$currPos, 2) === peg$c62) {
1550 s1 = peg$c62;
1551 peg$currPos += 2;
1552 } else {
1553 s1 = peg$FAILED;
1554 if (peg$silentFails === 0) { peg$fail(peg$c63); }
1555 }
1556 if (s1 !== peg$FAILED) {
1557 s2 = [];
1558 s3 = peg$currPos;
1559 s4 = peg$currPos;
1560 peg$silentFails++;
1561 if (input.substr(peg$currPos, 2) === peg$c64) {
1562 s5 = peg$c64;
1563 peg$currPos += 2;
1564 } else {
1565 s5 = peg$FAILED;
1566 if (peg$silentFails === 0) { peg$fail(peg$c65); }
1567 }
1568 peg$silentFails--;
1569 if (s5 === peg$FAILED) {
1570 s4 = void 0;
1571 } else {
1572 peg$currPos = s4;
1573 s4 = peg$FAILED;
1574 }
1575 if (s4 !== peg$FAILED) {
1576 s5 = peg$parseSourceCharacter();
1577 if (s5 !== peg$FAILED) {
1578 s4 = [s4, s5];
1579 s3 = s4;
1580 } else {
1581 peg$currPos = s3;
1582 s3 = peg$FAILED;
1583 }
1584 } else {
1585 peg$currPos = s3;
1586 s3 = peg$FAILED;
1587 }
1588 while (s3 !== peg$FAILED) {
1589 s2.push(s3);
1590 s3 = peg$currPos;
1591 s4 = peg$currPos;
1592 peg$silentFails++;
1593 if (input.substr(peg$currPos, 2) === peg$c64) {
1594 s5 = peg$c64;
1595 peg$currPos += 2;
1596 } else {
1597 s5 = peg$FAILED;
1598 if (peg$silentFails === 0) { peg$fail(peg$c65); }
1599 }
1600 peg$silentFails--;
1601 if (s5 === peg$FAILED) {
1602 s4 = void 0;
1603 } else {
1604 peg$currPos = s4;
1605 s4 = peg$FAILED;
1606 }
1607 if (s4 !== peg$FAILED) {
1608 s5 = peg$parseSourceCharacter();
1609 if (s5 !== peg$FAILED) {
1610 s4 = [s4, s5];
1611 s3 = s4;
1612 } else {
1613 peg$currPos = s3;
1614 s3 = peg$FAILED;
1615 }
1616 } else {
1617 peg$currPos = s3;
1618 s3 = peg$FAILED;
1619 }
1620 }
1621 if (s2 !== peg$FAILED) {
1622 if (input.substr(peg$currPos, 2) === peg$c64) {
1623 s3 = peg$c64;
1624 peg$currPos += 2;
1625 } else {
1626 s3 = peg$FAILED;
1627 if (peg$silentFails === 0) { peg$fail(peg$c65); }
1628 }
1629 if (s3 !== peg$FAILED) {
1630 s1 = [s1, s2, s3];
1631 s0 = s1;
1632 } else {
1633 peg$currPos = s0;
1634 s0 = peg$FAILED;
1635 }
1636 } else {
1637 peg$currPos = s0;
1638 s0 = peg$FAILED;
1639 }
1640 } else {
1641 peg$currPos = s0;
1642 s0 = peg$FAILED;
1643 }
1644
1645 return s0;
1646 }
1647
1648 function peg$parseMultiLineCommentNoLineTerminator() {
1649 var s0, s1, s2, s3, s4, s5;
1650
1651 s0 = peg$currPos;
1652 if (input.substr(peg$currPos, 2) === peg$c62) {
1653 s1 = peg$c62;
1654 peg$currPos += 2;
1655 } else {
1656 s1 = peg$FAILED;
1657 if (peg$silentFails === 0) { peg$fail(peg$c63); }
1658 }
1659 if (s1 !== peg$FAILED) {
1660 s2 = [];
1661 s3 = peg$currPos;
1662 s4 = peg$currPos;
1663 peg$silentFails++;
1664 if (input.substr(peg$currPos, 2) === peg$c64) {
1665 s5 = peg$c64;
1666 peg$currPos += 2;
1667 } else {
1668 s5 = peg$FAILED;
1669 if (peg$silentFails === 0) { peg$fail(peg$c65); }
1670 }
1671 if (s5 === peg$FAILED) {
1672 s5 = peg$parseLineTerminator();
1673 }
1674 peg$silentFails--;
1675 if (s5 === peg$FAILED) {
1676 s4 = void 0;
1677 } else {
1678 peg$currPos = s4;
1679 s4 = peg$FAILED;
1680 }
1681 if (s4 !== peg$FAILED) {
1682 s5 = peg$parseSourceCharacter();
1683 if (s5 !== peg$FAILED) {
1684 s4 = [s4, s5];
1685 s3 = s4;
1686 } else {
1687 peg$currPos = s3;
1688 s3 = peg$FAILED;
1689 }
1690 } else {
1691 peg$currPos = s3;
1692 s3 = peg$FAILED;
1693 }
1694 while (s3 !== peg$FAILED) {
1695 s2.push(s3);
1696 s3 = peg$currPos;
1697 s4 = peg$currPos;
1698 peg$silentFails++;
1699 if (input.substr(peg$currPos, 2) === peg$c64) {
1700 s5 = peg$c64;
1701 peg$currPos += 2;
1702 } else {
1703 s5 = peg$FAILED;
1704 if (peg$silentFails === 0) { peg$fail(peg$c65); }
1705 }
1706 if (s5 === peg$FAILED) {
1707 s5 = peg$parseLineTerminator();
1708 }
1709 peg$silentFails--;
1710 if (s5 === peg$FAILED) {
1711 s4 = void 0;
1712 } else {
1713 peg$currPos = s4;
1714 s4 = peg$FAILED;
1715 }
1716 if (s4 !== peg$FAILED) {
1717 s5 = peg$parseSourceCharacter();
1718 if (s5 !== peg$FAILED) {
1719 s4 = [s4, s5];
1720 s3 = s4;
1721 } else {
1722 peg$currPos = s3;
1723 s3 = peg$FAILED;
1724 }
1725 } else {
1726 peg$currPos = s3;
1727 s3 = peg$FAILED;
1728 }
1729 }
1730 if (s2 !== peg$FAILED) {
1731 if (input.substr(peg$currPos, 2) === peg$c64) {
1732 s3 = peg$c64;
1733 peg$currPos += 2;
1734 } else {
1735 s3 = peg$FAILED;
1736 if (peg$silentFails === 0) { peg$fail(peg$c65); }
1737 }
1738 if (s3 !== peg$FAILED) {
1739 s1 = [s1, s2, s3];
1740 s0 = s1;
1741 } else {
1742 peg$currPos = s0;
1743 s0 = peg$FAILED;
1744 }
1745 } else {
1746 peg$currPos = s0;
1747 s0 = peg$FAILED;
1748 }
1749 } else {
1750 peg$currPos = s0;
1751 s0 = peg$FAILED;
1752 }
1753
1754 return s0;
1755 }
1756
1757 function peg$parseSingleLineComment() {
1758 var s0, s1, s2, s3, s4, s5;
1759
1760 s0 = peg$currPos;
1761 if (input.substr(peg$currPos, 2) === peg$c66) {
1762 s1 = peg$c66;
1763 peg$currPos += 2;
1764 } else {
1765 s1 = peg$FAILED;
1766 if (peg$silentFails === 0) { peg$fail(peg$c67); }
1767 }
1768 if (s1 !== peg$FAILED) {
1769 s2 = [];
1770 s3 = peg$currPos;
1771 s4 = peg$currPos;
1772 peg$silentFails++;
1773 s5 = peg$parseLineTerminator();
1774 peg$silentFails--;
1775 if (s5 === peg$FAILED) {
1776 s4 = void 0;
1777 } else {
1778 peg$currPos = s4;
1779 s4 = peg$FAILED;
1780 }
1781 if (s4 !== peg$FAILED) {
1782 s5 = peg$parseSourceCharacter();
1783 if (s5 !== peg$FAILED) {
1784 s4 = [s4, s5];
1785 s3 = s4;
1786 } else {
1787 peg$currPos = s3;
1788 s3 = peg$FAILED;
1789 }
1790 } else {
1791 peg$currPos = s3;
1792 s3 = peg$FAILED;
1793 }
1794 while (s3 !== peg$FAILED) {
1795 s2.push(s3);
1796 s3 = peg$currPos;
1797 s4 = peg$currPos;
1798 peg$silentFails++;
1799 s5 = peg$parseLineTerminator();
1800 peg$silentFails--;
1801 if (s5 === peg$FAILED) {
1802 s4 = void 0;
1803 } else {
1804 peg$currPos = s4;
1805 s4 = peg$FAILED;
1806 }
1807 if (s4 !== peg$FAILED) {
1808 s5 = peg$parseSourceCharacter();
1809 if (s5 !== peg$FAILED) {
1810 s4 = [s4, s5];
1811 s3 = s4;
1812 } else {
1813 peg$currPos = s3;
1814 s3 = peg$FAILED;
1815 }
1816 } else {
1817 peg$currPos = s3;
1818 s3 = peg$FAILED;
1819 }
1820 }
1821 if (s2 !== peg$FAILED) {
1822 s1 = [s1, s2];
1823 s0 = s1;
1824 } else {
1825 peg$currPos = s0;
1826 s0 = peg$FAILED;
1827 }
1828 } else {
1829 peg$currPos = s0;
1830 s0 = peg$FAILED;
1831 }
1832
1833 return s0;
1834 }
1835
1836 function peg$parseIdentifier() {
1837 var s0, s1, s2;
1838
1839 s0 = peg$currPos;
1840 s1 = peg$currPos;
1841 peg$silentFails++;
1842 s2 = peg$parseReservedWord();
1843 peg$silentFails--;
1844 if (s2 === peg$FAILED) {
1845 s1 = void 0;
1846 } else {
1847 peg$currPos = s1;
1848 s1 = peg$FAILED;
1849 }
1850 if (s1 !== peg$FAILED) {
1851 s2 = peg$parseIdentifierName();
1852 if (s2 !== peg$FAILED) {
1853 peg$savedPos = s0;
1854 s1 = peg$c68(s2);
1855 s0 = s1;
1856 } else {
1857 peg$currPos = s0;
1858 s0 = peg$FAILED;
1859 }
1860 } else {
1861 peg$currPos = s0;
1862 s0 = peg$FAILED;
1863 }
1864
1865 return s0;
1866 }
1867
1868 function peg$parseIdentifierName() {
1869 var s0, s1, s2, s3;
1870
1871 peg$silentFails++;
1872 s0 = peg$currPos;
1873 s1 = peg$parseIdentifierStart();
1874 if (s1 !== peg$FAILED) {
1875 s2 = [];
1876 s3 = peg$parseIdentifierPart();
1877 while (s3 !== peg$FAILED) {
1878 s2.push(s3);
1879 s3 = peg$parseIdentifierPart();
1880 }
1881 if (s2 !== peg$FAILED) {
1882 peg$savedPos = s0;
1883 s1 = peg$c70(s1, s2);
1884 s0 = s1;
1885 } else {
1886 peg$currPos = s0;
1887 s0 = peg$FAILED;
1888 }
1889 } else {
1890 peg$currPos = s0;
1891 s0 = peg$FAILED;
1892 }
1893 peg$silentFails--;
1894 if (s0 === peg$FAILED) {
1895 s1 = peg$FAILED;
1896 if (peg$silentFails === 0) { peg$fail(peg$c69); }
1897 }
1898
1899 return s0;
1900 }
1901
1902 function peg$parseIdentifierStart() {
1903 var s0, s1, s2;
1904
1905 s0 = peg$parseUnicodeLetter();
1906 if (s0 === peg$FAILED) {
1907 if (input.charCodeAt(peg$currPos) === 36) {
1908 s0 = peg$c14;
1909 peg$currPos++;
1910 } else {
1911 s0 = peg$FAILED;
1912 if (peg$silentFails === 0) { peg$fail(peg$c15); }
1913 }
1914 if (s0 === peg$FAILED) {
1915 if (input.charCodeAt(peg$currPos) === 95) {
1916 s0 = peg$c71;
1917 peg$currPos++;
1918 } else {
1919 s0 = peg$FAILED;
1920 if (peg$silentFails === 0) { peg$fail(peg$c72); }
1921 }
1922 if (s0 === peg$FAILED) {
1923 s0 = peg$currPos;
1924 if (input.charCodeAt(peg$currPos) === 92) {
1925 s1 = peg$c73;
1926 peg$currPos++;
1927 } else {
1928 s1 = peg$FAILED;
1929 if (peg$silentFails === 0) { peg$fail(peg$c74); }
1930 }
1931 if (s1 !== peg$FAILED) {
1932 s2 = peg$parseUnicodeEscapeSequence();
1933 if (s2 !== peg$FAILED) {
1934 peg$savedPos = s0;
1935 s1 = peg$c75(s2);
1936 s0 = s1;
1937 } else {
1938 peg$currPos = s0;
1939 s0 = peg$FAILED;
1940 }
1941 } else {
1942 peg$currPos = s0;
1943 s0 = peg$FAILED;
1944 }
1945 }
1946 }
1947 }
1948
1949 return s0;
1950 }
1951
1952 function peg$parseIdentifierPart() {
1953 var s0;
1954
1955 s0 = peg$parseIdentifierStart();
1956 if (s0 === peg$FAILED) {
1957 s0 = peg$parseUnicodeCombiningMark();
1958 if (s0 === peg$FAILED) {
1959 s0 = peg$parseNd();
1960 if (s0 === peg$FAILED) {
1961 s0 = peg$parsePc();
1962 if (s0 === peg$FAILED) {
1963 if (input.charCodeAt(peg$currPos) === 8204) {
1964 s0 = peg$c76;
1965 peg$currPos++;
1966 } else {
1967 s0 = peg$FAILED;
1968 if (peg$silentFails === 0) { peg$fail(peg$c77); }
1969 }
1970 if (s0 === peg$FAILED) {
1971 if (input.charCodeAt(peg$currPos) === 8205) {
1972 s0 = peg$c78;
1973 peg$currPos++;
1974 } else {
1975 s0 = peg$FAILED;
1976 if (peg$silentFails === 0) { peg$fail(peg$c79); }
1977 }
1978 }
1979 }
1980 }
1981 }
1982 }
1983
1984 return s0;
1985 }
1986
1987 function peg$parseUnicodeLetter() {
1988 var s0;
1989
1990 s0 = peg$parseLu();
1991 if (s0 === peg$FAILED) {
1992 s0 = peg$parseLl();
1993 if (s0 === peg$FAILED) {
1994 s0 = peg$parseLt();
1995 if (s0 === peg$FAILED) {
1996 s0 = peg$parseLm();
1997 if (s0 === peg$FAILED) {
1998 s0 = peg$parseLo();
1999 if (s0 === peg$FAILED) {
2000 s0 = peg$parseNl();
2001 }
2002 }
2003 }
2004 }
2005 }
2006
2007 return s0;
2008 }
2009
2010 function peg$parseUnicodeCombiningMark() {
2011 var s0;
2012
2013 s0 = peg$parseMn();
2014 if (s0 === peg$FAILED) {
2015 s0 = peg$parseMc();
2016 }
2017
2018 return s0;
2019 }
2020
2021 function peg$parseReservedWord() {
2022 var s0;
2023
2024 s0 = peg$parseKeyword();
2025 if (s0 === peg$FAILED) {
2026 s0 = peg$parseFutureReservedWord();
2027 if (s0 === peg$FAILED) {
2028 s0 = peg$parseNullToken();
2029 if (s0 === peg$FAILED) {
2030 s0 = peg$parseBooleanLiteral();
2031 }
2032 }
2033 }
2034
2035 return s0;
2036 }
2037
2038 function peg$parseKeyword() {
2039 var s0;
2040
2041 s0 = peg$parseBreakToken();
2042 if (s0 === peg$FAILED) {
2043 s0 = peg$parseCaseToken();
2044 if (s0 === peg$FAILED) {
2045 s0 = peg$parseCatchToken();
2046 if (s0 === peg$FAILED) {
2047 s0 = peg$parseContinueToken();
2048 if (s0 === peg$FAILED) {
2049 s0 = peg$parseDebuggerToken();
2050 if (s0 === peg$FAILED) {
2051 s0 = peg$parseDefaultToken();
2052 if (s0 === peg$FAILED) {
2053 s0 = peg$parseDeleteToken();
2054 if (s0 === peg$FAILED) {
2055 s0 = peg$parseDoToken();
2056 if (s0 === peg$FAILED) {
2057 s0 = peg$parseElseToken();
2058 if (s0 === peg$FAILED) {
2059 s0 = peg$parseFinallyToken();
2060 if (s0 === peg$FAILED) {
2061 s0 = peg$parseForToken();
2062 if (s0 === peg$FAILED) {
2063 s0 = peg$parseFunctionToken();
2064 if (s0 === peg$FAILED) {
2065 s0 = peg$parseIfToken();
2066 if (s0 === peg$FAILED) {
2067 s0 = peg$parseInstanceofToken();
2068 if (s0 === peg$FAILED) {
2069 s0 = peg$parseInToken();
2070 if (s0 === peg$FAILED) {
2071 s0 = peg$parseNewToken();
2072 if (s0 === peg$FAILED) {
2073 s0 = peg$parseReturnToken();
2074 if (s0 === peg$FAILED) {
2075 s0 = peg$parseSwitchToken();
2076 if (s0 === peg$FAILED) {
2077 s0 = peg$parseThisToken();
2078 if (s0 === peg$FAILED) {
2079 s0 = peg$parseThrowToken();
2080 if (s0 === peg$FAILED) {
2081 s0 = peg$parseTryToken();
2082 if (s0 === peg$FAILED) {
2083 s0 = peg$parseTypeofToken();
2084 if (s0 === peg$FAILED) {
2085 s0 = peg$parseVarToken();
2086 if (s0 === peg$FAILED) {
2087 s0 = peg$parseVoidToken();
2088 if (s0 === peg$FAILED) {
2089 s0 = peg$parseWhileToken();
2090 if (s0 === peg$FAILED) {
2091 s0 = peg$parseWithToken();
2092 }
2093 }
2094 }
2095 }
2096 }
2097 }
2098 }
2099 }
2100 }
2101 }
2102 }
2103 }
2104 }
2105 }
2106 }
2107 }
2108 }
2109 }
2110 }
2111 }
2112 }
2113 }
2114 }
2115 }
2116 }
2117
2118 return s0;
2119 }
2120
2121 function peg$parseFutureReservedWord() {
2122 var s0;
2123
2124 s0 = peg$parseClassToken();
2125 if (s0 === peg$FAILED) {
2126 s0 = peg$parseConstToken();
2127 if (s0 === peg$FAILED) {
2128 s0 = peg$parseEnumToken();
2129 if (s0 === peg$FAILED) {
2130 s0 = peg$parseExportToken();
2131 if (s0 === peg$FAILED) {
2132 s0 = peg$parseExtendsToken();
2133 if (s0 === peg$FAILED) {
2134 s0 = peg$parseImportToken();
2135 if (s0 === peg$FAILED) {
2136 s0 = peg$parseSuperToken();
2137 }
2138 }
2139 }
2140 }
2141 }
2142 }
2143
2144 return s0;
2145 }
2146
2147 function peg$parseBooleanLiteral() {
2148 var s0;
2149
2150 s0 = peg$parseTrueToken();
2151 if (s0 === peg$FAILED) {
2152 s0 = peg$parseFalseToken();
2153 }
2154
2155 return s0;
2156 }
2157
2158 function peg$parseLiteralMatcher() {
2159 var s0, s1, s2;
2160
2161 peg$silentFails++;
2162 s0 = peg$currPos;
2163 s1 = peg$parseStringLiteral();
2164 if (s1 !== peg$FAILED) {
2165 if (input.charCodeAt(peg$currPos) === 105) {
2166 s2 = peg$c81;
2167 peg$currPos++;
2168 } else {
2169 s2 = peg$FAILED;
2170 if (peg$silentFails === 0) { peg$fail(peg$c82); }
2171 }
2172 if (s2 === peg$FAILED) {
2173 s2 = null;
2174 }
2175 if (s2 !== peg$FAILED) {
2176 peg$savedPos = s0;
2177 s1 = peg$c83(s1, s2);
2178 s0 = s1;
2179 } else {
2180 peg$currPos = s0;
2181 s0 = peg$FAILED;
2182 }
2183 } else {
2184 peg$currPos = s0;
2185 s0 = peg$FAILED;
2186 }
2187 peg$silentFails--;
2188 if (s0 === peg$FAILED) {
2189 s1 = peg$FAILED;
2190 if (peg$silentFails === 0) { peg$fail(peg$c80); }
2191 }
2192
2193 return s0;
2194 }
2195
2196 function peg$parseStringLiteral() {
2197 var s0, s1, s2, s3;
2198
2199 peg$silentFails++;
2200 s0 = peg$currPos;
2201 if (input.charCodeAt(peg$currPos) === 34) {
2202 s1 = peg$c85;
2203 peg$currPos++;
2204 } else {
2205 s1 = peg$FAILED;
2206 if (peg$silentFails === 0) { peg$fail(peg$c86); }
2207 }
2208 if (s1 !== peg$FAILED) {
2209 s2 = [];
2210 s3 = peg$parseDoubleStringCharacter();
2211 while (s3 !== peg$FAILED) {
2212 s2.push(s3);
2213 s3 = peg$parseDoubleStringCharacter();
2214 }
2215 if (s2 !== peg$FAILED) {
2216 if (input.charCodeAt(peg$currPos) === 34) {
2217 s3 = peg$c85;
2218 peg$currPos++;
2219 } else {
2220 s3 = peg$FAILED;
2221 if (peg$silentFails === 0) { peg$fail(peg$c86); }
2222 }
2223 if (s3 !== peg$FAILED) {
2224 peg$savedPos = s0;
2225 s1 = peg$c87(s2);
2226 s0 = s1;
2227 } else {
2228 peg$currPos = s0;
2229 s0 = peg$FAILED;
2230 }
2231 } else {
2232 peg$currPos = s0;
2233 s0 = peg$FAILED;
2234 }
2235 } else {
2236 peg$currPos = s0;
2237 s0 = peg$FAILED;
2238 }
2239 if (s0 === peg$FAILED) {
2240 s0 = peg$currPos;
2241 if (input.charCodeAt(peg$currPos) === 39) {
2242 s1 = peg$c88;
2243 peg$currPos++;
2244 } else {
2245 s1 = peg$FAILED;
2246 if (peg$silentFails === 0) { peg$fail(peg$c89); }
2247 }
2248 if (s1 !== peg$FAILED) {
2249 s2 = [];
2250 s3 = peg$parseSingleStringCharacter();
2251 while (s3 !== peg$FAILED) {
2252 s2.push(s3);
2253 s3 = peg$parseSingleStringCharacter();
2254 }
2255 if (s2 !== peg$FAILED) {
2256 if (input.charCodeAt(peg$currPos) === 39) {
2257 s3 = peg$c88;
2258 peg$currPos++;
2259 } else {
2260 s3 = peg$FAILED;
2261 if (peg$silentFails === 0) { peg$fail(peg$c89); }
2262 }
2263 if (s3 !== peg$FAILED) {
2264 peg$savedPos = s0;
2265 s1 = peg$c87(s2);
2266 s0 = s1;
2267 } else {
2268 peg$currPos = s0;
2269 s0 = peg$FAILED;
2270 }
2271 } else {
2272 peg$currPos = s0;
2273 s0 = peg$FAILED;
2274 }
2275 } else {
2276 peg$currPos = s0;
2277 s0 = peg$FAILED;
2278 }
2279 }
2280 peg$silentFails--;
2281 if (s0 === peg$FAILED) {
2282 s1 = peg$FAILED;
2283 if (peg$silentFails === 0) { peg$fail(peg$c84); }
2284 }
2285
2286 return s0;
2287 }
2288
2289 function peg$parseDoubleStringCharacter() {
2290 var s0, s1, s2;
2291
2292 s0 = peg$currPos;
2293 s1 = peg$currPos;
2294 peg$silentFails++;
2295 if (input.charCodeAt(peg$currPos) === 34) {
2296 s2 = peg$c85;
2297 peg$currPos++;
2298 } else {
2299 s2 = peg$FAILED;
2300 if (peg$silentFails === 0) { peg$fail(peg$c86); }
2301 }
2302 if (s2 === peg$FAILED) {
2303 if (input.charCodeAt(peg$currPos) === 92) {
2304 s2 = peg$c73;
2305 peg$currPos++;
2306 } else {
2307 s2 = peg$FAILED;
2308 if (peg$silentFails === 0) { peg$fail(peg$c74); }
2309 }
2310 if (s2 === peg$FAILED) {
2311 s2 = peg$parseLineTerminator();
2312 }
2313 }
2314 peg$silentFails--;
2315 if (s2 === peg$FAILED) {
2316 s1 = void 0;
2317 } else {
2318 peg$currPos = s1;
2319 s1 = peg$FAILED;
2320 }
2321 if (s1 !== peg$FAILED) {
2322 s2 = peg$parseSourceCharacter();
2323 if (s2 !== peg$FAILED) {
2324 peg$savedPos = s0;
2325 s1 = peg$c90();
2326 s0 = s1;
2327 } else {
2328 peg$currPos = s0;
2329 s0 = peg$FAILED;
2330 }
2331 } else {
2332 peg$currPos = s0;
2333 s0 = peg$FAILED;
2334 }
2335 if (s0 === peg$FAILED) {
2336 s0 = peg$currPos;
2337 if (input.charCodeAt(peg$currPos) === 92) {
2338 s1 = peg$c73;
2339 peg$currPos++;
2340 } else {
2341 s1 = peg$FAILED;
2342 if (peg$silentFails === 0) { peg$fail(peg$c74); }
2343 }
2344 if (s1 !== peg$FAILED) {
2345 s2 = peg$parseEscapeSequence();
2346 if (s2 !== peg$FAILED) {
2347 peg$savedPos = s0;
2348 s1 = peg$c75(s2);
2349 s0 = s1;
2350 } else {
2351 peg$currPos = s0;
2352 s0 = peg$FAILED;
2353 }
2354 } else {
2355 peg$currPos = s0;
2356 s0 = peg$FAILED;
2357 }
2358 if (s0 === peg$FAILED) {
2359 s0 = peg$parseLineContinuation();
2360 }
2361 }
2362
2363 return s0;
2364 }
2365
2366 function peg$parseSingleStringCharacter() {
2367 var s0, s1, s2;
2368
2369 s0 = peg$currPos;
2370 s1 = peg$currPos;
2371 peg$silentFails++;
2372 if (input.charCodeAt(peg$currPos) === 39) {
2373 s2 = peg$c88;
2374 peg$currPos++;
2375 } else {
2376 s2 = peg$FAILED;
2377 if (peg$silentFails === 0) { peg$fail(peg$c89); }
2378 }
2379 if (s2 === peg$FAILED) {
2380 if (input.charCodeAt(peg$currPos) === 92) {
2381 s2 = peg$c73;
2382 peg$currPos++;
2383 } else {
2384 s2 = peg$FAILED;
2385 if (peg$silentFails === 0) { peg$fail(peg$c74); }
2386 }
2387 if (s2 === peg$FAILED) {
2388 s2 = peg$parseLineTerminator();
2389 }
2390 }
2391 peg$silentFails--;
2392 if (s2 === peg$FAILED) {
2393 s1 = void 0;
2394 } else {
2395 peg$currPos = s1;
2396 s1 = peg$FAILED;
2397 }
2398 if (s1 !== peg$FAILED) {
2399 s2 = peg$parseSourceCharacter();
2400 if (s2 !== peg$FAILED) {
2401 peg$savedPos = s0;
2402 s1 = peg$c90();
2403 s0 = s1;
2404 } else {
2405 peg$currPos = s0;
2406 s0 = peg$FAILED;
2407 }
2408 } else {
2409 peg$currPos = s0;
2410 s0 = peg$FAILED;
2411 }
2412 if (s0 === peg$FAILED) {
2413 s0 = peg$currPos;
2414 if (input.charCodeAt(peg$currPos) === 92) {
2415 s1 = peg$c73;
2416 peg$currPos++;
2417 } else {
2418 s1 = peg$FAILED;
2419 if (peg$silentFails === 0) { peg$fail(peg$c74); }
2420 }
2421 if (s1 !== peg$FAILED) {
2422 s2 = peg$parseEscapeSequence();
2423 if (s2 !== peg$FAILED) {
2424 peg$savedPos = s0;
2425 s1 = peg$c75(s2);
2426 s0 = s1;
2427 } else {
2428 peg$currPos = s0;
2429 s0 = peg$FAILED;
2430 }
2431 } else {
2432 peg$currPos = s0;
2433 s0 = peg$FAILED;
2434 }
2435 if (s0 === peg$FAILED) {
2436 s0 = peg$parseLineContinuation();
2437 }
2438 }
2439
2440 return s0;
2441 }
2442
2443 function peg$parseCharacterClassMatcher() {
2444 var s0, s1, s2, s3, s4, s5;
2445
2446 peg$silentFails++;
2447 s0 = peg$currPos;
2448 if (input.charCodeAt(peg$currPos) === 91) {
2449 s1 = peg$c92;
2450 peg$currPos++;
2451 } else {
2452 s1 = peg$FAILED;
2453 if (peg$silentFails === 0) { peg$fail(peg$c93); }
2454 }
2455 if (s1 !== peg$FAILED) {
2456 if (input.charCodeAt(peg$currPos) === 94) {
2457 s2 = peg$c94;
2458 peg$currPos++;
2459 } else {
2460 s2 = peg$FAILED;
2461 if (peg$silentFails === 0) { peg$fail(peg$c95); }
2462 }
2463 if (s2 === peg$FAILED) {
2464 s2 = null;
2465 }
2466 if (s2 !== peg$FAILED) {
2467 s3 = [];
2468 s4 = peg$parseClassCharacterRange();
2469 if (s4 === peg$FAILED) {
2470 s4 = peg$parseClassCharacter();
2471 }
2472 while (s4 !== peg$FAILED) {
2473 s3.push(s4);
2474 s4 = peg$parseClassCharacterRange();
2475 if (s4 === peg$FAILED) {
2476 s4 = peg$parseClassCharacter();
2477 }
2478 }
2479 if (s3 !== peg$FAILED) {
2480 if (input.charCodeAt(peg$currPos) === 93) {
2481 s4 = peg$c96;
2482 peg$currPos++;
2483 } else {
2484 s4 = peg$FAILED;
2485 if (peg$silentFails === 0) { peg$fail(peg$c97); }
2486 }
2487 if (s4 !== peg$FAILED) {
2488 if (input.charCodeAt(peg$currPos) === 105) {
2489 s5 = peg$c81;
2490 peg$currPos++;
2491 } else {
2492 s5 = peg$FAILED;
2493 if (peg$silentFails === 0) { peg$fail(peg$c82); }
2494 }
2495 if (s5 === peg$FAILED) {
2496 s5 = null;
2497 }
2498 if (s5 !== peg$FAILED) {
2499 peg$savedPos = s0;
2500 s1 = peg$c98(s2, s3, s5);
2501 s0 = s1;
2502 } else {
2503 peg$currPos = s0;
2504 s0 = peg$FAILED;
2505 }
2506 } else {
2507 peg$currPos = s0;
2508 s0 = peg$FAILED;
2509 }
2510 } else {
2511 peg$currPos = s0;
2512 s0 = peg$FAILED;
2513 }
2514 } else {
2515 peg$currPos = s0;
2516 s0 = peg$FAILED;
2517 }
2518 } else {
2519 peg$currPos = s0;
2520 s0 = peg$FAILED;
2521 }
2522 peg$silentFails--;
2523 if (s0 === peg$FAILED) {
2524 s1 = peg$FAILED;
2525 if (peg$silentFails === 0) { peg$fail(peg$c91); }
2526 }
2527
2528 return s0;
2529 }
2530
2531 function peg$parseClassCharacterRange() {
2532 var s0, s1, s2, s3;
2533
2534 s0 = peg$currPos;
2535 s1 = peg$parseClassCharacter();
2536 if (s1 !== peg$FAILED) {
2537 if (input.charCodeAt(peg$currPos) === 45) {
2538 s2 = peg$c99;
2539 peg$currPos++;
2540 } else {
2541 s2 = peg$FAILED;
2542 if (peg$silentFails === 0) { peg$fail(peg$c100); }
2543 }
2544 if (s2 !== peg$FAILED) {
2545 s3 = peg$parseClassCharacter();
2546 if (s3 !== peg$FAILED) {
2547 peg$savedPos = s0;
2548 s1 = peg$c101(s1, s3);
2549 s0 = s1;
2550 } else {
2551 peg$currPos = s0;
2552 s0 = peg$FAILED;
2553 }
2554 } else {
2555 peg$currPos = s0;
2556 s0 = peg$FAILED;
2557 }
2558 } else {
2559 peg$currPos = s0;
2560 s0 = peg$FAILED;
2561 }
2562
2563 return s0;
2564 }
2565
2566 function peg$parseClassCharacter() {
2567 var s0, s1, s2;
2568
2569 s0 = peg$currPos;
2570 s1 = peg$currPos;
2571 peg$silentFails++;
2572 if (input.charCodeAt(peg$currPos) === 93) {
2573 s2 = peg$c96;
2574 peg$currPos++;
2575 } else {
2576 s2 = peg$FAILED;
2577 if (peg$silentFails === 0) { peg$fail(peg$c97); }
2578 }
2579 if (s2 === peg$FAILED) {
2580 if (input.charCodeAt(peg$currPos) === 92) {
2581 s2 = peg$c73;
2582 peg$currPos++;
2583 } else {
2584 s2 = peg$FAILED;
2585 if (peg$silentFails === 0) { peg$fail(peg$c74); }
2586 }
2587 if (s2 === peg$FAILED) {
2588 s2 = peg$parseLineTerminator();
2589 }
2590 }
2591 peg$silentFails--;
2592 if (s2 === peg$FAILED) {
2593 s1 = void 0;
2594 } else {
2595 peg$currPos = s1;
2596 s1 = peg$FAILED;
2597 }
2598 if (s1 !== peg$FAILED) {
2599 s2 = peg$parseSourceCharacter();
2600 if (s2 !== peg$FAILED) {
2601 peg$savedPos = s0;
2602 s1 = peg$c90();
2603 s0 = s1;
2604 } else {
2605 peg$currPos = s0;
2606 s0 = peg$FAILED;
2607 }
2608 } else {
2609 peg$currPos = s0;
2610 s0 = peg$FAILED;
2611 }
2612 if (s0 === peg$FAILED) {
2613 s0 = peg$currPos;
2614 if (input.charCodeAt(peg$currPos) === 92) {
2615 s1 = peg$c73;
2616 peg$currPos++;
2617 } else {
2618 s1 = peg$FAILED;
2619 if (peg$silentFails === 0) { peg$fail(peg$c74); }
2620 }
2621 if (s1 !== peg$FAILED) {
2622 s2 = peg$parseEscapeSequence();
2623 if (s2 !== peg$FAILED) {
2624 peg$savedPos = s0;
2625 s1 = peg$c75(s2);
2626 s0 = s1;
2627 } else {
2628 peg$currPos = s0;
2629 s0 = peg$FAILED;
2630 }
2631 } else {
2632 peg$currPos = s0;
2633 s0 = peg$FAILED;
2634 }
2635 if (s0 === peg$FAILED) {
2636 s0 = peg$parseLineContinuation();
2637 }
2638 }
2639
2640 return s0;
2641 }
2642
2643 function peg$parseLineContinuation() {
2644 var s0, s1, s2;
2645
2646 s0 = peg$currPos;
2647 if (input.charCodeAt(peg$currPos) === 92) {
2648 s1 = peg$c73;
2649 peg$currPos++;
2650 } else {
2651 s1 = peg$FAILED;
2652 if (peg$silentFails === 0) { peg$fail(peg$c74); }
2653 }
2654 if (s1 !== peg$FAILED) {
2655 s2 = peg$parseLineTerminatorSequence();
2656 if (s2 !== peg$FAILED) {
2657 peg$savedPos = s0;
2658 s1 = peg$c102();
2659 s0 = s1;
2660 } else {
2661 peg$currPos = s0;
2662 s0 = peg$FAILED;
2663 }
2664 } else {
2665 peg$currPos = s0;
2666 s0 = peg$FAILED;
2667 }
2668
2669 return s0;
2670 }
2671
2672 function peg$parseEscapeSequence() {
2673 var s0, s1, s2, s3;
2674
2675 s0 = peg$parseCharacterEscapeSequence();
2676 if (s0 === peg$FAILED) {
2677 s0 = peg$currPos;
2678 if (input.charCodeAt(peg$currPos) === 48) {
2679 s1 = peg$c103;
2680 peg$currPos++;
2681 } else {
2682 s1 = peg$FAILED;
2683 if (peg$silentFails === 0) { peg$fail(peg$c104); }
2684 }
2685 if (s1 !== peg$FAILED) {
2686 s2 = peg$currPos;
2687 peg$silentFails++;
2688 s3 = peg$parseDecimalDigit();
2689 peg$silentFails--;
2690 if (s3 === peg$FAILED) {
2691 s2 = void 0;
2692 } else {
2693 peg$currPos = s2;
2694 s2 = peg$FAILED;
2695 }
2696 if (s2 !== peg$FAILED) {
2697 peg$savedPos = s0;
2698 s1 = peg$c105();
2699 s0 = s1;
2700 } else {
2701 peg$currPos = s0;
2702 s0 = peg$FAILED;
2703 }
2704 } else {
2705 peg$currPos = s0;
2706 s0 = peg$FAILED;
2707 }
2708 if (s0 === peg$FAILED) {
2709 s0 = peg$parseHexEscapeSequence();
2710 if (s0 === peg$FAILED) {
2711 s0 = peg$parseUnicodeEscapeSequence();
2712 }
2713 }
2714 }
2715
2716 return s0;
2717 }
2718
2719 function peg$parseCharacterEscapeSequence() {
2720 var s0;
2721
2722 s0 = peg$parseSingleEscapeCharacter();
2723 if (s0 === peg$FAILED) {
2724 s0 = peg$parseNonEscapeCharacter();
2725 }
2726
2727 return s0;
2728 }
2729
2730 function peg$parseSingleEscapeCharacter() {
2731 var s0, s1;
2732
2733 if (input.charCodeAt(peg$currPos) === 39) {
2734 s0 = peg$c88;
2735 peg$currPos++;
2736 } else {
2737 s0 = peg$FAILED;
2738 if (peg$silentFails === 0) { peg$fail(peg$c89); }
2739 }
2740 if (s0 === peg$FAILED) {
2741 if (input.charCodeAt(peg$currPos) === 34) {
2742 s0 = peg$c85;
2743 peg$currPos++;
2744 } else {
2745 s0 = peg$FAILED;
2746 if (peg$silentFails === 0) { peg$fail(peg$c86); }
2747 }
2748 if (s0 === peg$FAILED) {
2749 if (input.charCodeAt(peg$currPos) === 92) {
2750 s0 = peg$c73;
2751 peg$currPos++;
2752 } else {
2753 s0 = peg$FAILED;
2754 if (peg$silentFails === 0) { peg$fail(peg$c74); }
2755 }
2756 if (s0 === peg$FAILED) {
2757 s0 = peg$currPos;
2758 if (input.charCodeAt(peg$currPos) === 98) {
2759 s1 = peg$c106;
2760 peg$currPos++;
2761 } else {
2762 s1 = peg$FAILED;
2763 if (peg$silentFails === 0) { peg$fail(peg$c107); }
2764 }
2765 if (s1 !== peg$FAILED) {
2766 peg$savedPos = s0;
2767 s1 = peg$c108();
2768 }
2769 s0 = s1;
2770 if (s0 === peg$FAILED) {
2771 s0 = peg$currPos;
2772 if (input.charCodeAt(peg$currPos) === 102) {
2773 s1 = peg$c109;
2774 peg$currPos++;
2775 } else {
2776 s1 = peg$FAILED;
2777 if (peg$silentFails === 0) { peg$fail(peg$c110); }
2778 }
2779 if (s1 !== peg$FAILED) {
2780 peg$savedPos = s0;
2781 s1 = peg$c111();
2782 }
2783 s0 = s1;
2784 if (s0 === peg$FAILED) {
2785 s0 = peg$currPos;
2786 if (input.charCodeAt(peg$currPos) === 110) {
2787 s1 = peg$c112;
2788 peg$currPos++;
2789 } else {
2790 s1 = peg$FAILED;
2791 if (peg$silentFails === 0) { peg$fail(peg$c113); }
2792 }
2793 if (s1 !== peg$FAILED) {
2794 peg$savedPos = s0;
2795 s1 = peg$c114();
2796 }
2797 s0 = s1;
2798 if (s0 === peg$FAILED) {
2799 s0 = peg$currPos;
2800 if (input.charCodeAt(peg$currPos) === 114) {
2801 s1 = peg$c115;
2802 peg$currPos++;
2803 } else {
2804 s1 = peg$FAILED;
2805 if (peg$silentFails === 0) { peg$fail(peg$c116); }
2806 }
2807 if (s1 !== peg$FAILED) {
2808 peg$savedPos = s0;
2809 s1 = peg$c117();
2810 }
2811 s0 = s1;
2812 if (s0 === peg$FAILED) {
2813 s0 = peg$currPos;
2814 if (input.charCodeAt(peg$currPos) === 116) {
2815 s1 = peg$c118;
2816 peg$currPos++;
2817 } else {
2818 s1 = peg$FAILED;
2819 if (peg$silentFails === 0) { peg$fail(peg$c119); }
2820 }
2821 if (s1 !== peg$FAILED) {
2822 peg$savedPos = s0;
2823 s1 = peg$c120();
2824 }
2825 s0 = s1;
2826 if (s0 === peg$FAILED) {
2827 s0 = peg$currPos;
2828 if (input.charCodeAt(peg$currPos) === 118) {
2829 s1 = peg$c121;
2830 peg$currPos++;
2831 } else {
2832 s1 = peg$FAILED;
2833 if (peg$silentFails === 0) { peg$fail(peg$c122); }
2834 }
2835 if (s1 !== peg$FAILED) {
2836 peg$savedPos = s0;
2837 s1 = peg$c123();
2838 }
2839 s0 = s1;
2840 }
2841 }
2842 }
2843 }
2844 }
2845 }
2846 }
2847 }
2848
2849 return s0;
2850 }
2851
2852 function peg$parseNonEscapeCharacter() {
2853 var s0, s1, s2;
2854
2855 s0 = peg$currPos;
2856 s1 = peg$currPos;
2857 peg$silentFails++;
2858 s2 = peg$parseEscapeCharacter();
2859 if (s2 === peg$FAILED) {
2860 s2 = peg$parseLineTerminator();
2861 }
2862 peg$silentFails--;
2863 if (s2 === peg$FAILED) {
2864 s1 = void 0;
2865 } else {
2866 peg$currPos = s1;
2867 s1 = peg$FAILED;
2868 }
2869 if (s1 !== peg$FAILED) {
2870 s2 = peg$parseSourceCharacter();
2871 if (s2 !== peg$FAILED) {
2872 peg$savedPos = s0;
2873 s1 = peg$c90();
2874 s0 = s1;
2875 } else {
2876 peg$currPos = s0;
2877 s0 = peg$FAILED;
2878 }
2879 } else {
2880 peg$currPos = s0;
2881 s0 = peg$FAILED;
2882 }
2883
2884 return s0;
2885 }
2886
2887 function peg$parseEscapeCharacter() {
2888 var s0;
2889
2890 s0 = peg$parseSingleEscapeCharacter();
2891 if (s0 === peg$FAILED) {
2892 s0 = peg$parseDecimalDigit();
2893 if (s0 === peg$FAILED) {
2894 if (input.charCodeAt(peg$currPos) === 120) {
2895 s0 = peg$c124;
2896 peg$currPos++;
2897 } else {
2898 s0 = peg$FAILED;
2899 if (peg$silentFails === 0) { peg$fail(peg$c125); }
2900 }
2901 if (s0 === peg$FAILED) {
2902 if (input.charCodeAt(peg$currPos) === 117) {
2903 s0 = peg$c126;
2904 peg$currPos++;
2905 } else {
2906 s0 = peg$FAILED;
2907 if (peg$silentFails === 0) { peg$fail(peg$c127); }
2908 }
2909 }
2910 }
2911 }
2912
2913 return s0;
2914 }
2915
2916 function peg$parseHexEscapeSequence() {
2917 var s0, s1, s2, s3, s4, s5;
2918
2919 s0 = peg$currPos;
2920 if (input.charCodeAt(peg$currPos) === 120) {
2921 s1 = peg$c124;
2922 peg$currPos++;
2923 } else {
2924 s1 = peg$FAILED;
2925 if (peg$silentFails === 0) { peg$fail(peg$c125); }
2926 }
2927 if (s1 !== peg$FAILED) {
2928 s2 = peg$currPos;
2929 s3 = peg$currPos;
2930 s4 = peg$parseHexDigit();
2931 if (s4 !== peg$FAILED) {
2932 s5 = peg$parseHexDigit();
2933 if (s5 !== peg$FAILED) {
2934 s4 = [s4, s5];
2935 s3 = s4;
2936 } else {
2937 peg$currPos = s3;
2938 s3 = peg$FAILED;
2939 }
2940 } else {
2941 peg$currPos = s3;
2942 s3 = peg$FAILED;
2943 }
2944 if (s3 !== peg$FAILED) {
2945 s2 = input.substring(s2, peg$currPos);
2946 } else {
2947 s2 = s3;
2948 }
2949 if (s2 !== peg$FAILED) {
2950 peg$savedPos = s0;
2951 s1 = peg$c128(s2);
2952 s0 = s1;
2953 } else {
2954 peg$currPos = s0;
2955 s0 = peg$FAILED;
2956 }
2957 } else {
2958 peg$currPos = s0;
2959 s0 = peg$FAILED;
2960 }
2961
2962 return s0;
2963 }
2964
2965 function peg$parseUnicodeEscapeSequence() {
2966 var s0, s1, s2, s3, s4, s5, s6, s7;
2967
2968 s0 = peg$currPos;
2969 if (input.charCodeAt(peg$currPos) === 117) {
2970 s1 = peg$c126;
2971 peg$currPos++;
2972 } else {
2973 s1 = peg$FAILED;
2974 if (peg$silentFails === 0) { peg$fail(peg$c127); }
2975 }
2976 if (s1 !== peg$FAILED) {
2977 s2 = peg$currPos;
2978 s3 = peg$currPos;
2979 s4 = peg$parseHexDigit();
2980 if (s4 !== peg$FAILED) {
2981 s5 = peg$parseHexDigit();
2982 if (s5 !== peg$FAILED) {
2983 s6 = peg$parseHexDigit();
2984 if (s6 !== peg$FAILED) {
2985 s7 = peg$parseHexDigit();
2986 if (s7 !== peg$FAILED) {
2987 s4 = [s4, s5, s6, s7];
2988 s3 = s4;
2989 } else {
2990 peg$currPos = s3;
2991 s3 = peg$FAILED;
2992 }
2993 } else {
2994 peg$currPos = s3;
2995 s3 = peg$FAILED;
2996 }
2997 } else {
2998 peg$currPos = s3;
2999 s3 = peg$FAILED;
3000 }
3001 } else {
3002 peg$currPos = s3;
3003 s3 = peg$FAILED;
3004 }
3005 if (s3 !== peg$FAILED) {
3006 s2 = input.substring(s2, peg$currPos);
3007 } else {
3008 s2 = s3;
3009 }
3010 if (s2 !== peg$FAILED) {
3011 peg$savedPos = s0;
3012 s1 = peg$c128(s2);
3013 s0 = s1;
3014 } else {
3015 peg$currPos = s0;
3016 s0 = peg$FAILED;
3017 }
3018 } else {
3019 peg$currPos = s0;
3020 s0 = peg$FAILED;
3021 }
3022
3023 return s0;
3024 }
3025
3026 function peg$parseDecimalDigit() {
3027 var s0;
3028
3029 if (peg$c129.test(input.charAt(peg$currPos))) {
3030 s0 = input.charAt(peg$currPos);
3031 peg$currPos++;
3032 } else {
3033 s0 = peg$FAILED;
3034 if (peg$silentFails === 0) { peg$fail(peg$c130); }
3035 }
3036
3037 return s0;
3038 }
3039
3040 function peg$parseHexDigit() {
3041 var s0;
3042
3043 if (peg$c131.test(input.charAt(peg$currPos))) {
3044 s0 = input.charAt(peg$currPos);
3045 peg$currPos++;
3046 } else {
3047 s0 = peg$FAILED;
3048 if (peg$silentFails === 0) { peg$fail(peg$c132); }
3049 }
3050
3051 return s0;
3052 }
3053
3054 function peg$parseAnyMatcher() {
3055 var s0, s1;
3056
3057 s0 = peg$currPos;
3058 if (input.charCodeAt(peg$currPos) === 46) {
3059 s1 = peg$c133;
3060 peg$currPos++;
3061 } else {
3062 s1 = peg$FAILED;
3063 if (peg$silentFails === 0) { peg$fail(peg$c134); }
3064 }
3065 if (s1 !== peg$FAILED) {
3066 peg$savedPos = s0;
3067 s1 = peg$c135();
3068 }
3069 s0 = s1;
3070
3071 return s0;
3072 }
3073
3074 function peg$parseCodeBlock() {
3075 var s0, s1, s2, s3;
3076
3077 peg$silentFails++;
3078 s0 = peg$currPos;
3079 if (input.charCodeAt(peg$currPos) === 123) {
3080 s1 = peg$c137;
3081 peg$currPos++;
3082 } else {
3083 s1 = peg$FAILED;
3084 if (peg$silentFails === 0) { peg$fail(peg$c138); }
3085 }
3086 if (s1 !== peg$FAILED) {
3087 s2 = peg$parseCode();
3088 if (s2 !== peg$FAILED) {
3089 if (input.charCodeAt(peg$currPos) === 125) {
3090 s3 = peg$c139;
3091 peg$currPos++;
3092 } else {
3093 s3 = peg$FAILED;
3094 if (peg$silentFails === 0) { peg$fail(peg$c140); }
3095 }
3096 if (s3 !== peg$FAILED) {
3097 peg$savedPos = s0;
3098 s1 = peg$c141(s2);
3099 s0 = s1;
3100 } else {
3101 peg$currPos = s0;
3102 s0 = peg$FAILED;
3103 }
3104 } else {
3105 peg$currPos = s0;
3106 s0 = peg$FAILED;
3107 }
3108 } else {
3109 peg$currPos = s0;
3110 s0 = peg$FAILED;
3111 }
3112 peg$silentFails--;
3113 if (s0 === peg$FAILED) {
3114 s1 = peg$FAILED;
3115 if (peg$silentFails === 0) { peg$fail(peg$c136); }
3116 }
3117
3118 return s0;
3119 }
3120
3121 function peg$parseCode() {
3122 var s0, s1, s2, s3, s4, s5;
3123
3124 s0 = peg$currPos;
3125 s1 = [];
3126 s2 = [];
3127 s3 = peg$currPos;
3128 s4 = peg$currPos;
3129 peg$silentFails++;
3130 if (peg$c142.test(input.charAt(peg$currPos))) {
3131 s5 = input.charAt(peg$currPos);
3132 peg$currPos++;
3133 } else {
3134 s5 = peg$FAILED;
3135 if (peg$silentFails === 0) { peg$fail(peg$c143); }
3136 }
3137 peg$silentFails--;
3138 if (s5 === peg$FAILED) {
3139 s4 = void 0;
3140 } else {
3141 peg$currPos = s4;
3142 s4 = peg$FAILED;
3143 }
3144 if (s4 !== peg$FAILED) {
3145 s5 = peg$parseSourceCharacter();
3146 if (s5 !== peg$FAILED) {
3147 s4 = [s4, s5];
3148 s3 = s4;
3149 } else {
3150 peg$currPos = s3;
3151 s3 = peg$FAILED;
3152 }
3153 } else {
3154 peg$currPos = s3;
3155 s3 = peg$FAILED;
3156 }
3157 if (s3 !== peg$FAILED) {
3158 while (s3 !== peg$FAILED) {
3159 s2.push(s3);
3160 s3 = peg$currPos;
3161 s4 = peg$currPos;
3162 peg$silentFails++;
3163 if (peg$c142.test(input.charAt(peg$currPos))) {
3164 s5 = input.charAt(peg$currPos);
3165 peg$currPos++;
3166 } else {
3167 s5 = peg$FAILED;
3168 if (peg$silentFails === 0) { peg$fail(peg$c143); }
3169 }
3170 peg$silentFails--;
3171 if (s5 === peg$FAILED) {
3172 s4 = void 0;
3173 } else {
3174 peg$currPos = s4;
3175 s4 = peg$FAILED;
3176 }
3177 if (s4 !== peg$FAILED) {
3178 s5 = peg$parseSourceCharacter();
3179 if (s5 !== peg$FAILED) {
3180 s4 = [s4, s5];
3181 s3 = s4;
3182 } else {
3183 peg$currPos = s3;
3184 s3 = peg$FAILED;
3185 }
3186 } else {
3187 peg$currPos = s3;
3188 s3 = peg$FAILED;
3189 }
3190 }
3191 } else {
3192 s2 = peg$FAILED;
3193 }
3194 if (s2 === peg$FAILED) {
3195 s2 = peg$currPos;
3196 if (input.charCodeAt(peg$currPos) === 123) {
3197 s3 = peg$c137;
3198 peg$currPos++;
3199 } else {
3200 s3 = peg$FAILED;
3201 if (peg$silentFails === 0) { peg$fail(peg$c138); }
3202 }
3203 if (s3 !== peg$FAILED) {
3204 s4 = peg$parseCode();
3205 if (s4 !== peg$FAILED) {
3206 if (input.charCodeAt(peg$currPos) === 125) {
3207 s5 = peg$c139;
3208 peg$currPos++;
3209 } else {
3210 s5 = peg$FAILED;
3211 if (peg$silentFails === 0) { peg$fail(peg$c140); }
3212 }
3213 if (s5 !== peg$FAILED) {
3214 s3 = [s3, s4, s5];
3215 s2 = s3;
3216 } else {
3217 peg$currPos = s2;
3218 s2 = peg$FAILED;
3219 }
3220 } else {
3221 peg$currPos = s2;
3222 s2 = peg$FAILED;
3223 }
3224 } else {
3225 peg$currPos = s2;
3226 s2 = peg$FAILED;
3227 }
3228 }
3229 while (s2 !== peg$FAILED) {
3230 s1.push(s2);
3231 s2 = [];
3232 s3 = peg$currPos;
3233 s4 = peg$currPos;
3234 peg$silentFails++;
3235 if (peg$c142.test(input.charAt(peg$currPos))) {
3236 s5 = input.charAt(peg$currPos);
3237 peg$currPos++;
3238 } else {
3239 s5 = peg$FAILED;
3240 if (peg$silentFails === 0) { peg$fail(peg$c143); }
3241 }
3242 peg$silentFails--;
3243 if (s5 === peg$FAILED) {
3244 s4 = void 0;
3245 } else {
3246 peg$currPos = s4;
3247 s4 = peg$FAILED;
3248 }
3249 if (s4 !== peg$FAILED) {
3250 s5 = peg$parseSourceCharacter();
3251 if (s5 !== peg$FAILED) {
3252 s4 = [s4, s5];
3253 s3 = s4;
3254 } else {
3255 peg$currPos = s3;
3256 s3 = peg$FAILED;
3257 }
3258 } else {
3259 peg$currPos = s3;
3260 s3 = peg$FAILED;
3261 }
3262 if (s3 !== peg$FAILED) {
3263 while (s3 !== peg$FAILED) {
3264 s2.push(s3);
3265 s3 = peg$currPos;
3266 s4 = peg$currPos;
3267 peg$silentFails++;
3268 if (peg$c142.test(input.charAt(peg$currPos))) {
3269 s5 = input.charAt(peg$currPos);
3270 peg$currPos++;
3271 } else {
3272 s5 = peg$FAILED;
3273 if (peg$silentFails === 0) { peg$fail(peg$c143); }
3274 }
3275 peg$silentFails--;
3276 if (s5 === peg$FAILED) {
3277 s4 = void 0;
3278 } else {
3279 peg$currPos = s4;
3280 s4 = peg$FAILED;
3281 }
3282 if (s4 !== peg$FAILED) {
3283 s5 = peg$parseSourceCharacter();
3284 if (s5 !== peg$FAILED) {
3285 s4 = [s4, s5];
3286 s3 = s4;
3287 } else {
3288 peg$currPos = s3;
3289 s3 = peg$FAILED;
3290 }
3291 } else {
3292 peg$currPos = s3;
3293 s3 = peg$FAILED;
3294 }
3295 }
3296 } else {
3297 s2 = peg$FAILED;
3298 }
3299 if (s2 === peg$FAILED) {
3300 s2 = peg$currPos;
3301 if (input.charCodeAt(peg$currPos) === 123) {
3302 s3 = peg$c137;
3303 peg$currPos++;
3304 } else {
3305 s3 = peg$FAILED;
3306 if (peg$silentFails === 0) { peg$fail(peg$c138); }
3307 }
3308 if (s3 !== peg$FAILED) {
3309 s4 = peg$parseCode();
3310 if (s4 !== peg$FAILED) {
3311 if (input.charCodeAt(peg$currPos) === 125) {
3312 s5 = peg$c139;
3313 peg$currPos++;
3314 } else {
3315 s5 = peg$FAILED;
3316 if (peg$silentFails === 0) { peg$fail(peg$c140); }
3317 }
3318 if (s5 !== peg$FAILED) {
3319 s3 = [s3, s4, s5];
3320 s2 = s3;
3321 } else {
3322 peg$currPos = s2;
3323 s2 = peg$FAILED;
3324 }
3325 } else {
3326 peg$currPos = s2;
3327 s2 = peg$FAILED;
3328 }
3329 } else {
3330 peg$currPos = s2;
3331 s2 = peg$FAILED;
3332 }
3333 }
3334 }
3335 if (s1 !== peg$FAILED) {
3336 s0 = input.substring(s0, peg$currPos);
3337 } else {
3338 s0 = s1;
3339 }
3340
3341 return s0;
3342 }
3343
3344 function peg$parseLl() {
3345 var s0;
3346
3347 if (peg$c144.test(input.charAt(peg$currPos))) {
3348 s0 = input.charAt(peg$currPos);
3349 peg$currPos++;
3350 } else {
3351 s0 = peg$FAILED;
3352 if (peg$silentFails === 0) { peg$fail(peg$c145); }
3353 }
3354
3355 return s0;
3356 }
3357
3358 function peg$parseLm() {
3359 var s0;
3360
3361 if (peg$c146.test(input.charAt(peg$currPos))) {
3362 s0 = input.charAt(peg$currPos);
3363 peg$currPos++;
3364 } else {
3365 s0 = peg$FAILED;
3366 if (peg$silentFails === 0) { peg$fail(peg$c147); }
3367 }
3368
3369 return s0;
3370 }
3371
3372 function peg$parseLo() {
3373 var s0;
3374
3375 if (peg$c148.test(input.charAt(peg$currPos))) {
3376 s0 = input.charAt(peg$currPos);
3377 peg$currPos++;
3378 } else {
3379 s0 = peg$FAILED;
3380 if (peg$silentFails === 0) { peg$fail(peg$c149); }
3381 }
3382
3383 return s0;
3384 }
3385
3386 function peg$parseLt() {
3387 var s0;
3388
3389 if (peg$c150.test(input.charAt(peg$currPos))) {
3390 s0 = input.charAt(peg$currPos);
3391 peg$currPos++;
3392 } else {
3393 s0 = peg$FAILED;
3394 if (peg$silentFails === 0) { peg$fail(peg$c151); }
3395 }
3396
3397 return s0;
3398 }
3399
3400 function peg$parseLu() {
3401 var s0;
3402
3403 if (peg$c152.test(input.charAt(peg$currPos))) {
3404 s0 = input.charAt(peg$currPos);
3405 peg$currPos++;
3406 } else {
3407 s0 = peg$FAILED;
3408 if (peg$silentFails === 0) { peg$fail(peg$c153); }
3409 }
3410
3411 return s0;
3412 }
3413
3414 function peg$parseMc() {
3415 var s0;
3416
3417 if (peg$c154.test(input.charAt(peg$currPos))) {
3418 s0 = input.charAt(peg$currPos);
3419 peg$currPos++;
3420 } else {
3421 s0 = peg$FAILED;
3422 if (peg$silentFails === 0) { peg$fail(peg$c155); }
3423 }
3424
3425 return s0;
3426 }
3427
3428 function peg$parseMn() {
3429 var s0;
3430
3431 if (peg$c156.test(input.charAt(peg$currPos))) {
3432 s0 = input.charAt(peg$currPos);
3433 peg$currPos++;
3434 } else {
3435 s0 = peg$FAILED;
3436 if (peg$silentFails === 0) { peg$fail(peg$c157); }
3437 }
3438
3439 return s0;
3440 }
3441
3442 function peg$parseNd() {
3443 var s0;
3444
3445 if (peg$c158.test(input.charAt(peg$currPos))) {
3446 s0 = input.charAt(peg$currPos);
3447 peg$currPos++;
3448 } else {
3449 s0 = peg$FAILED;
3450 if (peg$silentFails === 0) { peg$fail(peg$c159); }
3451 }
3452
3453 return s0;
3454 }
3455
3456 function peg$parseNl() {
3457 var s0;
3458
3459 if (peg$c160.test(input.charAt(peg$currPos))) {
3460 s0 = input.charAt(peg$currPos);
3461 peg$currPos++;
3462 } else {
3463 s0 = peg$FAILED;
3464 if (peg$silentFails === 0) { peg$fail(peg$c161); }
3465 }
3466
3467 return s0;
3468 }
3469
3470 function peg$parsePc() {
3471 var s0;
3472
3473 if (peg$c162.test(input.charAt(peg$currPos))) {
3474 s0 = input.charAt(peg$currPos);
3475 peg$currPos++;
3476 } else {
3477 s0 = peg$FAILED;
3478 if (peg$silentFails === 0) { peg$fail(peg$c163); }
3479 }
3480
3481 return s0;
3482 }
3483
3484 function peg$parseZs() {
3485 var s0;
3486
3487 if (peg$c164.test(input.charAt(peg$currPos))) {
3488 s0 = input.charAt(peg$currPos);
3489 peg$currPos++;
3490 } else {
3491 s0 = peg$FAILED;
3492 if (peg$silentFails === 0) { peg$fail(peg$c165); }
3493 }
3494
3495 return s0;
3496 }
3497
3498 function peg$parseBreakToken() {
3499 var s0, s1, s2, s3;
3500
3501 s0 = peg$currPos;
3502 if (input.substr(peg$currPos, 5) === peg$c166) {
3503 s1 = peg$c166;
3504 peg$currPos += 5;
3505 } else {
3506 s1 = peg$FAILED;
3507 if (peg$silentFails === 0) { peg$fail(peg$c167); }
3508 }
3509 if (s1 !== peg$FAILED) {
3510 s2 = peg$currPos;
3511 peg$silentFails++;
3512 s3 = peg$parseIdentifierPart();
3513 peg$silentFails--;
3514 if (s3 === peg$FAILED) {
3515 s2 = void 0;
3516 } else {
3517 peg$currPos = s2;
3518 s2 = peg$FAILED;
3519 }
3520 if (s2 !== peg$FAILED) {
3521 s1 = [s1, s2];
3522 s0 = s1;
3523 } else {
3524 peg$currPos = s0;
3525 s0 = peg$FAILED;
3526 }
3527 } else {
3528 peg$currPos = s0;
3529 s0 = peg$FAILED;
3530 }
3531
3532 return s0;
3533 }
3534
3535 function peg$parseCaseToken() {
3536 var s0, s1, s2, s3;
3537
3538 s0 = peg$currPos;
3539 if (input.substr(peg$currPos, 4) === peg$c168) {
3540 s1 = peg$c168;
3541 peg$currPos += 4;
3542 } else {
3543 s1 = peg$FAILED;
3544 if (peg$silentFails === 0) { peg$fail(peg$c169); }
3545 }
3546 if (s1 !== peg$FAILED) {
3547 s2 = peg$currPos;
3548 peg$silentFails++;
3549 s3 = peg$parseIdentifierPart();
3550 peg$silentFails--;
3551 if (s3 === peg$FAILED) {
3552 s2 = void 0;
3553 } else {
3554 peg$currPos = s2;
3555 s2 = peg$FAILED;
3556 }
3557 if (s2 !== peg$FAILED) {
3558 s1 = [s1, s2];
3559 s0 = s1;
3560 } else {
3561 peg$currPos = s0;
3562 s0 = peg$FAILED;
3563 }
3564 } else {
3565 peg$currPos = s0;
3566 s0 = peg$FAILED;
3567 }
3568
3569 return s0;
3570 }
3571
3572 function peg$parseCatchToken() {
3573 var s0, s1, s2, s3;
3574
3575 s0 = peg$currPos;
3576 if (input.substr(peg$currPos, 5) === peg$c170) {
3577 s1 = peg$c170;
3578 peg$currPos += 5;
3579 } else {
3580 s1 = peg$FAILED;
3581 if (peg$silentFails === 0) { peg$fail(peg$c171); }
3582 }
3583 if (s1 !== peg$FAILED) {
3584 s2 = peg$currPos;
3585 peg$silentFails++;
3586 s3 = peg$parseIdentifierPart();
3587 peg$silentFails--;
3588 if (s3 === peg$FAILED) {
3589 s2 = void 0;
3590 } else {
3591 peg$currPos = s2;
3592 s2 = peg$FAILED;
3593 }
3594 if (s2 !== peg$FAILED) {
3595 s1 = [s1, s2];
3596 s0 = s1;
3597 } else {
3598 peg$currPos = s0;
3599 s0 = peg$FAILED;
3600 }
3601 } else {
3602 peg$currPos = s0;
3603 s0 = peg$FAILED;
3604 }
3605
3606 return s0;
3607 }
3608
3609 function peg$parseClassToken() {
3610 var s0, s1, s2, s3;
3611
3612 s0 = peg$currPos;
3613 if (input.substr(peg$currPos, 5) === peg$c172) {
3614 s1 = peg$c172;
3615 peg$currPos += 5;
3616 } else {
3617 s1 = peg$FAILED;
3618 if (peg$silentFails === 0) { peg$fail(peg$c173); }
3619 }
3620 if (s1 !== peg$FAILED) {
3621 s2 = peg$currPos;
3622 peg$silentFails++;
3623 s3 = peg$parseIdentifierPart();
3624 peg$silentFails--;
3625 if (s3 === peg$FAILED) {
3626 s2 = void 0;
3627 } else {
3628 peg$currPos = s2;
3629 s2 = peg$FAILED;
3630 }
3631 if (s2 !== peg$FAILED) {
3632 s1 = [s1, s2];
3633 s0 = s1;
3634 } else {
3635 peg$currPos = s0;
3636 s0 = peg$FAILED;
3637 }
3638 } else {
3639 peg$currPos = s0;
3640 s0 = peg$FAILED;
3641 }
3642
3643 return s0;
3644 }
3645
3646 function peg$parseConstToken() {
3647 var s0, s1, s2, s3;
3648
3649 s0 = peg$currPos;
3650 if (input.substr(peg$currPos, 5) === peg$c174) {
3651 s1 = peg$c174;
3652 peg$currPos += 5;
3653 } else {
3654 s1 = peg$FAILED;
3655 if (peg$silentFails === 0) { peg$fail(peg$c175); }
3656 }
3657 if (s1 !== peg$FAILED) {
3658 s2 = peg$currPos;
3659 peg$silentFails++;
3660 s3 = peg$parseIdentifierPart();
3661 peg$silentFails--;
3662 if (s3 === peg$FAILED) {
3663 s2 = void 0;
3664 } else {
3665 peg$currPos = s2;
3666 s2 = peg$FAILED;
3667 }
3668 if (s2 !== peg$FAILED) {
3669 s1 = [s1, s2];
3670 s0 = s1;
3671 } else {
3672 peg$currPos = s0;
3673 s0 = peg$FAILED;
3674 }
3675 } else {
3676 peg$currPos = s0;
3677 s0 = peg$FAILED;
3678 }
3679
3680 return s0;
3681 }
3682
3683 function peg$parseContinueToken() {
3684 var s0, s1, s2, s3;
3685
3686 s0 = peg$currPos;
3687 if (input.substr(peg$currPos, 8) === peg$c176) {
3688 s1 = peg$c176;
3689 peg$currPos += 8;
3690 } else {
3691 s1 = peg$FAILED;
3692 if (peg$silentFails === 0) { peg$fail(peg$c177); }
3693 }
3694 if (s1 !== peg$FAILED) {
3695 s2 = peg$currPos;
3696 peg$silentFails++;
3697 s3 = peg$parseIdentifierPart();
3698 peg$silentFails--;
3699 if (s3 === peg$FAILED) {
3700 s2 = void 0;
3701 } else {
3702 peg$currPos = s2;
3703 s2 = peg$FAILED;
3704 }
3705 if (s2 !== peg$FAILED) {
3706 s1 = [s1, s2];
3707 s0 = s1;
3708 } else {
3709 peg$currPos = s0;
3710 s0 = peg$FAILED;
3711 }
3712 } else {
3713 peg$currPos = s0;
3714 s0 = peg$FAILED;
3715 }
3716
3717 return s0;
3718 }
3719
3720 function peg$parseDebuggerToken() {
3721 var s0, s1, s2, s3;
3722
3723 s0 = peg$currPos;
3724 if (input.substr(peg$currPos, 8) === peg$c178) {
3725 s1 = peg$c178;
3726 peg$currPos += 8;
3727 } else {
3728 s1 = peg$FAILED;
3729 if (peg$silentFails === 0) { peg$fail(peg$c179); }
3730 }
3731 if (s1 !== peg$FAILED) {
3732 s2 = peg$currPos;
3733 peg$silentFails++;
3734 s3 = peg$parseIdentifierPart();
3735 peg$silentFails--;
3736 if (s3 === peg$FAILED) {
3737 s2 = void 0;
3738 } else {
3739 peg$currPos = s2;
3740 s2 = peg$FAILED;
3741 }
3742 if (s2 !== peg$FAILED) {
3743 s1 = [s1, s2];
3744 s0 = s1;
3745 } else {
3746 peg$currPos = s0;
3747 s0 = peg$FAILED;
3748 }
3749 } else {
3750 peg$currPos = s0;
3751 s0 = peg$FAILED;
3752 }
3753
3754 return s0;
3755 }
3756
3757 function peg$parseDefaultToken() {
3758 var s0, s1, s2, s3;
3759
3760 s0 = peg$currPos;
3761 if (input.substr(peg$currPos, 7) === peg$c180) {
3762 s1 = peg$c180;
3763 peg$currPos += 7;
3764 } else {
3765 s1 = peg$FAILED;
3766 if (peg$silentFails === 0) { peg$fail(peg$c181); }
3767 }
3768 if (s1 !== peg$FAILED) {
3769 s2 = peg$currPos;
3770 peg$silentFails++;
3771 s3 = peg$parseIdentifierPart();
3772 peg$silentFails--;
3773 if (s3 === peg$FAILED) {
3774 s2 = void 0;
3775 } else {
3776 peg$currPos = s2;
3777 s2 = peg$FAILED;
3778 }
3779 if (s2 !== peg$FAILED) {
3780 s1 = [s1, s2];
3781 s0 = s1;
3782 } else {
3783 peg$currPos = s0;
3784 s0 = peg$FAILED;
3785 }
3786 } else {
3787 peg$currPos = s0;
3788 s0 = peg$FAILED;
3789 }
3790
3791 return s0;
3792 }
3793
3794 function peg$parseDeleteToken() {
3795 var s0, s1, s2, s3;
3796
3797 s0 = peg$currPos;
3798 if (input.substr(peg$currPos, 6) === peg$c182) {
3799 s1 = peg$c182;
3800 peg$currPos += 6;
3801 } else {
3802 s1 = peg$FAILED;
3803 if (peg$silentFails === 0) { peg$fail(peg$c183); }
3804 }
3805 if (s1 !== peg$FAILED) {
3806 s2 = peg$currPos;
3807 peg$silentFails++;
3808 s3 = peg$parseIdentifierPart();
3809 peg$silentFails--;
3810 if (s3 === peg$FAILED) {
3811 s2 = void 0;
3812 } else {
3813 peg$currPos = s2;
3814 s2 = peg$FAILED;
3815 }
3816 if (s2 !== peg$FAILED) {
3817 s1 = [s1, s2];
3818 s0 = s1;
3819 } else {
3820 peg$currPos = s0;
3821 s0 = peg$FAILED;
3822 }
3823 } else {
3824 peg$currPos = s0;
3825 s0 = peg$FAILED;
3826 }
3827
3828 return s0;
3829 }
3830
3831 function peg$parseDoToken() {
3832 var s0, s1, s2, s3;
3833
3834 s0 = peg$currPos;
3835 if (input.substr(peg$currPos, 2) === peg$c184) {
3836 s1 = peg$c184;
3837 peg$currPos += 2;
3838 } else {
3839 s1 = peg$FAILED;
3840 if (peg$silentFails === 0) { peg$fail(peg$c185); }
3841 }
3842 if (s1 !== peg$FAILED) {
3843 s2 = peg$currPos;
3844 peg$silentFails++;
3845 s3 = peg$parseIdentifierPart();
3846 peg$silentFails--;
3847 if (s3 === peg$FAILED) {
3848 s2 = void 0;
3849 } else {
3850 peg$currPos = s2;
3851 s2 = peg$FAILED;
3852 }
3853 if (s2 !== peg$FAILED) {
3854 s1 = [s1, s2];
3855 s0 = s1;
3856 } else {
3857 peg$currPos = s0;
3858 s0 = peg$FAILED;
3859 }
3860 } else {
3861 peg$currPos = s0;
3862 s0 = peg$FAILED;
3863 }
3864
3865 return s0;
3866 }
3867
3868 function peg$parseElseToken() {
3869 var s0, s1, s2, s3;
3870
3871 s0 = peg$currPos;
3872 if (input.substr(peg$currPos, 4) === peg$c186) {
3873 s1 = peg$c186;
3874 peg$currPos += 4;
3875 } else {
3876 s1 = peg$FAILED;
3877 if (peg$silentFails === 0) { peg$fail(peg$c187); }
3878 }
3879 if (s1 !== peg$FAILED) {
3880 s2 = peg$currPos;
3881 peg$silentFails++;
3882 s3 = peg$parseIdentifierPart();
3883 peg$silentFails--;
3884 if (s3 === peg$FAILED) {
3885 s2 = void 0;
3886 } else {
3887 peg$currPos = s2;
3888 s2 = peg$FAILED;
3889 }
3890 if (s2 !== peg$FAILED) {
3891 s1 = [s1, s2];
3892 s0 = s1;
3893 } else {
3894 peg$currPos = s0;
3895 s0 = peg$FAILED;
3896 }
3897 } else {
3898 peg$currPos = s0;
3899 s0 = peg$FAILED;
3900 }
3901
3902 return s0;
3903 }
3904
3905 function peg$parseEnumToken() {
3906 var s0, s1, s2, s3;
3907
3908 s0 = peg$currPos;
3909 if (input.substr(peg$currPos, 4) === peg$c188) {
3910 s1 = peg$c188;
3911 peg$currPos += 4;
3912 } else {
3913 s1 = peg$FAILED;
3914 if (peg$silentFails === 0) { peg$fail(peg$c189); }
3915 }
3916 if (s1 !== peg$FAILED) {
3917 s2 = peg$currPos;
3918 peg$silentFails++;
3919 s3 = peg$parseIdentifierPart();
3920 peg$silentFails--;
3921 if (s3 === peg$FAILED) {
3922 s2 = void 0;
3923 } else {
3924 peg$currPos = s2;
3925 s2 = peg$FAILED;
3926 }
3927 if (s2 !== peg$FAILED) {
3928 s1 = [s1, s2];
3929 s0 = s1;
3930 } else {
3931 peg$currPos = s0;
3932 s0 = peg$FAILED;
3933 }
3934 } else {
3935 peg$currPos = s0;
3936 s0 = peg$FAILED;
3937 }
3938
3939 return s0;
3940 }
3941
3942 function peg$parseExportToken() {
3943 var s0, s1, s2, s3;
3944
3945 s0 = peg$currPos;
3946 if (input.substr(peg$currPos, 6) === peg$c190) {
3947 s1 = peg$c190;
3948 peg$currPos += 6;
3949 } else {
3950 s1 = peg$FAILED;
3951 if (peg$silentFails === 0) { peg$fail(peg$c191); }
3952 }
3953 if (s1 !== peg$FAILED) {
3954 s2 = peg$currPos;
3955 peg$silentFails++;
3956 s3 = peg$parseIdentifierPart();
3957 peg$silentFails--;
3958 if (s3 === peg$FAILED) {
3959 s2 = void 0;
3960 } else {
3961 peg$currPos = s2;
3962 s2 = peg$FAILED;
3963 }
3964 if (s2 !== peg$FAILED) {
3965 s1 = [s1, s2];
3966 s0 = s1;
3967 } else {
3968 peg$currPos = s0;
3969 s0 = peg$FAILED;
3970 }
3971 } else {
3972 peg$currPos = s0;
3973 s0 = peg$FAILED;
3974 }
3975
3976 return s0;
3977 }
3978
3979 function peg$parseExtendsToken() {
3980 var s0, s1, s2, s3;
3981
3982 s0 = peg$currPos;
3983 if (input.substr(peg$currPos, 7) === peg$c192) {
3984 s1 = peg$c192;
3985 peg$currPos += 7;
3986 } else {
3987 s1 = peg$FAILED;
3988 if (peg$silentFails === 0) { peg$fail(peg$c193); }
3989 }
3990 if (s1 !== peg$FAILED) {
3991 s2 = peg$currPos;
3992 peg$silentFails++;
3993 s3 = peg$parseIdentifierPart();
3994 peg$silentFails--;
3995 if (s3 === peg$FAILED) {
3996 s2 = void 0;
3997 } else {
3998 peg$currPos = s2;
3999 s2 = peg$FAILED;
4000 }
4001 if (s2 !== peg$FAILED) {
4002 s1 = [s1, s2];
4003 s0 = s1;
4004 } else {
4005 peg$currPos = s0;
4006 s0 = peg$FAILED;
4007 }
4008 } else {
4009 peg$currPos = s0;
4010 s0 = peg$FAILED;
4011 }
4012
4013 return s0;
4014 }
4015
4016 function peg$parseFalseToken() {
4017 var s0, s1, s2, s3;
4018
4019 s0 = peg$currPos;
4020 if (input.substr(peg$currPos, 5) === peg$c194) {
4021 s1 = peg$c194;
4022 peg$currPos += 5;
4023 } else {
4024 s1 = peg$FAILED;
4025 if (peg$silentFails === 0) { peg$fail(peg$c195); }
4026 }
4027 if (s1 !== peg$FAILED) {
4028 s2 = peg$currPos;
4029 peg$silentFails++;
4030 s3 = peg$parseIdentifierPart();
4031 peg$silentFails--;
4032 if (s3 === peg$FAILED) {
4033 s2 = void 0;
4034 } else {
4035 peg$currPos = s2;
4036 s2 = peg$FAILED;
4037 }
4038 if (s2 !== peg$FAILED) {
4039 s1 = [s1, s2];
4040 s0 = s1;
4041 } else {
4042 peg$currPos = s0;
4043 s0 = peg$FAILED;
4044 }
4045 } else {
4046 peg$currPos = s0;
4047 s0 = peg$FAILED;
4048 }
4049
4050 return s0;
4051 }
4052
4053 function peg$parseFinallyToken() {
4054 var s0, s1, s2, s3;
4055
4056 s0 = peg$currPos;
4057 if (input.substr(peg$currPos, 7) === peg$c196) {
4058 s1 = peg$c196;
4059 peg$currPos += 7;
4060 } else {
4061 s1 = peg$FAILED;
4062 if (peg$silentFails === 0) { peg$fail(peg$c197); }
4063 }
4064 if (s1 !== peg$FAILED) {
4065 s2 = peg$currPos;
4066 peg$silentFails++;
4067 s3 = peg$parseIdentifierPart();
4068 peg$silentFails--;
4069 if (s3 === peg$FAILED) {
4070 s2 = void 0;
4071 } else {
4072 peg$currPos = s2;
4073 s2 = peg$FAILED;
4074 }
4075 if (s2 !== peg$FAILED) {
4076 s1 = [s1, s2];
4077 s0 = s1;
4078 } else {
4079 peg$currPos = s0;
4080 s0 = peg$FAILED;
4081 }
4082 } else {
4083 peg$currPos = s0;
4084 s0 = peg$FAILED;
4085 }
4086
4087 return s0;
4088 }
4089
4090 function peg$parseForToken() {
4091 var s0, s1, s2, s3;
4092
4093 s0 = peg$currPos;
4094 if (input.substr(peg$currPos, 3) === peg$c198) {
4095 s1 = peg$c198;
4096 peg$currPos += 3;
4097 } else {
4098 s1 = peg$FAILED;
4099 if (peg$silentFails === 0) { peg$fail(peg$c199); }
4100 }
4101 if (s1 !== peg$FAILED) {
4102 s2 = peg$currPos;
4103 peg$silentFails++;
4104 s3 = peg$parseIdentifierPart();
4105 peg$silentFails--;
4106 if (s3 === peg$FAILED) {
4107 s2 = void 0;
4108 } else {
4109 peg$currPos = s2;
4110 s2 = peg$FAILED;
4111 }
4112 if (s2 !== peg$FAILED) {
4113 s1 = [s1, s2];
4114 s0 = s1;
4115 } else {
4116 peg$currPos = s0;
4117 s0 = peg$FAILED;
4118 }
4119 } else {
4120 peg$currPos = s0;
4121 s0 = peg$FAILED;
4122 }
4123
4124 return s0;
4125 }
4126
4127 function peg$parseFunctionToken() {
4128 var s0, s1, s2, s3;
4129
4130 s0 = peg$currPos;
4131 if (input.substr(peg$currPos, 8) === peg$c200) {
4132 s1 = peg$c200;
4133 peg$currPos += 8;
4134 } else {
4135 s1 = peg$FAILED;
4136 if (peg$silentFails === 0) { peg$fail(peg$c201); }
4137 }
4138 if (s1 !== peg$FAILED) {
4139 s2 = peg$currPos;
4140 peg$silentFails++;
4141 s3 = peg$parseIdentifierPart();
4142 peg$silentFails--;
4143 if (s3 === peg$FAILED) {
4144 s2 = void 0;
4145 } else {
4146 peg$currPos = s2;
4147 s2 = peg$FAILED;
4148 }
4149 if (s2 !== peg$FAILED) {
4150 s1 = [s1, s2];
4151 s0 = s1;
4152 } else {
4153 peg$currPos = s0;
4154 s0 = peg$FAILED;
4155 }
4156 } else {
4157 peg$currPos = s0;
4158 s0 = peg$FAILED;
4159 }
4160
4161 return s0;
4162 }
4163
4164 function peg$parseIfToken() {
4165 var s0, s1, s2, s3;
4166
4167 s0 = peg$currPos;
4168 if (input.substr(peg$currPos, 2) === peg$c202) {
4169 s1 = peg$c202;
4170 peg$currPos += 2;
4171 } else {
4172 s1 = peg$FAILED;
4173 if (peg$silentFails === 0) { peg$fail(peg$c203); }
4174 }
4175 if (s1 !== peg$FAILED) {
4176 s2 = peg$currPos;
4177 peg$silentFails++;
4178 s3 = peg$parseIdentifierPart();
4179 peg$silentFails--;
4180 if (s3 === peg$FAILED) {
4181 s2 = void 0;
4182 } else {
4183 peg$currPos = s2;
4184 s2 = peg$FAILED;
4185 }
4186 if (s2 !== peg$FAILED) {
4187 s1 = [s1, s2];
4188 s0 = s1;
4189 } else {
4190 peg$currPos = s0;
4191 s0 = peg$FAILED;
4192 }
4193 } else {
4194 peg$currPos = s0;
4195 s0 = peg$FAILED;
4196 }
4197
4198 return s0;
4199 }
4200
4201 function peg$parseImportToken() {
4202 var s0, s1, s2, s3;
4203
4204 s0 = peg$currPos;
4205 if (input.substr(peg$currPos, 6) === peg$c204) {
4206 s1 = peg$c204;
4207 peg$currPos += 6;
4208 } else {
4209 s1 = peg$FAILED;
4210 if (peg$silentFails === 0) { peg$fail(peg$c205); }
4211 }
4212 if (s1 !== peg$FAILED) {
4213 s2 = peg$currPos;
4214 peg$silentFails++;
4215 s3 = peg$parseIdentifierPart();
4216 peg$silentFails--;
4217 if (s3 === peg$FAILED) {
4218 s2 = void 0;
4219 } else {
4220 peg$currPos = s2;
4221 s2 = peg$FAILED;
4222 }
4223 if (s2 !== peg$FAILED) {
4224 s1 = [s1, s2];
4225 s0 = s1;
4226 } else {
4227 peg$currPos = s0;
4228 s0 = peg$FAILED;
4229 }
4230 } else {
4231 peg$currPos = s0;
4232 s0 = peg$FAILED;
4233 }
4234
4235 return s0;
4236 }
4237
4238 function peg$parseInstanceofToken() {
4239 var s0, s1, s2, s3;
4240
4241 s0 = peg$currPos;
4242 if (input.substr(peg$currPos, 10) === peg$c206) {
4243 s1 = peg$c206;
4244 peg$currPos += 10;
4245 } else {
4246 s1 = peg$FAILED;
4247 if (peg$silentFails === 0) { peg$fail(peg$c207); }
4248 }
4249 if (s1 !== peg$FAILED) {
4250 s2 = peg$currPos;
4251 peg$silentFails++;
4252 s3 = peg$parseIdentifierPart();
4253 peg$silentFails--;
4254 if (s3 === peg$FAILED) {
4255 s2 = void 0;
4256 } else {
4257 peg$currPos = s2;
4258 s2 = peg$FAILED;
4259 }
4260 if (s2 !== peg$FAILED) {
4261 s1 = [s1, s2];
4262 s0 = s1;
4263 } else {
4264 peg$currPos = s0;
4265 s0 = peg$FAILED;
4266 }
4267 } else {
4268 peg$currPos = s0;
4269 s0 = peg$FAILED;
4270 }
4271
4272 return s0;
4273 }
4274
4275 function peg$parseInToken() {
4276 var s0, s1, s2, s3;
4277
4278 s0 = peg$currPos;
4279 if (input.substr(peg$currPos, 2) === peg$c208) {
4280 s1 = peg$c208;
4281 peg$currPos += 2;
4282 } else {
4283 s1 = peg$FAILED;
4284 if (peg$silentFails === 0) { peg$fail(peg$c209); }
4285 }
4286 if (s1 !== peg$FAILED) {
4287 s2 = peg$currPos;
4288 peg$silentFails++;
4289 s3 = peg$parseIdentifierPart();
4290 peg$silentFails--;
4291 if (s3 === peg$FAILED) {
4292 s2 = void 0;
4293 } else {
4294 peg$currPos = s2;
4295 s2 = peg$FAILED;
4296 }
4297 if (s2 !== peg$FAILED) {
4298 s1 = [s1, s2];
4299 s0 = s1;
4300 } else {
4301 peg$currPos = s0;
4302 s0 = peg$FAILED;
4303 }
4304 } else {
4305 peg$currPos = s0;
4306 s0 = peg$FAILED;
4307 }
4308
4309 return s0;
4310 }
4311
4312 function peg$parseNewToken() {
4313 var s0, s1, s2, s3;
4314
4315 s0 = peg$currPos;
4316 if (input.substr(peg$currPos, 3) === peg$c210) {
4317 s1 = peg$c210;
4318 peg$currPos += 3;
4319 } else {
4320 s1 = peg$FAILED;
4321 if (peg$silentFails === 0) { peg$fail(peg$c211); }
4322 }
4323 if (s1 !== peg$FAILED) {
4324 s2 = peg$currPos;
4325 peg$silentFails++;
4326 s3 = peg$parseIdentifierPart();
4327 peg$silentFails--;
4328 if (s3 === peg$FAILED) {
4329 s2 = void 0;
4330 } else {
4331 peg$currPos = s2;
4332 s2 = peg$FAILED;
4333 }
4334 if (s2 !== peg$FAILED) {
4335 s1 = [s1, s2];
4336 s0 = s1;
4337 } else {
4338 peg$currPos = s0;
4339 s0 = peg$FAILED;
4340 }
4341 } else {
4342 peg$currPos = s0;
4343 s0 = peg$FAILED;
4344 }
4345
4346 return s0;
4347 }
4348
4349 function peg$parseNullToken() {
4350 var s0, s1, s2, s3;
4351
4352 s0 = peg$currPos;
4353 if (input.substr(peg$currPos, 4) === peg$c212) {
4354 s1 = peg$c212;
4355 peg$currPos += 4;
4356 } else {
4357 s1 = peg$FAILED;
4358 if (peg$silentFails === 0) { peg$fail(peg$c213); }
4359 }
4360 if (s1 !== peg$FAILED) {
4361 s2 = peg$currPos;
4362 peg$silentFails++;
4363 s3 = peg$parseIdentifierPart();
4364 peg$silentFails--;
4365 if (s3 === peg$FAILED) {
4366 s2 = void 0;
4367 } else {
4368 peg$currPos = s2;
4369 s2 = peg$FAILED;
4370 }
4371 if (s2 !== peg$FAILED) {
4372 s1 = [s1, s2];
4373 s0 = s1;
4374 } else {
4375 peg$currPos = s0;
4376 s0 = peg$FAILED;
4377 }
4378 } else {
4379 peg$currPos = s0;
4380 s0 = peg$FAILED;
4381 }
4382
4383 return s0;
4384 }
4385
4386 function peg$parseReturnToken() {
4387 var s0, s1, s2, s3;
4388
4389 s0 = peg$currPos;
4390 if (input.substr(peg$currPos, 6) === peg$c214) {
4391 s1 = peg$c214;
4392 peg$currPos += 6;
4393 } else {
4394 s1 = peg$FAILED;
4395 if (peg$silentFails === 0) { peg$fail(peg$c215); }
4396 }
4397 if (s1 !== peg$FAILED) {
4398 s2 = peg$currPos;
4399 peg$silentFails++;
4400 s3 = peg$parseIdentifierPart();
4401 peg$silentFails--;
4402 if (s3 === peg$FAILED) {
4403 s2 = void 0;
4404 } else {
4405 peg$currPos = s2;
4406 s2 = peg$FAILED;
4407 }
4408 if (s2 !== peg$FAILED) {
4409 s1 = [s1, s2];
4410 s0 = s1;
4411 } else {
4412 peg$currPos = s0;
4413 s0 = peg$FAILED;
4414 }
4415 } else {
4416 peg$currPos = s0;
4417 s0 = peg$FAILED;
4418 }
4419
4420 return s0;
4421 }
4422
4423 function peg$parseSuperToken() {
4424 var s0, s1, s2, s3;
4425
4426 s0 = peg$currPos;
4427 if (input.substr(peg$currPos, 5) === peg$c216) {
4428 s1 = peg$c216;
4429 peg$currPos += 5;
4430 } else {
4431 s1 = peg$FAILED;
4432 if (peg$silentFails === 0) { peg$fail(peg$c217); }
4433 }
4434 if (s1 !== peg$FAILED) {
4435 s2 = peg$currPos;
4436 peg$silentFails++;
4437 s3 = peg$parseIdentifierPart();
4438 peg$silentFails--;
4439 if (s3 === peg$FAILED) {
4440 s2 = void 0;
4441 } else {
4442 peg$currPos = s2;
4443 s2 = peg$FAILED;
4444 }
4445 if (s2 !== peg$FAILED) {
4446 s1 = [s1, s2];
4447 s0 = s1;
4448 } else {
4449 peg$currPos = s0;
4450 s0 = peg$FAILED;
4451 }
4452 } else {
4453 peg$currPos = s0;
4454 s0 = peg$FAILED;
4455 }
4456
4457 return s0;
4458 }
4459
4460 function peg$parseSwitchToken() {
4461 var s0, s1, s2, s3;
4462
4463 s0 = peg$currPos;
4464 if (input.substr(peg$currPos, 6) === peg$c218) {
4465 s1 = peg$c218;
4466 peg$currPos += 6;
4467 } else {
4468 s1 = peg$FAILED;
4469 if (peg$silentFails === 0) { peg$fail(peg$c219); }
4470 }
4471 if (s1 !== peg$FAILED) {
4472 s2 = peg$currPos;
4473 peg$silentFails++;
4474 s3 = peg$parseIdentifierPart();
4475 peg$silentFails--;
4476 if (s3 === peg$FAILED) {
4477 s2 = void 0;
4478 } else {
4479 peg$currPos = s2;
4480 s2 = peg$FAILED;
4481 }
4482 if (s2 !== peg$FAILED) {
4483 s1 = [s1, s2];
4484 s0 = s1;
4485 } else {
4486 peg$currPos = s0;
4487 s0 = peg$FAILED;
4488 }
4489 } else {
4490 peg$currPos = s0;
4491 s0 = peg$FAILED;
4492 }
4493
4494 return s0;
4495 }
4496
4497 function peg$parseThisToken() {
4498 var s0, s1, s2, s3;
4499
4500 s0 = peg$currPos;
4501 if (input.substr(peg$currPos, 4) === peg$c220) {
4502 s1 = peg$c220;
4503 peg$currPos += 4;
4504 } else {
4505 s1 = peg$FAILED;
4506 if (peg$silentFails === 0) { peg$fail(peg$c221); }
4507 }
4508 if (s1 !== peg$FAILED) {
4509 s2 = peg$currPos;
4510 peg$silentFails++;
4511 s3 = peg$parseIdentifierPart();
4512 peg$silentFails--;
4513 if (s3 === peg$FAILED) {
4514 s2 = void 0;
4515 } else {
4516 peg$currPos = s2;
4517 s2 = peg$FAILED;
4518 }
4519 if (s2 !== peg$FAILED) {
4520 s1 = [s1, s2];
4521 s0 = s1;
4522 } else {
4523 peg$currPos = s0;
4524 s0 = peg$FAILED;
4525 }
4526 } else {
4527 peg$currPos = s0;
4528 s0 = peg$FAILED;
4529 }
4530
4531 return s0;
4532 }
4533
4534 function peg$parseThrowToken() {
4535 var s0, s1, s2, s3;
4536
4537 s0 = peg$currPos;
4538 if (input.substr(peg$currPos, 5) === peg$c222) {
4539 s1 = peg$c222;
4540 peg$currPos += 5;
4541 } else {
4542 s1 = peg$FAILED;
4543 if (peg$silentFails === 0) { peg$fail(peg$c223); }
4544 }
4545 if (s1 !== peg$FAILED) {
4546 s2 = peg$currPos;
4547 peg$silentFails++;
4548 s3 = peg$parseIdentifierPart();
4549 peg$silentFails--;
4550 if (s3 === peg$FAILED) {
4551 s2 = void 0;
4552 } else {
4553 peg$currPos = s2;
4554 s2 = peg$FAILED;
4555 }
4556 if (s2 !== peg$FAILED) {
4557 s1 = [s1, s2];
4558 s0 = s1;
4559 } else {
4560 peg$currPos = s0;
4561 s0 = peg$FAILED;
4562 }
4563 } else {
4564 peg$currPos = s0;
4565 s0 = peg$FAILED;
4566 }
4567
4568 return s0;
4569 }
4570
4571 function peg$parseTrueToken() {
4572 var s0, s1, s2, s3;
4573
4574 s0 = peg$currPos;
4575 if (input.substr(peg$currPos, 4) === peg$c224) {
4576 s1 = peg$c224;
4577 peg$currPos += 4;
4578 } else {
4579 s1 = peg$FAILED;
4580 if (peg$silentFails === 0) { peg$fail(peg$c225); }
4581 }
4582 if (s1 !== peg$FAILED) {
4583 s2 = peg$currPos;
4584 peg$silentFails++;
4585 s3 = peg$parseIdentifierPart();
4586 peg$silentFails--;
4587 if (s3 === peg$FAILED) {
4588 s2 = void 0;
4589 } else {
4590 peg$currPos = s2;
4591 s2 = peg$FAILED;
4592 }
4593 if (s2 !== peg$FAILED) {
4594 s1 = [s1, s2];
4595 s0 = s1;
4596 } else {
4597 peg$currPos = s0;
4598 s0 = peg$FAILED;
4599 }
4600 } else {
4601 peg$currPos = s0;
4602 s0 = peg$FAILED;
4603 }
4604
4605 return s0;
4606 }
4607
4608 function peg$parseTryToken() {
4609 var s0, s1, s2, s3;
4610
4611 s0 = peg$currPos;
4612 if (input.substr(peg$currPos, 3) === peg$c226) {
4613 s1 = peg$c226;
4614 peg$currPos += 3;
4615 } else {
4616 s1 = peg$FAILED;
4617 if (peg$silentFails === 0) { peg$fail(peg$c227); }
4618 }
4619 if (s1 !== peg$FAILED) {
4620 s2 = peg$currPos;
4621 peg$silentFails++;
4622 s3 = peg$parseIdentifierPart();
4623 peg$silentFails--;
4624 if (s3 === peg$FAILED) {
4625 s2 = void 0;
4626 } else {
4627 peg$currPos = s2;
4628 s2 = peg$FAILED;
4629 }
4630 if (s2 !== peg$FAILED) {
4631 s1 = [s1, s2];
4632 s0 = s1;
4633 } else {
4634 peg$currPos = s0;
4635 s0 = peg$FAILED;
4636 }
4637 } else {
4638 peg$currPos = s0;
4639 s0 = peg$FAILED;
4640 }
4641
4642 return s0;
4643 }
4644
4645 function peg$parseTypeofToken() {
4646 var s0, s1, s2, s3;
4647
4648 s0 = peg$currPos;
4649 if (input.substr(peg$currPos, 6) === peg$c228) {
4650 s1 = peg$c228;
4651 peg$currPos += 6;
4652 } else {
4653 s1 = peg$FAILED;
4654 if (peg$silentFails === 0) { peg$fail(peg$c229); }
4655 }
4656 if (s1 !== peg$FAILED) {
4657 s2 = peg$currPos;
4658 peg$silentFails++;
4659 s3 = peg$parseIdentifierPart();
4660 peg$silentFails--;
4661 if (s3 === peg$FAILED) {
4662 s2 = void 0;
4663 } else {
4664 peg$currPos = s2;
4665 s2 = peg$FAILED;
4666 }
4667 if (s2 !== peg$FAILED) {
4668 s1 = [s1, s2];
4669 s0 = s1;
4670 } else {
4671 peg$currPos = s0;
4672 s0 = peg$FAILED;
4673 }
4674 } else {
4675 peg$currPos = s0;
4676 s0 = peg$FAILED;
4677 }
4678
4679 return s0;
4680 }
4681
4682 function peg$parseVarToken() {
4683 var s0, s1, s2, s3;
4684
4685 s0 = peg$currPos;
4686 if (input.substr(peg$currPos, 3) === peg$c230) {
4687 s1 = peg$c230;
4688 peg$currPos += 3;
4689 } else {
4690 s1 = peg$FAILED;
4691 if (peg$silentFails === 0) { peg$fail(peg$c231); }
4692 }
4693 if (s1 !== peg$FAILED) {
4694 s2 = peg$currPos;
4695 peg$silentFails++;
4696 s3 = peg$parseIdentifierPart();
4697 peg$silentFails--;
4698 if (s3 === peg$FAILED) {
4699 s2 = void 0;
4700 } else {
4701 peg$currPos = s2;
4702 s2 = peg$FAILED;
4703 }
4704 if (s2 !== peg$FAILED) {
4705 s1 = [s1, s2];
4706 s0 = s1;
4707 } else {
4708 peg$currPos = s0;
4709 s0 = peg$FAILED;
4710 }
4711 } else {
4712 peg$currPos = s0;
4713 s0 = peg$FAILED;
4714 }
4715
4716 return s0;
4717 }
4718
4719 function peg$parseVoidToken() {
4720 var s0, s1, s2, s3;
4721
4722 s0 = peg$currPos;
4723 if (input.substr(peg$currPos, 4) === peg$c232) {
4724 s1 = peg$c232;
4725 peg$currPos += 4;
4726 } else {
4727 s1 = peg$FAILED;
4728 if (peg$silentFails === 0) { peg$fail(peg$c233); }
4729 }
4730 if (s1 !== peg$FAILED) {
4731 s2 = peg$currPos;
4732 peg$silentFails++;
4733 s3 = peg$parseIdentifierPart();
4734 peg$silentFails--;
4735 if (s3 === peg$FAILED) {
4736 s2 = void 0;
4737 } else {
4738 peg$currPos = s2;
4739 s2 = peg$FAILED;
4740 }
4741 if (s2 !== peg$FAILED) {
4742 s1 = [s1, s2];
4743 s0 = s1;
4744 } else {
4745 peg$currPos = s0;
4746 s0 = peg$FAILED;
4747 }
4748 } else {
4749 peg$currPos = s0;
4750 s0 = peg$FAILED;
4751 }
4752
4753 return s0;
4754 }
4755
4756 function peg$parseWhileToken() {
4757 var s0, s1, s2, s3;
4758
4759 s0 = peg$currPos;
4760 if (input.substr(peg$currPos, 5) === peg$c234) {
4761 s1 = peg$c234;
4762 peg$currPos += 5;
4763 } else {
4764 s1 = peg$FAILED;
4765 if (peg$silentFails === 0) { peg$fail(peg$c235); }
4766 }
4767 if (s1 !== peg$FAILED) {
4768 s2 = peg$currPos;
4769 peg$silentFails++;
4770 s3 = peg$parseIdentifierPart();
4771 peg$silentFails--;
4772 if (s3 === peg$FAILED) {
4773 s2 = void 0;
4774 } else {
4775 peg$currPos = s2;
4776 s2 = peg$FAILED;
4777 }
4778 if (s2 !== peg$FAILED) {
4779 s1 = [s1, s2];
4780 s0 = s1;
4781 } else {
4782 peg$currPos = s0;
4783 s0 = peg$FAILED;
4784 }
4785 } else {
4786 peg$currPos = s0;
4787 s0 = peg$FAILED;
4788 }
4789
4790 return s0;
4791 }
4792
4793 function peg$parseWithToken() {
4794 var s0, s1, s2, s3;
4795
4796 s0 = peg$currPos;
4797 if (input.substr(peg$currPos, 4) === peg$c236) {
4798 s1 = peg$c236;
4799 peg$currPos += 4;
4800 } else {
4801 s1 = peg$FAILED;
4802 if (peg$silentFails === 0) { peg$fail(peg$c237); }
4803 }
4804 if (s1 !== peg$FAILED) {
4805 s2 = peg$currPos;
4806 peg$silentFails++;
4807 s3 = peg$parseIdentifierPart();
4808 peg$silentFails--;
4809 if (s3 === peg$FAILED) {
4810 s2 = void 0;
4811 } else {
4812 peg$currPos = s2;
4813 s2 = peg$FAILED;
4814 }
4815 if (s2 !== peg$FAILED) {
4816 s1 = [s1, s2];
4817 s0 = s1;
4818 } else {
4819 peg$currPos = s0;
4820 s0 = peg$FAILED;
4821 }
4822 } else {
4823 peg$currPos = s0;
4824 s0 = peg$FAILED;
4825 }
4826
4827 return s0;
4828 }
4829
4830 function peg$parse__() {
4831 var s0, s1;
4832
4833 s0 = [];
4834 s1 = peg$parseWhiteSpace();
4835 if (s1 === peg$FAILED) {
4836 s1 = peg$parseLineTerminatorSequence();
4837 if (s1 === peg$FAILED) {
4838 s1 = peg$parseComment();
4839 }
4840 }
4841 while (s1 !== peg$FAILED) {
4842 s0.push(s1);
4843 s1 = peg$parseWhiteSpace();
4844 if (s1 === peg$FAILED) {
4845 s1 = peg$parseLineTerminatorSequence();
4846 if (s1 === peg$FAILED) {
4847 s1 = peg$parseComment();
4848 }
4849 }
4850 }
4851
4852 return s0;
4853 }
4854
4855 function peg$parse_() {
4856 var s0, s1;
4857
4858 s0 = [];
4859 s1 = peg$parseWhiteSpace();
4860 if (s1 === peg$FAILED) {
4861 s1 = peg$parseMultiLineCommentNoLineTerminator();
4862 }
4863 while (s1 !== peg$FAILED) {
4864 s0.push(s1);
4865 s1 = peg$parseWhiteSpace();
4866 if (s1 === peg$FAILED) {
4867 s1 = peg$parseMultiLineCommentNoLineTerminator();
4868 }
4869 }
4870
4871 return s0;
4872 }
4873
4874 function peg$parseEOS() {
4875 var s0, s1, s2, s3;
4876
4877 s0 = peg$currPos;
4878 s1 = peg$parse__();
4879 if (s1 !== peg$FAILED) {
4880 if (input.charCodeAt(peg$currPos) === 59) {
4881 s2 = peg$c238;
4882 peg$currPos++;
4883 } else {
4884 s2 = peg$FAILED;
4885 if (peg$silentFails === 0) { peg$fail(peg$c239); }
4886 }
4887 if (s2 !== peg$FAILED) {
4888 s1 = [s1, s2];
4889 s0 = s1;
4890 } else {
4891 peg$currPos = s0;
4892 s0 = peg$FAILED;
4893 }
4894 } else {
4895 peg$currPos = s0;
4896 s0 = peg$FAILED;
4897 }
4898 if (s0 === peg$FAILED) {
4899 s0 = peg$currPos;
4900 s1 = peg$parse_();
4901 if (s1 !== peg$FAILED) {
4902 s2 = peg$parseSingleLineComment();
4903 if (s2 === peg$FAILED) {
4904 s2 = null;
4905 }
4906 if (s2 !== peg$FAILED) {
4907 s3 = peg$parseLineTerminatorSequence();
4908 if (s3 !== peg$FAILED) {
4909 s1 = [s1, s2, s3];
4910 s0 = s1;
4911 } else {
4912 peg$currPos = s0;
4913 s0 = peg$FAILED;
4914 }
4915 } else {
4916 peg$currPos = s0;
4917 s0 = peg$FAILED;
4918 }
4919 } else {
4920 peg$currPos = s0;
4921 s0 = peg$FAILED;
4922 }
4923 if (s0 === peg$FAILED) {
4924 s0 = peg$currPos;
4925 s1 = peg$parse__();
4926 if (s1 !== peg$FAILED) {
4927 s2 = peg$parseEOF();
4928 if (s2 !== peg$FAILED) {
4929 s1 = [s1, s2];
4930 s0 = s1;
4931 } else {
4932 peg$currPos = s0;
4933 s0 = peg$FAILED;
4934 }
4935 } else {
4936 peg$currPos = s0;
4937 s0 = peg$FAILED;
4938 }
4939 }
4940 }
4941
4942 return s0;
4943 }
4944
4945 function peg$parseEOF() {
4946 var s0, s1;
4947
4948 s0 = peg$currPos;
4949 peg$silentFails++;
4950 if (input.length > peg$currPos) {
4951 s1 = input.charAt(peg$currPos);
4952 peg$currPos++;
4953 } else {
4954 s1 = peg$FAILED;
4955 if (peg$silentFails === 0) { peg$fail(peg$c34); }
4956 }
4957 peg$silentFails--;
4958 if (s1 === peg$FAILED) {
4959 s0 = void 0;
4960 } else {
4961 peg$currPos = s0;
4962 s0 = peg$FAILED;
4963 }
4964
4965 return s0;
4966 }
4967
4968
4969 var OPS_TO_PREFIXED_TYPES = {
4970 "$": "text",
4971 "&": "simple_and",
4972 "!": "simple_not"
4973 };
4974
4975 var OPS_TO_SUFFIXED_TYPES = {
4976 "?": "optional",
4977 "*": "zero_or_more",
4978 "+": "one_or_more"
4979 };
4980
4981 var OPS_TO_SEMANTIC_PREDICATE_TYPES = {
4982 "&": "semantic_and",
4983 "!": "semantic_not"
4984 };
4985
4986 function filterEmptyStrings(array) {
4987 var result = [], i;
4988
4989 for (i = 0; i < array.length; i++) {
4990 if (array[i] !== "") {
4991 result.push(array[i]);
4992 }
4993 }
4994
4995 return result;
4996 }
4997
4998 function extractOptional(optional, index) {
4999 return optional ? optional[index] : null;
5000 }
5001
5002 function extractList(list, index) {
5003 var result = new Array(list.length), i;
5004
5005 for (i = 0; i < list.length; i++) {
5006 result[i] = list[i][index];
5007 }
5008
5009 return result;
5010 }
5011
5012 function buildList(head, tail, index) {
5013 return [head].concat(extractList(tail, index));
5014 }
5015
5016
5017 peg$result = peg$startRuleFunction();
5018
5019 if (peg$result !== peg$FAILED && peg$currPos === input.length) {
5020 return peg$result;
5021 } else {
5022 if (peg$result !== peg$FAILED && peg$currPos < input.length) {
5023 peg$fail(peg$endExpectation());
5024 }
5025
5026 throw peg$buildStructuredError(
5027 peg$maxFailExpected,
5028 peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null,
5029 peg$maxFailPos < input.length
5030 ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1)
5031 : peg$computeLocation(peg$maxFailPos, peg$maxFailPos)
5032 );
5033 }
5034 }
5035
5036 module.exports = {
5037 SyntaxError: peg$SyntaxError,
5038 parse: peg$parse
5039 };
0 /*
1 * PEG.js 0.7.0
2 *
3 * http://pegjs.majda.cz/
4 *
5 * Copyright (c) 2010-2012 David Majda
6 * Licensend under the MIT license.
7 */
8 var PEG = (function(undefined) {
0 "use strict";
91
10 var PEG = {
2 var arrays = require("./utils/arrays"),
3 objects = require("./utils/objects");
4
5 var peg = {
116 /* PEG.js version (uses semantic versioning). */
12 VERSION: "0.7.0",
7 VERSION: "0.10.0",
8
9 GrammarError: require("./grammar-error"),
10 parser: require("./parser"),
11 compiler: require("./compiler"),
1312
1413 /*
1514 * Generates a parser from a specified grammar and returns it.
1716 * The grammar must be a string in the format described by the metagramar in
1817 * the parser.pegjs file.
1918 *
20 * Throws |PEG.parser.SyntaxError| if the grammar contains a syntax error or
21 * |PEG.GrammarError| if it contains a semantic error. Note that not all
19 * Throws |peg.parser.SyntaxError| if the grammar contains a syntax error or
20 * |peg.GrammarError| if it contains a semantic error. Note that not all
2221 * errors are detected during the generation and some may protrude to the
2322 * generated parser and cause its malfunction.
2423 */
25 buildParser: function(grammar, options) {
26 return PEG.compiler.compile(PEG.parser.parse(grammar), options);
24 generate: function(grammar, options) {
25 options = options !== void 0 ? options : {};
26
27 function convertPasses(passes) {
28 var converted = {}, stage;
29
30 for (stage in passes) {
31 if (passes.hasOwnProperty(stage)) {
32 converted[stage] = objects.values(passes[stage]);
33 }
34 }
35
36 return converted;
37 }
38
39 options = objects.clone(options);
40
41 var plugins = "plugins" in options ? options.plugins : [],
42 config = {
43 parser: peg.parser,
44 passes: convertPasses(peg.compiler.passes)
45 };
46
47 arrays.each(plugins, function(p) { p.use(config, options); });
48
49 return peg.compiler.compile(
50 config.parser.parse(grammar),
51 config.passes,
52 options
53 );
2754 }
2855 };
2956
30 /* Thrown when the grammar contains an error. */
31
32 PEG.GrammarError = function(message) {
33 this.name = "PEG.GrammarError";
34 this.message = message;
35 };
36
37 PEG.GrammarError.prototype = Error.prototype;
38
39 /* Like Python's |range|, but without |step|. */
40 function range(start, stop) {
41 if (stop === undefined) {
42 stop = start;
43 start = 0;
44 }
45
46 var result = new Array(Math.max(0, stop - start));
47 for (var i = 0, j = start; j < stop; i++, j++) {
48 result[i] = j;
49 }
50 return result;
51 }
52
53 function find(array, callback) {
54 var length = array.length;
55 for (var i = 0; i < length; i++) {
56 if (callback(array[i])) {
57 return array[i];
58 }
59 }
60 }
61
62 function contains(array, value) {
63 /*
64 * Stupid IE does not have Array.prototype.indexOf, otherwise this function
65 * would be a one-liner.
66 */
67 var length = array.length;
68 for (var i = 0; i < length; i++) {
69 if (array[i] === value) {
70 return true;
71 }
72 }
73 return false;
74 }
75
76 function each(array, callback) {
77 var length = array.length;
78 for (var i = 0; i < length; i++) {
79 callback(array[i], i);
80 }
81 }
82
83 function map(array, callback) {
84 var result = [];
85 var length = array.length;
86 for (var i = 0; i < length; i++) {
87 result[i] = callback(array[i], i);
88 }
89 return result;
90 }
91
92 function pluck(array, key) {
93 return map(array, function (e) { return e[key]; });
94 }
95
96 function keys(object) {
97 var result = [];
98 for (var key in object) {
99 result.push(key);
100 }
101 return result;
102 }
103
104 function values(object) {
105 var result = [];
106 for (var key in object) {
107 result.push(object[key]);
108 }
109 return result;
110 }
111
112 /*
113 * Returns a string padded on the left to a desired length with a character.
114 *
115 * The code needs to be in sync with the code template in the compilation
116 * function for "action" nodes.
117 */
118 function padLeft(input, padding, length) {
119 var result = input;
120
121 var padLength = length - input.length;
122 for (var i = 0; i < padLength; i++) {
123 result = padding + result;
124 }
125
126 return result;
127 }
128
129 /*
130 * Returns an escape sequence for given character. Uses \x for characters <=
131 * 0xFF to save space, \u for the rest.
132 *
133 * The code needs to be in sync with the code template in the compilation
134 * function for "action" nodes.
135 */
136 function escape(ch) {
137 var charCode = ch.charCodeAt(0);
138 var escapeChar;
139 var length;
140
141 if (charCode <= 0xFF) {
142 escapeChar = 'x';
143 length = 2;
144 } else {
145 escapeChar = 'u';
146 length = 4;
147 }
148
149 return '\\' + escapeChar + padLeft(charCode.toString(16).toUpperCase(), '0', length);
150 }
151
152 /*
153 * Surrounds the string with quotes and escapes characters inside so that the
154 * result is a valid JavaScript string.
155 *
156 * The code needs to be in sync with the code template in the compilation
157 * function for "action" nodes.
158 */
159 function quote(s) {
160 /*
161 * ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a string
162 * literal except for the closing quote character, backslash, carriage return,
163 * line separator, paragraph separator, and line feed. Any character may
164 * appear in the form of an escape sequence.
165 *
166 * For portability, we also escape escape all control and non-ASCII
167 * characters. Note that "\0" and "\v" escape sequences are not used because
168 * JSHint does not like the first and IE the second.
169 */
170 return '"' + s
171 .replace(/\\/g, '\\\\') // backslash
172 .replace(/"/g, '\\"') // closing quote character
173 .replace(/\x08/g, '\\b') // backspace
174 .replace(/\t/g, '\\t') // horizontal tab
175 .replace(/\n/g, '\\n') // line feed
176 .replace(/\f/g, '\\f') // form feed
177 .replace(/\r/g, '\\r') // carriage return
178 .replace(/[\x00-\x07\x0B\x0E-\x1F\x80-\uFFFF]/g, escape)
179 + '"';
180 }
181
182 /*
183 * Escapes characters inside the string so that it can be used as a list of
184 * characters in a character class of a regular expression.
185 */
186 function quoteForRegexpClass(s) {
187 /*
188 * Based on ECMA-262, 5th ed., 7.8.5 & 15.10.1.
189 *
190 * For portability, we also escape escape all control and non-ASCII
191 * characters.
192 */
193 return s
194 .replace(/\\/g, '\\\\') // backslash
195 .replace(/\//g, '\\/') // closing slash
196 .replace(/\]/g, '\\]') // closing bracket
197 .replace(/-/g, '\\-') // dash
198 .replace(/\0/g, '\\0') // null
199 .replace(/\t/g, '\\t') // horizontal tab
200 .replace(/\n/g, '\\n') // line feed
201 .replace(/\v/g, '\\x0B') // vertical tab
202 .replace(/\f/g, '\\f') // form feed
203 .replace(/\r/g, '\\r') // carriage return
204 .replace(/[\x01-\x08\x0E-\x1F\x80-\uFFFF]/g, escape);
205 }
206
207 /*
208 * Builds a node visitor -- a function which takes a node and any number of
209 * other parameters, calls an appropriate function according to the node type,
210 * passes it all its parameters and returns its value. The functions for various
211 * node types are passed in a parameter to |buildNodeVisitor| as a hash.
212 */
213 function buildNodeVisitor(functions) {
214 return function(node) {
215 return functions[node.type].apply(null, arguments);
216 };
217 }
218
219 function findRuleByName(ast, name) {
220 return find(ast.rules, function(r) { return r.name === name; });
221 }
222 PEG.parser = (function(){
223 /*
224 * Generated by PEG.js 0.7.0.
225 *
226 * http://pegjs.majda.cz/
227 */
228
229 function quote(s) {
230 /*
231 * ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a
232 * string literal except for the closing quote character, backslash,
233 * carriage return, line separator, paragraph separator, and line feed.
234 * Any character may appear in the form of an escape sequence.
235 *
236 * For portability, we also escape escape all control and non-ASCII
237 * characters. Note that "\0" and "\v" escape sequences are not used
238 * because JSHint does not like the first and IE the second.
239 */
240 return '"' + s
241 .replace(/\\/g, '\\\\') // backslash
242 .replace(/"/g, '\\"') // closing quote character
243 .replace(/\x08/g, '\\b') // backspace
244 .replace(/\t/g, '\\t') // horizontal tab
245 .replace(/\n/g, '\\n') // line feed
246 .replace(/\f/g, '\\f') // form feed
247 .replace(/\r/g, '\\r') // carriage return
248 .replace(/[\x00-\x07\x0B\x0E-\x1F\x80-\uFFFF]/g, escape)
249 + '"';
250 }
251
252 var result = {
253 /*
254 * Parses the input with a generated parser. If the parsing is successfull,
255 * returns a value explicitly or implicitly specified by the grammar from
256 * which the parser was generated (see |PEG.buildParser|). If the parsing is
257 * unsuccessful, throws |PEG.parser.SyntaxError| describing the error.
258 */
259 parse: function(input, startRule) {
260 var parseFunctions = {
261 "grammar": parse_grammar,
262 "initializer": parse_initializer,
263 "rule": parse_rule,
264 "choice": parse_choice,
265 "sequence": parse_sequence,
266 "labeled": parse_labeled,
267 "prefixed": parse_prefixed,
268 "suffixed": parse_suffixed,
269 "primary": parse_primary,
270 "action": parse_action,
271 "braced": parse_braced,
272 "nonBraceCharacters": parse_nonBraceCharacters,
273 "nonBraceCharacter": parse_nonBraceCharacter,
274 "equals": parse_equals,
275 "colon": parse_colon,
276 "semicolon": parse_semicolon,
277 "slash": parse_slash,
278 "and": parse_and,
279 "not": parse_not,
280 "question": parse_question,
281 "star": parse_star,
282 "plus": parse_plus,
283 "lparen": parse_lparen,
284 "rparen": parse_rparen,
285 "dot": parse_dot,
286 "identifier": parse_identifier,
287 "literal": parse_literal,
288 "string": parse_string,
289 "doubleQuotedString": parse_doubleQuotedString,
290 "doubleQuotedCharacter": parse_doubleQuotedCharacter,
291 "simpleDoubleQuotedCharacter": parse_simpleDoubleQuotedCharacter,
292 "singleQuotedString": parse_singleQuotedString,
293 "singleQuotedCharacter": parse_singleQuotedCharacter,
294 "simpleSingleQuotedCharacter": parse_simpleSingleQuotedCharacter,
295 "class": parse_class,
296 "classCharacterRange": parse_classCharacterRange,
297 "classCharacter": parse_classCharacter,
298 "bracketDelimitedCharacter": parse_bracketDelimitedCharacter,
299 "simpleBracketDelimitedCharacter": parse_simpleBracketDelimitedCharacter,
300 "simpleEscapeSequence": parse_simpleEscapeSequence,
301 "zeroEscapeSequence": parse_zeroEscapeSequence,
302 "hexEscapeSequence": parse_hexEscapeSequence,
303 "unicodeEscapeSequence": parse_unicodeEscapeSequence,
304 "eolEscapeSequence": parse_eolEscapeSequence,
305 "digit": parse_digit,
306 "hexDigit": parse_hexDigit,
307 "letter": parse_letter,
308 "lowerCaseLetter": parse_lowerCaseLetter,
309 "upperCaseLetter": parse_upperCaseLetter,
310 "__": parse___,
311 "comment": parse_comment,
312 "singleLineComment": parse_singleLineComment,
313 "multiLineComment": parse_multiLineComment,
314 "eol": parse_eol,
315 "eolChar": parse_eolChar,
316 "whitespace": parse_whitespace
317 };
318
319 if (startRule !== undefined) {
320 if (parseFunctions[startRule] === undefined) {
321 throw new Error("Invalid rule name: " + quote(startRule) + ".");
322 }
323 } else {
324 startRule = "grammar";
325 }
326
327 var pos = 0;
328 var reportFailures = 0;
329 var rightmostFailuresPos = 0;
330 var rightmostFailuresExpected = [];
331
332 function padLeft(input, padding, length) {
333 var result = input;
334
335 var padLength = length - input.length;
336 for (var i = 0; i < padLength; i++) {
337 result = padding + result;
338 }
339
340 return result;
341 }
342
343 function escape(ch) {
344 var charCode = ch.charCodeAt(0);
345 var escapeChar;
346 var length;
347
348 if (charCode <= 0xFF) {
349 escapeChar = 'x';
350 length = 2;
351 } else {
352 escapeChar = 'u';
353 length = 4;
354 }
355
356 return '\\' + escapeChar + padLeft(charCode.toString(16).toUpperCase(), '0', length);
357 }
358
359 function matchFailed(failure) {
360 if (pos < rightmostFailuresPos) {
361 return;
362 }
363
364 if (pos > rightmostFailuresPos) {
365 rightmostFailuresPos = pos;
366 rightmostFailuresExpected = [];
367 }
368
369 rightmostFailuresExpected.push(failure);
370 }
371
372 function parse_grammar() {
373 var result0, result1, result2, result3;
374 var pos0, pos1;
375
376 pos0 = pos;
377 pos1 = pos;
378 result0 = parse___();
379 if (result0 !== null) {
380 result1 = parse_initializer();
381 result1 = result1 !== null ? result1 : "";
382 if (result1 !== null) {
383 result3 = parse_rule();
384 if (result3 !== null) {
385 result2 = [];
386 while (result3 !== null) {
387 result2.push(result3);
388 result3 = parse_rule();
389 }
390 } else {
391 result2 = null;
392 }
393 if (result2 !== null) {
394 result0 = [result0, result1, result2];
395 } else {
396 result0 = null;
397 pos = pos1;
398 }
399 } else {
400 result0 = null;
401 pos = pos1;
402 }
403 } else {
404 result0 = null;
405 pos = pos1;
406 }
407 if (result0 !== null) {
408 result0 = (function(offset, initializer, rules) {
409 return {
410 type: "grammar",
411 initializer: initializer !== "" ? initializer : null,
412 rules: rules,
413 startRule: rules[0].name
414 };
415 })(pos0, result0[1], result0[2]);
416 }
417 if (result0 === null) {
418 pos = pos0;
419 }
420 return result0;
421 }
422
423 function parse_initializer() {
424 var result0, result1;
425 var pos0, pos1;
426
427 pos0 = pos;
428 pos1 = pos;
429 result0 = parse_action();
430 if (result0 !== null) {
431 result1 = parse_semicolon();
432 result1 = result1 !== null ? result1 : "";
433 if (result1 !== null) {
434 result0 = [result0, result1];
435 } else {
436 result0 = null;
437 pos = pos1;
438 }
439 } else {
440 result0 = null;
441 pos = pos1;
442 }
443 if (result0 !== null) {
444 result0 = (function(offset, code) {
445 return {
446 type: "initializer",
447 code: code
448 };
449 })(pos0, result0[0]);
450 }
451 if (result0 === null) {
452 pos = pos0;
453 }
454 return result0;
455 }
456
457 function parse_rule() {
458 var result0, result1, result2, result3, result4;
459 var pos0, pos1;
460
461 pos0 = pos;
462 pos1 = pos;
463 result0 = parse_identifier();
464 if (result0 !== null) {
465 result1 = parse_string();
466 result1 = result1 !== null ? result1 : "";
467 if (result1 !== null) {
468 result2 = parse_equals();
469 if (result2 !== null) {
470 result3 = parse_choice();
471 if (result3 !== null) {
472 result4 = parse_semicolon();
473 result4 = result4 !== null ? result4 : "";
474 if (result4 !== null) {
475 result0 = [result0, result1, result2, result3, result4];
476 } else {
477 result0 = null;
478 pos = pos1;
479 }
480 } else {
481 result0 = null;
482 pos = pos1;
483 }
484 } else {
485 result0 = null;
486 pos = pos1;
487 }
488 } else {
489 result0 = null;
490 pos = pos1;
491 }
492 } else {
493 result0 = null;
494 pos = pos1;
495 }
496 if (result0 !== null) {
497 result0 = (function(offset, name, displayName, expression) {
498 return {
499 type: "rule",
500 name: name,
501 displayName: displayName !== "" ? displayName : null,
502 expression: expression
503 };
504 })(pos0, result0[0], result0[1], result0[3]);
505 }
506 if (result0 === null) {
507 pos = pos0;
508 }
509 return result0;
510 }
511
512 function parse_choice() {
513 var result0, result1, result2, result3;
514 var pos0, pos1, pos2;
515
516 pos0 = pos;
517 pos1 = pos;
518 result0 = parse_sequence();
519 if (result0 !== null) {
520 result1 = [];
521 pos2 = pos;
522 result2 = parse_slash();
523 if (result2 !== null) {
524 result3 = parse_sequence();
525 if (result3 !== null) {
526 result2 = [result2, result3];
527 } else {
528 result2 = null;
529 pos = pos2;
530 }
531 } else {
532 result2 = null;
533 pos = pos2;
534 }
535 while (result2 !== null) {
536 result1.push(result2);
537 pos2 = pos;
538 result2 = parse_slash();
539 if (result2 !== null) {
540 result3 = parse_sequence();
541 if (result3 !== null) {
542 result2 = [result2, result3];
543 } else {
544 result2 = null;
545 pos = pos2;
546 }
547 } else {
548 result2 = null;
549 pos = pos2;
550 }
551 }
552 if (result1 !== null) {
553 result0 = [result0, result1];
554 } else {
555 result0 = null;
556 pos = pos1;
557 }
558 } else {
559 result0 = null;
560 pos = pos1;
561 }
562 if (result0 !== null) {
563 result0 = (function(offset, head, tail) {
564 if (tail.length > 0) {
565 var alternatives = [head].concat(map(
566 tail,
567 function(element) { return element[1]; }
568 ));
569 return {
570 type: "choice",
571 alternatives: alternatives
572 };
573 } else {
574 return head;
575 }
576 })(pos0, result0[0], result0[1]);
577 }
578 if (result0 === null) {
579 pos = pos0;
580 }
581 return result0;
582 }
583
584 function parse_sequence() {
585 var result0, result1;
586 var pos0, pos1;
587
588 pos0 = pos;
589 pos1 = pos;
590 result0 = [];
591 result1 = parse_labeled();
592 while (result1 !== null) {
593 result0.push(result1);
594 result1 = parse_labeled();
595 }
596 if (result0 !== null) {
597 result1 = parse_action();
598 if (result1 !== null) {
599 result0 = [result0, result1];
600 } else {
601 result0 = null;
602 pos = pos1;
603 }
604 } else {
605 result0 = null;
606 pos = pos1;
607 }
608 if (result0 !== null) {
609 result0 = (function(offset, elements, code) {
610 var expression = elements.length !== 1
611 ? {
612 type: "sequence",
613 elements: elements
614 }
615 : elements[0];
616 return {
617 type: "action",
618 expression: expression,
619 code: code
620 };
621 })(pos0, result0[0], result0[1]);
622 }
623 if (result0 === null) {
624 pos = pos0;
625 }
626 if (result0 === null) {
627 pos0 = pos;
628 result0 = [];
629 result1 = parse_labeled();
630 while (result1 !== null) {
631 result0.push(result1);
632 result1 = parse_labeled();
633 }
634 if (result0 !== null) {
635 result0 = (function(offset, elements) {
636 return elements.length !== 1
637 ? {
638 type: "sequence",
639 elements: elements
640 }
641 : elements[0];
642 })(pos0, result0);
643 }
644 if (result0 === null) {
645 pos = pos0;
646 }
647 }
648 return result0;
649 }
650
651 function parse_labeled() {
652 var result0, result1, result2;
653 var pos0, pos1;
654
655 pos0 = pos;
656 pos1 = pos;
657 result0 = parse_identifier();
658 if (result0 !== null) {
659 result1 = parse_colon();
660 if (result1 !== null) {
661 result2 = parse_prefixed();
662 if (result2 !== null) {
663 result0 = [result0, result1, result2];
664 } else {
665 result0 = null;
666 pos = pos1;
667 }
668 } else {
669 result0 = null;
670 pos = pos1;
671 }
672 } else {
673 result0 = null;
674 pos = pos1;
675 }
676 if (result0 !== null) {
677 result0 = (function(offset, label, expression) {
678 return {
679 type: "labeled",
680 label: label,
681 expression: expression
682 };
683 })(pos0, result0[0], result0[2]);
684 }
685 if (result0 === null) {
686 pos = pos0;
687 }
688 if (result0 === null) {
689 result0 = parse_prefixed();
690 }
691 return result0;
692 }
693
694 function parse_prefixed() {
695 var result0, result1;
696 var pos0, pos1;
697
698 pos0 = pos;
699 pos1 = pos;
700 result0 = parse_and();
701 if (result0 !== null) {
702 result1 = parse_action();
703 if (result1 !== null) {
704 result0 = [result0, result1];
705 } else {
706 result0 = null;
707 pos = pos1;
708 }
709 } else {
710 result0 = null;
711 pos = pos1;
712 }
713 if (result0 !== null) {
714 result0 = (function(offset, code) {
715 return {
716 type: "semantic_and",
717 code: code
718 };
719 })(pos0, result0[1]);
720 }
721 if (result0 === null) {
722 pos = pos0;
723 }
724 if (result0 === null) {
725 pos0 = pos;
726 pos1 = pos;
727 result0 = parse_and();
728 if (result0 !== null) {
729 result1 = parse_suffixed();
730 if (result1 !== null) {
731 result0 = [result0, result1];
732 } else {
733 result0 = null;
734 pos = pos1;
735 }
736 } else {
737 result0 = null;
738 pos = pos1;
739 }
740 if (result0 !== null) {
741 result0 = (function(offset, expression) {
742 return {
743 type: "simple_and",
744 expression: expression
745 };
746 })(pos0, result0[1]);
747 }
748 if (result0 === null) {
749 pos = pos0;
750 }
751 if (result0 === null) {
752 pos0 = pos;
753 pos1 = pos;
754 result0 = parse_not();
755 if (result0 !== null) {
756 result1 = parse_action();
757 if (result1 !== null) {
758 result0 = [result0, result1];
759 } else {
760 result0 = null;
761 pos = pos1;
762 }
763 } else {
764 result0 = null;
765 pos = pos1;
766 }
767 if (result0 !== null) {
768 result0 = (function(offset, code) {
769 return {
770 type: "semantic_not",
771 code: code
772 };
773 })(pos0, result0[1]);
774 }
775 if (result0 === null) {
776 pos = pos0;
777 }
778 if (result0 === null) {
779 pos0 = pos;
780 pos1 = pos;
781 result0 = parse_not();
782 if (result0 !== null) {
783 result1 = parse_suffixed();
784 if (result1 !== null) {
785 result0 = [result0, result1];
786 } else {
787 result0 = null;
788 pos = pos1;
789 }
790 } else {
791 result0 = null;
792 pos = pos1;
793 }
794 if (result0 !== null) {
795 result0 = (function(offset, expression) {
796 return {
797 type: "simple_not",
798 expression: expression
799 };
800 })(pos0, result0[1]);
801 }
802 if (result0 === null) {
803 pos = pos0;
804 }
805 if (result0 === null) {
806 result0 = parse_suffixed();
807 }
808 }
809 }
810 }
811 return result0;
812 }
813
814 function parse_suffixed() {
815 var result0, result1;
816 var pos0, pos1;
817
818 pos0 = pos;
819 pos1 = pos;
820 result0 = parse_primary();
821 if (result0 !== null) {
822 result1 = parse_question();
823 if (result1 !== null) {
824 result0 = [result0, result1];
825 } else {
826 result0 = null;
827 pos = pos1;
828 }
829 } else {
830 result0 = null;
831 pos = pos1;
832 }
833 if (result0 !== null) {
834 result0 = (function(offset, expression) {
835 return {
836 type: "optional",
837 expression: expression
838 };
839 })(pos0, result0[0]);
840 }
841 if (result0 === null) {
842 pos = pos0;
843 }
844 if (result0 === null) {
845 pos0 = pos;
846 pos1 = pos;
847 result0 = parse_primary();
848 if (result0 !== null) {
849 result1 = parse_star();
850 if (result1 !== null) {
851 result0 = [result0, result1];
852 } else {
853 result0 = null;
854 pos = pos1;
855 }
856 } else {
857 result0 = null;
858 pos = pos1;
859 }
860 if (result0 !== null) {
861 result0 = (function(offset, expression) {
862 return {
863 type: "zero_or_more",
864 expression: expression
865 };
866 })(pos0, result0[0]);
867 }
868 if (result0 === null) {
869 pos = pos0;
870 }
871 if (result0 === null) {
872 pos0 = pos;
873 pos1 = pos;
874 result0 = parse_primary();
875 if (result0 !== null) {
876 result1 = parse_plus();
877 if (result1 !== null) {
878 result0 = [result0, result1];
879 } else {
880 result0 = null;
881 pos = pos1;
882 }
883 } else {
884 result0 = null;
885 pos = pos1;
886 }
887 if (result0 !== null) {
888 result0 = (function(offset, expression) {
889 return {
890 type: "one_or_more",
891 expression: expression
892 };
893 })(pos0, result0[0]);
894 }
895 if (result0 === null) {
896 pos = pos0;
897 }
898 if (result0 === null) {
899 result0 = parse_primary();
900 }
901 }
902 }
903 return result0;
904 }
905
906 function parse_primary() {
907 var result0, result1, result2;
908 var pos0, pos1, pos2, pos3;
909
910 pos0 = pos;
911 pos1 = pos;
912 result0 = parse_identifier();
913 if (result0 !== null) {
914 pos2 = pos;
915 reportFailures++;
916 pos3 = pos;
917 result1 = parse_string();
918 result1 = result1 !== null ? result1 : "";
919 if (result1 !== null) {
920 result2 = parse_equals();
921 if (result2 !== null) {
922 result1 = [result1, result2];
923 } else {
924 result1 = null;
925 pos = pos3;
926 }
927 } else {
928 result1 = null;
929 pos = pos3;
930 }
931 reportFailures--;
932 if (result1 === null) {
933 result1 = "";
934 } else {
935 result1 = null;
936 pos = pos2;
937 }
938 if (result1 !== null) {
939 result0 = [result0, result1];
940 } else {
941 result0 = null;
942 pos = pos1;
943 }
944 } else {
945 result0 = null;
946 pos = pos1;
947 }
948 if (result0 !== null) {
949 result0 = (function(offset, name) {
950 return {
951 type: "rule_ref",
952 name: name
953 };
954 })(pos0, result0[0]);
955 }
956 if (result0 === null) {
957 pos = pos0;
958 }
959 if (result0 === null) {
960 result0 = parse_literal();
961 if (result0 === null) {
962 pos0 = pos;
963 result0 = parse_dot();
964 if (result0 !== null) {
965 result0 = (function(offset) { return { type: "any" }; })(pos0);
966 }
967 if (result0 === null) {
968 pos = pos0;
969 }
970 if (result0 === null) {
971 result0 = parse_class();
972 if (result0 === null) {
973 pos0 = pos;
974 pos1 = pos;
975 result0 = parse_lparen();
976 if (result0 !== null) {
977 result1 = parse_choice();
978 if (result1 !== null) {
979 result2 = parse_rparen();
980 if (result2 !== null) {
981 result0 = [result0, result1, result2];
982 } else {
983 result0 = null;
984 pos = pos1;
985 }
986 } else {
987 result0 = null;
988 pos = pos1;
989 }
990 } else {
991 result0 = null;
992 pos = pos1;
993 }
994 if (result0 !== null) {
995 result0 = (function(offset, expression) { return expression; })(pos0, result0[1]);
996 }
997 if (result0 === null) {
998 pos = pos0;
999 }
1000 }
1001 }
1002 }
1003 }
1004 return result0;
1005 }
1006
1007 function parse_action() {
1008 var result0, result1;
1009 var pos0, pos1;
1010
1011 reportFailures++;
1012 pos0 = pos;
1013 pos1 = pos;
1014 result0 = parse_braced();
1015 if (result0 !== null) {
1016 result1 = parse___();
1017 if (result1 !== null) {
1018 result0 = [result0, result1];
1019 } else {
1020 result0 = null;
1021 pos = pos1;
1022 }
1023 } else {
1024 result0 = null;
1025 pos = pos1;
1026 }
1027 if (result0 !== null) {
1028 result0 = (function(offset, braced) { return braced.substr(1, braced.length - 2); })(pos0, result0[0]);
1029 }
1030 if (result0 === null) {
1031 pos = pos0;
1032 }
1033 reportFailures--;
1034 if (reportFailures === 0 && result0 === null) {
1035 matchFailed("action");
1036 }
1037 return result0;
1038 }
1039
1040 function parse_braced() {
1041 var result0, result1, result2;
1042 var pos0, pos1;
1043
1044 pos0 = pos;
1045 pos1 = pos;
1046 if (input.charCodeAt(pos) === 123) {
1047 result0 = "{";
1048 pos++;
1049 } else {
1050 result0 = null;
1051 if (reportFailures === 0) {
1052 matchFailed("\"{\"");
1053 }
1054 }
1055 if (result0 !== null) {
1056 result1 = [];
1057 result2 = parse_braced();
1058 if (result2 === null) {
1059 result2 = parse_nonBraceCharacter();
1060 }
1061 while (result2 !== null) {
1062 result1.push(result2);
1063 result2 = parse_braced();
1064 if (result2 === null) {
1065 result2 = parse_nonBraceCharacter();
1066 }
1067 }
1068 if (result1 !== null) {
1069 if (input.charCodeAt(pos) === 125) {
1070 result2 = "}";
1071 pos++;
1072 } else {
1073 result2 = null;
1074 if (reportFailures === 0) {
1075 matchFailed("\"}\"");
1076 }
1077 }
1078 if (result2 !== null) {
1079 result0 = [result0, result1, result2];
1080 } else {
1081 result0 = null;
1082 pos = pos1;
1083 }
1084 } else {
1085 result0 = null;
1086 pos = pos1;
1087 }
1088 } else {
1089 result0 = null;
1090 pos = pos1;
1091 }
1092 if (result0 !== null) {
1093 result0 = (function(offset, parts) {
1094 return "{" + parts.join("") + "}";
1095 })(pos0, result0[1]);
1096 }
1097 if (result0 === null) {
1098 pos = pos0;
1099 }
1100 return result0;
1101 }
1102
1103 function parse_nonBraceCharacters() {
1104 var result0, result1;
1105 var pos0;
1106
1107 pos0 = pos;
1108 result1 = parse_nonBraceCharacter();
1109 if (result1 !== null) {
1110 result0 = [];
1111 while (result1 !== null) {
1112 result0.push(result1);
1113 result1 = parse_nonBraceCharacter();
1114 }
1115 } else {
1116 result0 = null;
1117 }
1118 if (result0 !== null) {
1119 result0 = (function(offset, chars) { return chars.join(""); })(pos0, result0);
1120 }
1121 if (result0 === null) {
1122 pos = pos0;
1123 }
1124 return result0;
1125 }
1126
1127 function parse_nonBraceCharacter() {
1128 var result0;
1129
1130 if (/^[^{}]/.test(input.charAt(pos))) {
1131 result0 = input.charAt(pos);
1132 pos++;
1133 } else {
1134 result0 = null;
1135 if (reportFailures === 0) {
1136 matchFailed("[^{}]");
1137 }
1138 }
1139 return result0;
1140 }
1141
1142 function parse_equals() {
1143 var result0, result1;
1144 var pos0, pos1;
1145
1146 pos0 = pos;
1147 pos1 = pos;
1148 if (input.charCodeAt(pos) === 61) {
1149 result0 = "=";
1150 pos++;
1151 } else {
1152 result0 = null;
1153 if (reportFailures === 0) {
1154 matchFailed("\"=\"");
1155 }
1156 }
1157 if (result0 !== null) {
1158 result1 = parse___();
1159 if (result1 !== null) {
1160 result0 = [result0, result1];
1161 } else {
1162 result0 = null;
1163 pos = pos1;
1164 }
1165 } else {
1166 result0 = null;
1167 pos = pos1;
1168 }
1169 if (result0 !== null) {
1170 result0 = (function(offset) { return "="; })(pos0);
1171 }
1172 if (result0 === null) {
1173 pos = pos0;
1174 }
1175 return result0;
1176 }
1177
1178 function parse_colon() {
1179 var result0, result1;
1180 var pos0, pos1;
1181
1182 pos0 = pos;
1183 pos1 = pos;
1184 if (input.charCodeAt(pos) === 58) {
1185 result0 = ":";
1186 pos++;
1187 } else {
1188 result0 = null;
1189 if (reportFailures === 0) {
1190 matchFailed("\":\"");
1191 }
1192 }
1193 if (result0 !== null) {
1194 result1 = parse___();
1195 if (result1 !== null) {
1196 result0 = [result0, result1];
1197 } else {
1198 result0 = null;
1199 pos = pos1;
1200 }
1201 } else {
1202 result0 = null;
1203 pos = pos1;
1204 }
1205 if (result0 !== null) {
1206 result0 = (function(offset) { return ":"; })(pos0);
1207 }
1208 if (result0 === null) {
1209 pos = pos0;
1210 }
1211 return result0;
1212 }
1213
1214 function parse_semicolon() {
1215 var result0, result1;
1216 var pos0, pos1;
1217
1218 pos0 = pos;
1219 pos1 = pos;
1220 if (input.charCodeAt(pos) === 59) {
1221 result0 = ";";
1222 pos++;
1223 } else {
1224 result0 = null;
1225 if (reportFailures === 0) {
1226 matchFailed("\";\"");
1227 }
1228 }
1229 if (result0 !== null) {
1230 result1 = parse___();
1231 if (result1 !== null) {
1232 result0 = [result0, result1];
1233 } else {
1234 result0 = null;
1235 pos = pos1;
1236 }
1237 } else {
1238 result0 = null;
1239 pos = pos1;
1240 }
1241 if (result0 !== null) {
1242 result0 = (function(offset) { return ";"; })(pos0);
1243 }
1244 if (result0 === null) {
1245 pos = pos0;
1246 }
1247 return result0;
1248 }
1249
1250 function parse_slash() {
1251 var result0, result1;
1252 var pos0, pos1;
1253
1254 pos0 = pos;
1255 pos1 = pos;
1256 if (input.charCodeAt(pos) === 47) {
1257 result0 = "/";
1258 pos++;
1259 } else {
1260 result0 = null;
1261 if (reportFailures === 0) {
1262 matchFailed("\"/\"");
1263 }
1264 }
1265 if (result0 !== null) {
1266 result1 = parse___();
1267 if (result1 !== null) {
1268 result0 = [result0, result1];
1269 } else {
1270 result0 = null;
1271 pos = pos1;
1272 }
1273 } else {
1274 result0 = null;
1275 pos = pos1;
1276 }
1277 if (result0 !== null) {
1278 result0 = (function(offset) { return "/"; })(pos0);
1279 }
1280 if (result0 === null) {
1281 pos = pos0;
1282 }
1283 return result0;
1284 }
1285
1286 function parse_and() {
1287 var result0, result1;
1288 var pos0, pos1;
1289
1290 pos0 = pos;
1291 pos1 = pos;
1292 if (input.charCodeAt(pos) === 38) {
1293 result0 = "&";
1294 pos++;
1295 } else {
1296 result0 = null;
1297 if (reportFailures === 0) {
1298 matchFailed("\"&\"");
1299 }
1300 }
1301 if (result0 !== null) {
1302 result1 = parse___();
1303 if (result1 !== null) {
1304 result0 = [result0, result1];
1305 } else {
1306 result0 = null;
1307 pos = pos1;
1308 }
1309 } else {
1310 result0 = null;
1311 pos = pos1;
1312 }
1313 if (result0 !== null) {
1314 result0 = (function(offset) { return "&"; })(pos0);
1315 }
1316 if (result0 === null) {
1317 pos = pos0;
1318 }
1319 return result0;
1320 }
1321
1322 function parse_not() {
1323 var result0, result1;
1324 var pos0, pos1;
1325
1326 pos0 = pos;
1327 pos1 = pos;
1328 if (input.charCodeAt(pos) === 33) {
1329 result0 = "!";
1330 pos++;
1331 } else {
1332 result0 = null;
1333 if (reportFailures === 0) {
1334 matchFailed("\"!\"");
1335 }
1336 }
1337 if (result0 !== null) {
1338 result1 = parse___();
1339 if (result1 !== null) {
1340 result0 = [result0, result1];
1341 } else {
1342 result0 = null;
1343 pos = pos1;
1344 }
1345 } else {
1346 result0 = null;
1347 pos = pos1;
1348 }
1349 if (result0 !== null) {
1350 result0 = (function(offset) { return "!"; })(pos0);
1351 }
1352 if (result0 === null) {
1353 pos = pos0;
1354 }
1355 return result0;
1356 }
1357
1358 function parse_question() {
1359 var result0, result1;
1360 var pos0, pos1;
1361
1362 pos0 = pos;
1363 pos1 = pos;
1364 if (input.charCodeAt(pos) === 63) {
1365 result0 = "?";
1366 pos++;
1367 } else {
1368 result0 = null;
1369 if (reportFailures === 0) {
1370 matchFailed("\"?\"");
1371 }
1372 }
1373 if (result0 !== null) {
1374 result1 = parse___();
1375 if (result1 !== null) {
1376 result0 = [result0, result1];
1377 } else {
1378 result0 = null;
1379 pos = pos1;
1380 }
1381 } else {
1382 result0 = null;
1383 pos = pos1;
1384 }
1385 if (result0 !== null) {
1386 result0 = (function(offset) { return "?"; })(pos0);
1387 }
1388 if (result0 === null) {
1389 pos = pos0;
1390 }
1391 return result0;
1392 }
1393
1394 function parse_star() {
1395 var result0, result1;
1396 var pos0, pos1;
1397
1398 pos0 = pos;
1399 pos1 = pos;
1400 if (input.charCodeAt(pos) === 42) {
1401 result0 = "*";
1402 pos++;
1403 } else {
1404 result0 = null;
1405 if (reportFailures === 0) {
1406 matchFailed("\"*\"");
1407 }
1408 }
1409 if (result0 !== null) {
1410 result1 = parse___();
1411 if (result1 !== null) {
1412 result0 = [result0, result1];
1413 } else {
1414 result0 = null;
1415 pos = pos1;
1416 }
1417 } else {
1418 result0 = null;
1419 pos = pos1;
1420 }
1421 if (result0 !== null) {
1422 result0 = (function(offset) { return "*"; })(pos0);
1423 }
1424 if (result0 === null) {
1425 pos = pos0;
1426 }
1427 return result0;
1428 }
1429
1430 function parse_plus() {
1431 var result0, result1;
1432 var pos0, pos1;
1433
1434 pos0 = pos;
1435 pos1 = pos;
1436 if (input.charCodeAt(pos) === 43) {
1437 result0 = "+";
1438 pos++;
1439 } else {
1440 result0 = null;
1441 if (reportFailures === 0) {
1442 matchFailed("\"+\"");
1443 }
1444 }
1445 if (result0 !== null) {
1446 result1 = parse___();
1447 if (result1 !== null) {
1448 result0 = [result0, result1];
1449 } else {
1450 result0 = null;
1451 pos = pos1;
1452 }
1453 } else {
1454 result0 = null;
1455 pos = pos1;
1456 }
1457 if (result0 !== null) {
1458 result0 = (function(offset) { return "+"; })(pos0);
1459 }
1460 if (result0 === null) {
1461 pos = pos0;
1462 }
1463 return result0;
1464 }
1465
1466 function parse_lparen() {
1467 var result0, result1;
1468 var pos0, pos1;
1469
1470 pos0 = pos;
1471 pos1 = pos;
1472 if (input.charCodeAt(pos) === 40) {
1473 result0 = "(";
1474 pos++;
1475 } else {
1476 result0 = null;
1477 if (reportFailures === 0) {
1478 matchFailed("\"(\"");
1479 }
1480 }
1481 if (result0 !== null) {
1482 result1 = parse___();
1483 if (result1 !== null) {
1484 result0 = [result0, result1];
1485 } else {
1486 result0 = null;
1487 pos = pos1;
1488 }
1489 } else {
1490 result0 = null;
1491 pos = pos1;
1492 }
1493 if (result0 !== null) {
1494 result0 = (function(offset) { return "("; })(pos0);
1495 }
1496 if (result0 === null) {
1497 pos = pos0;
1498 }
1499 return result0;
1500 }
1501
1502 function parse_rparen() {
1503 var result0, result1;
1504 var pos0, pos1;
1505
1506 pos0 = pos;
1507 pos1 = pos;
1508 if (input.charCodeAt(pos) === 41) {
1509 result0 = ")";
1510 pos++;
1511 } else {
1512 result0 = null;
1513 if (reportFailures === 0) {
1514 matchFailed("\")\"");
1515 }
1516 }
1517 if (result0 !== null) {
1518 result1 = parse___();
1519 if (result1 !== null) {
1520 result0 = [result0, result1];
1521 } else {
1522 result0 = null;
1523 pos = pos1;
1524 }
1525 } else {
1526 result0 = null;
1527 pos = pos1;
1528 }
1529 if (result0 !== null) {
1530 result0 = (function(offset) { return ")"; })(pos0);
1531 }
1532 if (result0 === null) {
1533 pos = pos0;
1534 }
1535 return result0;
1536 }
1537
1538 function parse_dot() {
1539 var result0, result1;
1540 var pos0, pos1;
1541
1542 pos0 = pos;
1543 pos1 = pos;
1544 if (input.charCodeAt(pos) === 46) {
1545 result0 = ".";
1546 pos++;
1547 } else {
1548 result0 = null;
1549 if (reportFailures === 0) {
1550 matchFailed("\".\"");
1551 }
1552 }
1553 if (result0 !== null) {
1554 result1 = parse___();
1555 if (result1 !== null) {
1556 result0 = [result0, result1];
1557 } else {
1558 result0 = null;
1559 pos = pos1;
1560 }
1561 } else {
1562 result0 = null;
1563 pos = pos1;
1564 }
1565 if (result0 !== null) {
1566 result0 = (function(offset) { return "."; })(pos0);
1567 }
1568 if (result0 === null) {
1569 pos = pos0;
1570 }
1571 return result0;
1572 }
1573
1574 function parse_identifier() {
1575 var result0, result1, result2;
1576 var pos0, pos1;
1577
1578 reportFailures++;
1579 pos0 = pos;
1580 pos1 = pos;
1581 result0 = parse_letter();
1582 if (result0 === null) {
1583 if (input.charCodeAt(pos) === 95) {
1584 result0 = "_";
1585 pos++;
1586 } else {
1587 result0 = null;
1588 if (reportFailures === 0) {
1589 matchFailed("\"_\"");
1590 }
1591 }
1592 if (result0 === null) {
1593 if (input.charCodeAt(pos) === 36) {
1594 result0 = "$";
1595 pos++;
1596 } else {
1597 result0 = null;
1598 if (reportFailures === 0) {
1599 matchFailed("\"$\"");
1600 }
1601 }
1602 }
1603 }
1604 if (result0 !== null) {
1605 result1 = [];
1606 result2 = parse_letter();
1607 if (result2 === null) {
1608 result2 = parse_digit();
1609 if (result2 === null) {
1610 if (input.charCodeAt(pos) === 95) {
1611 result2 = "_";
1612 pos++;
1613 } else {
1614 result2 = null;
1615 if (reportFailures === 0) {
1616 matchFailed("\"_\"");
1617 }
1618 }
1619 if (result2 === null) {
1620 if (input.charCodeAt(pos) === 36) {
1621 result2 = "$";
1622 pos++;
1623 } else {
1624 result2 = null;
1625 if (reportFailures === 0) {
1626 matchFailed("\"$\"");
1627 }
1628 }
1629 }
1630 }
1631 }
1632 while (result2 !== null) {
1633 result1.push(result2);
1634 result2 = parse_letter();
1635 if (result2 === null) {
1636 result2 = parse_digit();
1637 if (result2 === null) {
1638 if (input.charCodeAt(pos) === 95) {
1639 result2 = "_";
1640 pos++;
1641 } else {
1642 result2 = null;
1643 if (reportFailures === 0) {
1644 matchFailed("\"_\"");
1645 }
1646 }
1647 if (result2 === null) {
1648 if (input.charCodeAt(pos) === 36) {
1649 result2 = "$";
1650 pos++;
1651 } else {
1652 result2 = null;
1653 if (reportFailures === 0) {
1654 matchFailed("\"$\"");
1655 }
1656 }
1657 }
1658 }
1659 }
1660 }
1661 if (result1 !== null) {
1662 result2 = parse___();
1663 if (result2 !== null) {
1664 result0 = [result0, result1, result2];
1665 } else {
1666 result0 = null;
1667 pos = pos1;
1668 }
1669 } else {
1670 result0 = null;
1671 pos = pos1;
1672 }
1673 } else {
1674 result0 = null;
1675 pos = pos1;
1676 }
1677 if (result0 !== null) {
1678 result0 = (function(offset, head, tail) {
1679 return head + tail.join("");
1680 })(pos0, result0[0], result0[1]);
1681 }
1682 if (result0 === null) {
1683 pos = pos0;
1684 }
1685 reportFailures--;
1686 if (reportFailures === 0 && result0 === null) {
1687 matchFailed("identifier");
1688 }
1689 return result0;
1690 }
1691
1692 function parse_literal() {
1693 var result0, result1, result2;
1694 var pos0, pos1;
1695
1696 reportFailures++;
1697 pos0 = pos;
1698 pos1 = pos;
1699 result0 = parse_doubleQuotedString();
1700 if (result0 === null) {
1701 result0 = parse_singleQuotedString();
1702 }
1703 if (result0 !== null) {
1704 if (input.charCodeAt(pos) === 105) {
1705 result1 = "i";
1706 pos++;
1707 } else {
1708 result1 = null;
1709 if (reportFailures === 0) {
1710 matchFailed("\"i\"");
1711 }
1712 }
1713 result1 = result1 !== null ? result1 : "";
1714 if (result1 !== null) {
1715 result2 = parse___();
1716 if (result2 !== null) {
1717 result0 = [result0, result1, result2];
1718 } else {
1719 result0 = null;
1720 pos = pos1;
1721 }
1722 } else {
1723 result0 = null;
1724 pos = pos1;
1725 }
1726 } else {
1727 result0 = null;
1728 pos = pos1;
1729 }
1730 if (result0 !== null) {
1731 result0 = (function(offset, value, flags) {
1732 return {
1733 type: "literal",
1734 value: value,
1735 ignoreCase: flags === "i"
1736 };
1737 })(pos0, result0[0], result0[1]);
1738 }
1739 if (result0 === null) {
1740 pos = pos0;
1741 }
1742 reportFailures--;
1743 if (reportFailures === 0 && result0 === null) {
1744 matchFailed("literal");
1745 }
1746 return result0;
1747 }
1748
1749 function parse_string() {
1750 var result0, result1;
1751 var pos0, pos1;
1752
1753 reportFailures++;
1754 pos0 = pos;
1755 pos1 = pos;
1756 result0 = parse_doubleQuotedString();
1757 if (result0 === null) {
1758 result0 = parse_singleQuotedString();
1759 }
1760 if (result0 !== null) {
1761 result1 = parse___();
1762 if (result1 !== null) {
1763 result0 = [result0, result1];
1764 } else {
1765 result0 = null;
1766 pos = pos1;
1767 }
1768 } else {
1769 result0 = null;
1770 pos = pos1;
1771 }
1772 if (result0 !== null) {
1773 result0 = (function(offset, string) { return string; })(pos0, result0[0]);
1774 }
1775 if (result0 === null) {
1776 pos = pos0;
1777 }
1778 reportFailures--;
1779 if (reportFailures === 0 && result0 === null) {
1780 matchFailed("string");
1781 }
1782 return result0;
1783 }
1784
1785 function parse_doubleQuotedString() {
1786 var result0, result1, result2;
1787 var pos0, pos1;
1788
1789 pos0 = pos;
1790 pos1 = pos;
1791 if (input.charCodeAt(pos) === 34) {
1792 result0 = "\"";
1793 pos++;
1794 } else {
1795 result0 = null;
1796 if (reportFailures === 0) {
1797 matchFailed("\"\\\"\"");
1798 }
1799 }
1800 if (result0 !== null) {
1801 result1 = [];
1802 result2 = parse_doubleQuotedCharacter();
1803 while (result2 !== null) {
1804 result1.push(result2);
1805 result2 = parse_doubleQuotedCharacter();
1806 }
1807 if (result1 !== null) {
1808 if (input.charCodeAt(pos) === 34) {
1809 result2 = "\"";
1810 pos++;
1811 } else {
1812 result2 = null;
1813 if (reportFailures === 0) {
1814 matchFailed("\"\\\"\"");
1815 }
1816 }
1817 if (result2 !== null) {
1818 result0 = [result0, result1, result2];
1819 } else {
1820 result0 = null;
1821 pos = pos1;
1822 }
1823 } else {
1824 result0 = null;
1825 pos = pos1;
1826 }
1827 } else {
1828 result0 = null;
1829 pos = pos1;
1830 }
1831 if (result0 !== null) {
1832 result0 = (function(offset, chars) { return chars.join(""); })(pos0, result0[1]);
1833 }
1834 if (result0 === null) {
1835 pos = pos0;
1836 }
1837 return result0;
1838 }
1839
1840 function parse_doubleQuotedCharacter() {
1841 var result0;
1842
1843 result0 = parse_simpleDoubleQuotedCharacter();
1844 if (result0 === null) {
1845 result0 = parse_simpleEscapeSequence();
1846 if (result0 === null) {
1847 result0 = parse_zeroEscapeSequence();
1848 if (result0 === null) {
1849 result0 = parse_hexEscapeSequence();
1850 if (result0 === null) {
1851 result0 = parse_unicodeEscapeSequence();
1852 if (result0 === null) {
1853 result0 = parse_eolEscapeSequence();
1854 }
1855 }
1856 }
1857 }
1858 }
1859 return result0;
1860 }
1861
1862 function parse_simpleDoubleQuotedCharacter() {
1863 var result0, result1;
1864 var pos0, pos1, pos2;
1865
1866 pos0 = pos;
1867 pos1 = pos;
1868 pos2 = pos;
1869 reportFailures++;
1870 if (input.charCodeAt(pos) === 34) {
1871 result0 = "\"";
1872 pos++;
1873 } else {
1874 result0 = null;
1875 if (reportFailures === 0) {
1876 matchFailed("\"\\\"\"");
1877 }
1878 }
1879 if (result0 === null) {
1880 if (input.charCodeAt(pos) === 92) {
1881 result0 = "\\";
1882 pos++;
1883 } else {
1884 result0 = null;
1885 if (reportFailures === 0) {
1886 matchFailed("\"\\\\\"");
1887 }
1888 }
1889 if (result0 === null) {
1890 result0 = parse_eolChar();
1891 }
1892 }
1893 reportFailures--;
1894 if (result0 === null) {
1895 result0 = "";
1896 } else {
1897 result0 = null;
1898 pos = pos2;
1899 }
1900 if (result0 !== null) {
1901 if (input.length > pos) {
1902 result1 = input.charAt(pos);
1903 pos++;
1904 } else {
1905 result1 = null;
1906 if (reportFailures === 0) {
1907 matchFailed("any character");
1908 }
1909 }
1910 if (result1 !== null) {
1911 result0 = [result0, result1];
1912 } else {
1913 result0 = null;
1914 pos = pos1;
1915 }
1916 } else {
1917 result0 = null;
1918 pos = pos1;
1919 }
1920 if (result0 !== null) {
1921 result0 = (function(offset, char_) { return char_; })(pos0, result0[1]);
1922 }
1923 if (result0 === null) {
1924 pos = pos0;
1925 }
1926 return result0;
1927 }
1928
1929 function parse_singleQuotedString() {
1930 var result0, result1, result2;
1931 var pos0, pos1;
1932
1933 pos0 = pos;
1934 pos1 = pos;
1935 if (input.charCodeAt(pos) === 39) {
1936 result0 = "'";
1937 pos++;
1938 } else {
1939 result0 = null;
1940 if (reportFailures === 0) {
1941 matchFailed("\"'\"");
1942 }
1943 }
1944 if (result0 !== null) {
1945 result1 = [];
1946 result2 = parse_singleQuotedCharacter();
1947 while (result2 !== null) {
1948 result1.push(result2);
1949 result2 = parse_singleQuotedCharacter();
1950 }
1951 if (result1 !== null) {
1952 if (input.charCodeAt(pos) === 39) {
1953 result2 = "'";
1954 pos++;
1955 } else {
1956 result2 = null;
1957 if (reportFailures === 0) {
1958 matchFailed("\"'\"");
1959 }
1960 }
1961 if (result2 !== null) {
1962 result0 = [result0, result1, result2];
1963 } else {
1964 result0 = null;
1965 pos = pos1;
1966 }
1967 } else {
1968 result0 = null;
1969 pos = pos1;
1970 }
1971 } else {
1972 result0 = null;
1973 pos = pos1;
1974 }
1975 if (result0 !== null) {
1976 result0 = (function(offset, chars) { return chars.join(""); })(pos0, result0[1]);
1977 }
1978 if (result0 === null) {
1979 pos = pos0;
1980 }
1981 return result0;
1982 }
1983
1984 function parse_singleQuotedCharacter() {
1985 var result0;
1986
1987 result0 = parse_simpleSingleQuotedCharacter();
1988 if (result0 === null) {
1989 result0 = parse_simpleEscapeSequence();
1990 if (result0 === null) {
1991 result0 = parse_zeroEscapeSequence();
1992 if (result0 === null) {
1993 result0 = parse_hexEscapeSequence();
1994 if (result0 === null) {
1995 result0 = parse_unicodeEscapeSequence();
1996 if (result0 === null) {
1997 result0 = parse_eolEscapeSequence();
1998 }
1999 }
2000 }
2001 }
2002 }
2003 return result0;
2004 }
2005
2006 function parse_simpleSingleQuotedCharacter() {
2007 var result0, result1;
2008 var pos0, pos1, pos2;
2009
2010 pos0 = pos;
2011 pos1 = pos;
2012 pos2 = pos;
2013 reportFailures++;
2014 if (input.charCodeAt(pos) === 39) {
2015 result0 = "'";
2016 pos++;
2017 } else {
2018 result0 = null;
2019 if (reportFailures === 0) {
2020 matchFailed("\"'\"");
2021 }
2022 }
2023 if (result0 === null) {
2024 if (input.charCodeAt(pos) === 92) {
2025 result0 = "\\";
2026 pos++;
2027 } else {
2028 result0 = null;
2029 if (reportFailures === 0) {
2030 matchFailed("\"\\\\\"");
2031 }
2032 }
2033 if (result0 === null) {
2034 result0 = parse_eolChar();
2035 }
2036 }
2037 reportFailures--;
2038 if (result0 === null) {
2039 result0 = "";
2040 } else {
2041 result0 = null;
2042 pos = pos2;
2043 }
2044 if (result0 !== null) {
2045 if (input.length > pos) {
2046 result1 = input.charAt(pos);
2047 pos++;
2048 } else {
2049 result1 = null;
2050 if (reportFailures === 0) {
2051 matchFailed("any character");
2052 }
2053 }
2054 if (result1 !== null) {
2055 result0 = [result0, result1];
2056 } else {
2057 result0 = null;
2058 pos = pos1;
2059 }
2060 } else {
2061 result0 = null;
2062 pos = pos1;
2063 }
2064 if (result0 !== null) {
2065 result0 = (function(offset, char_) { return char_; })(pos0, result0[1]);
2066 }
2067 if (result0 === null) {
2068 pos = pos0;
2069 }
2070 return result0;
2071 }
2072
2073 function parse_class() {
2074 var result0, result1, result2, result3, result4, result5;
2075 var pos0, pos1;
2076
2077 reportFailures++;
2078 pos0 = pos;
2079 pos1 = pos;
2080 if (input.charCodeAt(pos) === 91) {
2081 result0 = "[";
2082 pos++;
2083 } else {
2084 result0 = null;
2085 if (reportFailures === 0) {
2086 matchFailed("\"[\"");
2087 }
2088 }
2089 if (result0 !== null) {
2090 if (input.charCodeAt(pos) === 94) {
2091 result1 = "^";
2092 pos++;
2093 } else {
2094 result1 = null;
2095 if (reportFailures === 0) {
2096 matchFailed("\"^\"");
2097 }
2098 }
2099 result1 = result1 !== null ? result1 : "";
2100 if (result1 !== null) {
2101 result2 = [];
2102 result3 = parse_classCharacterRange();
2103 if (result3 === null) {
2104 result3 = parse_classCharacter();
2105 }
2106 while (result3 !== null) {
2107 result2.push(result3);
2108 result3 = parse_classCharacterRange();
2109 if (result3 === null) {
2110 result3 = parse_classCharacter();
2111 }
2112 }
2113 if (result2 !== null) {
2114 if (input.charCodeAt(pos) === 93) {
2115 result3 = "]";
2116 pos++;
2117 } else {
2118 result3 = null;
2119 if (reportFailures === 0) {
2120 matchFailed("\"]\"");
2121 }
2122 }
2123 if (result3 !== null) {
2124 if (input.charCodeAt(pos) === 105) {
2125 result4 = "i";
2126 pos++;
2127 } else {
2128 result4 = null;
2129 if (reportFailures === 0) {
2130 matchFailed("\"i\"");
2131 }
2132 }
2133 result4 = result4 !== null ? result4 : "";
2134 if (result4 !== null) {
2135 result5 = parse___();
2136 if (result5 !== null) {
2137 result0 = [result0, result1, result2, result3, result4, result5];
2138 } else {
2139 result0 = null;
2140 pos = pos1;
2141 }
2142 } else {
2143 result0 = null;
2144 pos = pos1;
2145 }
2146 } else {
2147 result0 = null;
2148 pos = pos1;
2149 }
2150 } else {
2151 result0 = null;
2152 pos = pos1;
2153 }
2154 } else {
2155 result0 = null;
2156 pos = pos1;
2157 }
2158 } else {
2159 result0 = null;
2160 pos = pos1;
2161 }
2162 if (result0 !== null) {
2163 result0 = (function(offset, inverted, parts, flags) {
2164 var partsConverted = map(parts, function(part) { return part.data; });
2165 var rawText = "["
2166 + inverted
2167 + map(parts, function(part) { return part.rawText; }).join("")
2168 + "]"
2169 + flags;
2170
2171 return {
2172 type: "class",
2173 inverted: inverted === "^",
2174 ignoreCase: flags === "i",
2175 parts: partsConverted,
2176 // FIXME: Get the raw text from the input directly.
2177 rawText: rawText
2178 };
2179 })(pos0, result0[1], result0[2], result0[4]);
2180 }
2181 if (result0 === null) {
2182 pos = pos0;
2183 }
2184 reportFailures--;
2185 if (reportFailures === 0 && result0 === null) {
2186 matchFailed("character class");
2187 }
2188 return result0;
2189 }
2190
2191 function parse_classCharacterRange() {
2192 var result0, result1, result2;
2193 var pos0, pos1;
2194
2195 pos0 = pos;
2196 pos1 = pos;
2197 result0 = parse_classCharacter();
2198 if (result0 !== null) {
2199 if (input.charCodeAt(pos) === 45) {
2200 result1 = "-";
2201 pos++;
2202 } else {
2203 result1 = null;
2204 if (reportFailures === 0) {
2205 matchFailed("\"-\"");
2206 }
2207 }
2208 if (result1 !== null) {
2209 result2 = parse_classCharacter();
2210 if (result2 !== null) {
2211 result0 = [result0, result1, result2];
2212 } else {
2213 result0 = null;
2214 pos = pos1;
2215 }
2216 } else {
2217 result0 = null;
2218 pos = pos1;
2219 }
2220 } else {
2221 result0 = null;
2222 pos = pos1;
2223 }
2224 if (result0 !== null) {
2225 result0 = (function(offset, begin, end) {
2226 if (begin.data.charCodeAt(0) > end.data.charCodeAt(0)) {
2227 throw new this.SyntaxError(
2228 "Invalid character range: " + begin.rawText + "-" + end.rawText + "."
2229 );
2230 }
2231
2232 return {
2233 data: [begin.data, end.data],
2234 // FIXME: Get the raw text from the input directly.
2235 rawText: begin.rawText + "-" + end.rawText
2236 };
2237 })(pos0, result0[0], result0[2]);
2238 }
2239 if (result0 === null) {
2240 pos = pos0;
2241 }
2242 return result0;
2243 }
2244
2245 function parse_classCharacter() {
2246 var result0;
2247 var pos0;
2248
2249 pos0 = pos;
2250 result0 = parse_bracketDelimitedCharacter();
2251 if (result0 !== null) {
2252 result0 = (function(offset, char_) {
2253 return {
2254 data: char_,
2255 // FIXME: Get the raw text from the input directly.
2256 rawText: quoteForRegexpClass(char_)
2257 };
2258 })(pos0, result0);
2259 }
2260 if (result0 === null) {
2261 pos = pos0;
2262 }
2263 return result0;
2264 }
2265
2266 function parse_bracketDelimitedCharacter() {
2267 var result0;
2268
2269 result0 = parse_simpleBracketDelimitedCharacter();
2270 if (result0 === null) {
2271 result0 = parse_simpleEscapeSequence();
2272 if (result0 === null) {
2273 result0 = parse_zeroEscapeSequence();
2274 if (result0 === null) {
2275 result0 = parse_hexEscapeSequence();
2276 if (result0 === null) {
2277 result0 = parse_unicodeEscapeSequence();
2278 if (result0 === null) {
2279 result0 = parse_eolEscapeSequence();
2280 }
2281 }
2282 }
2283 }
2284 }
2285 return result0;
2286 }
2287
2288 function parse_simpleBracketDelimitedCharacter() {
2289 var result0, result1;
2290 var pos0, pos1, pos2;
2291
2292 pos0 = pos;
2293 pos1 = pos;
2294 pos2 = pos;
2295 reportFailures++;
2296 if (input.charCodeAt(pos) === 93) {
2297 result0 = "]";
2298 pos++;
2299 } else {
2300 result0 = null;
2301 if (reportFailures === 0) {
2302 matchFailed("\"]\"");
2303 }
2304 }
2305 if (result0 === null) {
2306 if (input.charCodeAt(pos) === 92) {
2307 result0 = "\\";
2308 pos++;
2309 } else {
2310 result0 = null;
2311 if (reportFailures === 0) {
2312 matchFailed("\"\\\\\"");
2313 }
2314 }
2315 if (result0 === null) {
2316 result0 = parse_eolChar();
2317 }
2318 }
2319 reportFailures--;
2320 if (result0 === null) {
2321 result0 = "";
2322 } else {
2323 result0 = null;
2324 pos = pos2;
2325 }
2326 if (result0 !== null) {
2327 if (input.length > pos) {
2328 result1 = input.charAt(pos);
2329 pos++;
2330 } else {
2331 result1 = null;
2332 if (reportFailures === 0) {
2333 matchFailed("any character");
2334 }
2335 }
2336 if (result1 !== null) {
2337 result0 = [result0, result1];
2338 } else {
2339 result0 = null;
2340 pos = pos1;
2341 }
2342 } else {
2343 result0 = null;
2344 pos = pos1;
2345 }
2346 if (result0 !== null) {
2347 result0 = (function(offset, char_) { return char_; })(pos0, result0[1]);
2348 }
2349 if (result0 === null) {
2350 pos = pos0;
2351 }
2352 return result0;
2353 }
2354
2355 function parse_simpleEscapeSequence() {
2356 var result0, result1, result2;
2357 var pos0, pos1, pos2;
2358
2359 pos0 = pos;
2360 pos1 = pos;
2361 if (input.charCodeAt(pos) === 92) {
2362 result0 = "\\";
2363 pos++;
2364 } else {
2365 result0 = null;
2366 if (reportFailures === 0) {
2367 matchFailed("\"\\\\\"");
2368 }
2369 }
2370 if (result0 !== null) {
2371 pos2 = pos;
2372 reportFailures++;
2373 result1 = parse_digit();
2374 if (result1 === null) {
2375 if (input.charCodeAt(pos) === 120) {
2376 result1 = "x";
2377 pos++;
2378 } else {
2379 result1 = null;
2380 if (reportFailures === 0) {
2381 matchFailed("\"x\"");
2382 }
2383 }
2384 if (result1 === null) {
2385 if (input.charCodeAt(pos) === 117) {
2386 result1 = "u";
2387 pos++;
2388 } else {
2389 result1 = null;
2390 if (reportFailures === 0) {
2391 matchFailed("\"u\"");
2392 }
2393 }
2394 if (result1 === null) {
2395 result1 = parse_eolChar();
2396 }
2397 }
2398 }
2399 reportFailures--;
2400 if (result1 === null) {
2401 result1 = "";
2402 } else {
2403 result1 = null;
2404 pos = pos2;
2405 }
2406 if (result1 !== null) {
2407 if (input.length > pos) {
2408 result2 = input.charAt(pos);
2409 pos++;
2410 } else {
2411 result2 = null;
2412 if (reportFailures === 0) {
2413 matchFailed("any character");
2414 }
2415 }
2416 if (result2 !== null) {
2417 result0 = [result0, result1, result2];
2418 } else {
2419 result0 = null;
2420 pos = pos1;
2421 }
2422 } else {
2423 result0 = null;
2424 pos = pos1;
2425 }
2426 } else {
2427 result0 = null;
2428 pos = pos1;
2429 }
2430 if (result0 !== null) {
2431 result0 = (function(offset, char_) {
2432 return char_
2433 .replace("b", "\b")
2434 .replace("f", "\f")
2435 .replace("n", "\n")
2436 .replace("r", "\r")
2437 .replace("t", "\t")
2438 .replace("v", "\x0B"); // IE does not recognize "\v".
2439 })(pos0, result0[2]);
2440 }
2441 if (result0 === null) {
2442 pos = pos0;
2443 }
2444 return result0;
2445 }
2446
2447 function parse_zeroEscapeSequence() {
2448 var result0, result1;
2449 var pos0, pos1, pos2;
2450
2451 pos0 = pos;
2452 pos1 = pos;
2453 if (input.substr(pos, 2) === "\\0") {
2454 result0 = "\\0";
2455 pos += 2;
2456 } else {
2457 result0 = null;
2458 if (reportFailures === 0) {
2459 matchFailed("\"\\\\0\"");
2460 }
2461 }
2462 if (result0 !== null) {
2463 pos2 = pos;
2464 reportFailures++;
2465 result1 = parse_digit();
2466 reportFailures--;
2467 if (result1 === null) {
2468 result1 = "";
2469 } else {
2470 result1 = null;
2471 pos = pos2;
2472 }
2473 if (result1 !== null) {
2474 result0 = [result0, result1];
2475 } else {
2476 result0 = null;
2477 pos = pos1;
2478 }
2479 } else {
2480 result0 = null;
2481 pos = pos1;
2482 }
2483 if (result0 !== null) {
2484 result0 = (function(offset) { return "\x00"; })(pos0);
2485 }
2486 if (result0 === null) {
2487 pos = pos0;
2488 }
2489 return result0;
2490 }
2491
2492 function parse_hexEscapeSequence() {
2493 var result0, result1, result2;
2494 var pos0, pos1;
2495
2496 pos0 = pos;
2497 pos1 = pos;
2498 if (input.substr(pos, 2) === "\\x") {
2499 result0 = "\\x";
2500 pos += 2;
2501 } else {
2502 result0 = null;
2503 if (reportFailures === 0) {
2504 matchFailed("\"\\\\x\"");
2505 }
2506 }
2507 if (result0 !== null) {
2508 result1 = parse_hexDigit();
2509 if (result1 !== null) {
2510 result2 = parse_hexDigit();
2511 if (result2 !== null) {
2512 result0 = [result0, result1, result2];
2513 } else {
2514 result0 = null;
2515 pos = pos1;
2516 }
2517 } else {
2518 result0 = null;
2519 pos = pos1;
2520 }
2521 } else {
2522 result0 = null;
2523 pos = pos1;
2524 }
2525 if (result0 !== null) {
2526 result0 = (function(offset, h1, h2) {
2527 return String.fromCharCode(parseInt(h1 + h2, 16));
2528 })(pos0, result0[1], result0[2]);
2529 }
2530 if (result0 === null) {
2531 pos = pos0;
2532 }
2533 return result0;
2534 }
2535
2536 function parse_unicodeEscapeSequence() {
2537 var result0, result1, result2, result3, result4;
2538 var pos0, pos1;
2539
2540 pos0 = pos;
2541 pos1 = pos;
2542 if (input.substr(pos, 2) === "\\u") {
2543 result0 = "\\u";
2544 pos += 2;
2545 } else {
2546 result0 = null;
2547 if (reportFailures === 0) {
2548 matchFailed("\"\\\\u\"");
2549 }
2550 }
2551 if (result0 !== null) {
2552 result1 = parse_hexDigit();
2553 if (result1 !== null) {
2554 result2 = parse_hexDigit();
2555 if (result2 !== null) {
2556 result3 = parse_hexDigit();
2557 if (result3 !== null) {
2558 result4 = parse_hexDigit();
2559 if (result4 !== null) {
2560 result0 = [result0, result1, result2, result3, result4];
2561 } else {
2562 result0 = null;
2563 pos = pos1;
2564 }
2565 } else {
2566 result0 = null;
2567 pos = pos1;
2568 }
2569 } else {
2570 result0 = null;
2571 pos = pos1;
2572 }
2573 } else {
2574 result0 = null;
2575 pos = pos1;
2576 }
2577 } else {
2578 result0 = null;
2579 pos = pos1;
2580 }
2581 if (result0 !== null) {
2582 result0 = (function(offset, h1, h2, h3, h4) {
2583 return String.fromCharCode(parseInt(h1 + h2 + h3 + h4, 16));
2584 })(pos0, result0[1], result0[2], result0[3], result0[4]);
2585 }
2586 if (result0 === null) {
2587 pos = pos0;
2588 }
2589 return result0;
2590 }
2591
2592 function parse_eolEscapeSequence() {
2593 var result0, result1;
2594 var pos0, pos1;
2595
2596 pos0 = pos;
2597 pos1 = pos;
2598 if (input.charCodeAt(pos) === 92) {
2599 result0 = "\\";
2600 pos++;
2601 } else {
2602 result0 = null;
2603 if (reportFailures === 0) {
2604 matchFailed("\"\\\\\"");
2605 }
2606 }
2607 if (result0 !== null) {
2608 result1 = parse_eol();
2609 if (result1 !== null) {
2610 result0 = [result0, result1];
2611 } else {
2612 result0 = null;
2613 pos = pos1;
2614 }
2615 } else {
2616 result0 = null;
2617 pos = pos1;
2618 }
2619 if (result0 !== null) {
2620 result0 = (function(offset, eol) { return eol; })(pos0, result0[1]);
2621 }
2622 if (result0 === null) {
2623 pos = pos0;
2624 }
2625 return result0;
2626 }
2627
2628 function parse_digit() {
2629 var result0;
2630
2631 if (/^[0-9]/.test(input.charAt(pos))) {
2632 result0 = input.charAt(pos);
2633 pos++;
2634 } else {
2635 result0 = null;
2636 if (reportFailures === 0) {
2637 matchFailed("[0-9]");
2638 }
2639 }
2640 return result0;
2641 }
2642
2643 function parse_hexDigit() {
2644 var result0;
2645
2646 if (/^[0-9a-fA-F]/.test(input.charAt(pos))) {
2647 result0 = input.charAt(pos);
2648 pos++;
2649 } else {
2650 result0 = null;
2651 if (reportFailures === 0) {
2652 matchFailed("[0-9a-fA-F]");
2653 }
2654 }
2655 return result0;
2656 }
2657
2658 function parse_letter() {
2659 var result0;
2660
2661 result0 = parse_lowerCaseLetter();
2662 if (result0 === null) {
2663 result0 = parse_upperCaseLetter();
2664 }
2665 return result0;
2666 }
2667
2668 function parse_lowerCaseLetter() {
2669 var result0;
2670
2671 if (/^[a-z]/.test(input.charAt(pos))) {
2672 result0 = input.charAt(pos);
2673 pos++;
2674 } else {
2675 result0 = null;
2676 if (reportFailures === 0) {
2677 matchFailed("[a-z]");
2678 }
2679 }
2680 return result0;
2681 }
2682
2683 function parse_upperCaseLetter() {
2684 var result0;
2685
2686 if (/^[A-Z]/.test(input.charAt(pos))) {
2687 result0 = input.charAt(pos);
2688 pos++;
2689 } else {
2690 result0 = null;
2691 if (reportFailures === 0) {
2692 matchFailed("[A-Z]");
2693 }
2694 }
2695 return result0;
2696 }
2697
2698 function parse___() {
2699 var result0, result1;
2700
2701 result0 = [];
2702 result1 = parse_whitespace();
2703 if (result1 === null) {
2704 result1 = parse_eol();
2705 if (result1 === null) {
2706 result1 = parse_comment();
2707 }
2708 }
2709 while (result1 !== null) {
2710 result0.push(result1);
2711 result1 = parse_whitespace();
2712 if (result1 === null) {
2713 result1 = parse_eol();
2714 if (result1 === null) {
2715 result1 = parse_comment();
2716 }
2717 }
2718 }
2719 return result0;
2720 }
2721
2722 function parse_comment() {
2723 var result0;
2724
2725 reportFailures++;
2726 result0 = parse_singleLineComment();
2727 if (result0 === null) {
2728 result0 = parse_multiLineComment();
2729 }
2730 reportFailures--;
2731 if (reportFailures === 0 && result0 === null) {
2732 matchFailed("comment");
2733 }
2734 return result0;
2735 }
2736
2737 function parse_singleLineComment() {
2738 var result0, result1, result2, result3;
2739 var pos0, pos1, pos2;
2740
2741 pos0 = pos;
2742 if (input.substr(pos, 2) === "//") {
2743 result0 = "//";
2744 pos += 2;
2745 } else {
2746 result0 = null;
2747 if (reportFailures === 0) {
2748 matchFailed("\"//\"");
2749 }
2750 }
2751 if (result0 !== null) {
2752 result1 = [];
2753 pos1 = pos;
2754 pos2 = pos;
2755 reportFailures++;
2756 result2 = parse_eolChar();
2757 reportFailures--;
2758 if (result2 === null) {
2759 result2 = "";
2760 } else {
2761 result2 = null;
2762 pos = pos2;
2763 }
2764 if (result2 !== null) {
2765 if (input.length > pos) {
2766 result3 = input.charAt(pos);
2767 pos++;
2768 } else {
2769 result3 = null;
2770 if (reportFailures === 0) {
2771 matchFailed("any character");
2772 }
2773 }
2774 if (result3 !== null) {
2775 result2 = [result2, result3];
2776 } else {
2777 result2 = null;
2778 pos = pos1;
2779 }
2780 } else {
2781 result2 = null;
2782 pos = pos1;
2783 }
2784 while (result2 !== null) {
2785 result1.push(result2);
2786 pos1 = pos;
2787 pos2 = pos;
2788 reportFailures++;
2789 result2 = parse_eolChar();
2790 reportFailures--;
2791 if (result2 === null) {
2792 result2 = "";
2793 } else {
2794 result2 = null;
2795 pos = pos2;
2796 }
2797 if (result2 !== null) {
2798 if (input.length > pos) {
2799 result3 = input.charAt(pos);
2800 pos++;
2801 } else {
2802 result3 = null;
2803 if (reportFailures === 0) {
2804 matchFailed("any character");
2805 }
2806 }
2807 if (result3 !== null) {
2808 result2 = [result2, result3];
2809 } else {
2810 result2 = null;
2811 pos = pos1;
2812 }
2813 } else {
2814 result2 = null;
2815 pos = pos1;
2816 }
2817 }
2818 if (result1 !== null) {
2819 result0 = [result0, result1];
2820 } else {
2821 result0 = null;
2822 pos = pos0;
2823 }
2824 } else {
2825 result0 = null;
2826 pos = pos0;
2827 }
2828 return result0;
2829 }
2830
2831 function parse_multiLineComment() {
2832 var result0, result1, result2, result3;
2833 var pos0, pos1, pos2;
2834
2835 pos0 = pos;
2836 if (input.substr(pos, 2) === "/*") {
2837 result0 = "/*";
2838 pos += 2;
2839 } else {
2840 result0 = null;
2841 if (reportFailures === 0) {
2842 matchFailed("\"/*\"");
2843 }
2844 }
2845 if (result0 !== null) {
2846 result1 = [];
2847 pos1 = pos;
2848 pos2 = pos;
2849 reportFailures++;
2850 if (input.substr(pos, 2) === "*/") {
2851 result2 = "*/";
2852 pos += 2;
2853 } else {
2854 result2 = null;
2855 if (reportFailures === 0) {
2856 matchFailed("\"*/\"");
2857 }
2858 }
2859 reportFailures--;
2860 if (result2 === null) {
2861 result2 = "";
2862 } else {
2863 result2 = null;
2864 pos = pos2;
2865 }
2866 if (result2 !== null) {
2867 if (input.length > pos) {
2868 result3 = input.charAt(pos);
2869 pos++;
2870 } else {
2871 result3 = null;
2872 if (reportFailures === 0) {
2873 matchFailed("any character");
2874 }
2875 }
2876 if (result3 !== null) {
2877 result2 = [result2, result3];
2878 } else {
2879 result2 = null;
2880 pos = pos1;
2881 }
2882 } else {
2883 result2 = null;
2884 pos = pos1;
2885 }
2886 while (result2 !== null) {
2887 result1.push(result2);
2888 pos1 = pos;
2889 pos2 = pos;
2890 reportFailures++;
2891 if (input.substr(pos, 2) === "*/") {
2892 result2 = "*/";
2893 pos += 2;
2894 } else {
2895 result2 = null;
2896 if (reportFailures === 0) {
2897 matchFailed("\"*/\"");
2898 }
2899 }
2900 reportFailures--;
2901 if (result2 === null) {
2902 result2 = "";
2903 } else {
2904 result2 = null;
2905 pos = pos2;
2906 }
2907 if (result2 !== null) {
2908 if (input.length > pos) {
2909 result3 = input.charAt(pos);
2910 pos++;
2911 } else {
2912 result3 = null;
2913 if (reportFailures === 0) {
2914 matchFailed("any character");
2915 }
2916 }
2917 if (result3 !== null) {
2918 result2 = [result2, result3];
2919 } else {
2920 result2 = null;
2921 pos = pos1;
2922 }
2923 } else {
2924 result2 = null;
2925 pos = pos1;
2926 }
2927 }
2928 if (result1 !== null) {
2929 if (input.substr(pos, 2) === "*/") {
2930 result2 = "*/";
2931 pos += 2;
2932 } else {
2933 result2 = null;
2934 if (reportFailures === 0) {
2935 matchFailed("\"*/\"");
2936 }
2937 }
2938 if (result2 !== null) {
2939 result0 = [result0, result1, result2];
2940 } else {
2941 result0 = null;
2942 pos = pos0;
2943 }
2944 } else {
2945 result0 = null;
2946 pos = pos0;
2947 }
2948 } else {
2949 result0 = null;
2950 pos = pos0;
2951 }
2952 return result0;
2953 }
2954
2955 function parse_eol() {
2956 var result0;
2957
2958 reportFailures++;
2959 if (input.charCodeAt(pos) === 10) {
2960 result0 = "\n";
2961 pos++;
2962 } else {
2963 result0 = null;
2964 if (reportFailures === 0) {
2965 matchFailed("\"\\n\"");
2966 }
2967 }
2968 if (result0 === null) {
2969 if (input.substr(pos, 2) === "\r\n") {
2970 result0 = "\r\n";
2971 pos += 2;
2972 } else {
2973 result0 = null;
2974 if (reportFailures === 0) {
2975 matchFailed("\"\\r\\n\"");
2976 }
2977 }
2978 if (result0 === null) {
2979 if (input.charCodeAt(pos) === 13) {
2980 result0 = "\r";
2981 pos++;
2982 } else {
2983 result0 = null;
2984 if (reportFailures === 0) {
2985 matchFailed("\"\\r\"");
2986 }
2987 }
2988 if (result0 === null) {
2989 if (input.charCodeAt(pos) === 8232) {
2990 result0 = "\u2028";
2991 pos++;
2992 } else {
2993 result0 = null;
2994 if (reportFailures === 0) {
2995 matchFailed("\"\\u2028\"");
2996 }
2997 }
2998 if (result0 === null) {
2999 if (input.charCodeAt(pos) === 8233) {
3000 result0 = "\u2029";
3001 pos++;
3002 } else {
3003 result0 = null;
3004 if (reportFailures === 0) {
3005 matchFailed("\"\\u2029\"");
3006 }
3007 }
3008 }
3009 }
3010 }
3011 }
3012 reportFailures--;
3013 if (reportFailures === 0 && result0 === null) {
3014 matchFailed("end of line");
3015 }
3016 return result0;
3017 }
3018
3019 function parse_eolChar() {
3020 var result0;
3021
3022 if (/^[\n\r\u2028\u2029]/.test(input.charAt(pos))) {
3023 result0 = input.charAt(pos);
3024 pos++;
3025 } else {
3026 result0 = null;
3027 if (reportFailures === 0) {
3028 matchFailed("[\\n\\r\\u2028\\u2029]");
3029 }
3030 }
3031 return result0;
3032 }
3033
3034 function parse_whitespace() {
3035 var result0;
3036
3037 reportFailures++;
3038 if (/^[ \t\x0B\f\xA0\uFEFF\u1680\u180E\u2000-\u200A\u202F\u205F\u3000]/.test(input.charAt(pos))) {
3039 result0 = input.charAt(pos);
3040 pos++;
3041 } else {
3042 result0 = null;
3043 if (reportFailures === 0) {
3044 matchFailed("[ \\t\\x0B\\f\\xA0\\uFEFF\\u1680\\u180E\\u2000-\\u200A\\u202F\\u205F\\u3000]");
3045 }
3046 }
3047 reportFailures--;
3048 if (reportFailures === 0 && result0 === null) {
3049 matchFailed("whitespace");
3050 }
3051 return result0;
3052 }
3053
3054
3055 function cleanupExpected(expected) {
3056 expected.sort();
3057
3058 var lastExpected = null;
3059 var cleanExpected = [];
3060 for (var i = 0; i < expected.length; i++) {
3061 if (expected[i] !== lastExpected) {
3062 cleanExpected.push(expected[i]);
3063 lastExpected = expected[i];
3064 }
3065 }
3066 return cleanExpected;
3067 }
3068
3069 function computeErrorPosition() {
3070 /*
3071 * The first idea was to use |String.split| to break the input up to the
3072 * error position along newlines and derive the line and column from
3073 * there. However IE's |split| implementation is so broken that it was
3074 * enough to prevent it.
3075 */
3076
3077 var line = 1;
3078 var column = 1;
3079 var seenCR = false;
3080
3081 for (var i = 0; i < Math.max(pos, rightmostFailuresPos); i++) {
3082 var ch = input.charAt(i);
3083 if (ch === "\n") {
3084 if (!seenCR) { line++; }
3085 column = 1;
3086 seenCR = false;
3087 } else if (ch === "\r" || ch === "\u2028" || ch === "\u2029") {
3088 line++;
3089 column = 1;
3090 seenCR = true;
3091 } else {
3092 column++;
3093 seenCR = false;
3094 }
3095 }
3096
3097 return { line: line, column: column };
3098 }
3099
3100
3101 var result = parseFunctions[startRule]();
3102
3103 /*
3104 * The parser is now in one of the following three states:
3105 *
3106 * 1. The parser successfully parsed the whole input.
3107 *
3108 * - |result !== null|
3109 * - |pos === input.length|
3110 * - |rightmostFailuresExpected| may or may not contain something
3111 *
3112 * 2. The parser successfully parsed only a part of the input.
3113 *
3114 * - |result !== null|
3115 * - |pos < input.length|
3116 * - |rightmostFailuresExpected| may or may not contain something
3117 *
3118 * 3. The parser did not successfully parse any part of the input.
3119 *
3120 * - |result === null|
3121 * - |pos === 0|
3122 * - |rightmostFailuresExpected| contains at least one failure
3123 *
3124 * All code following this comment (including called functions) must
3125 * handle these states.
3126 */
3127 if (result === null || pos !== input.length) {
3128 var offset = Math.max(pos, rightmostFailuresPos);
3129 var found = offset < input.length ? input.charAt(offset) : null;
3130 var errorPosition = computeErrorPosition();
3131
3132 throw new this.SyntaxError(
3133 cleanupExpected(rightmostFailuresExpected),
3134 found,
3135 offset,
3136 errorPosition.line,
3137 errorPosition.column
3138 );
3139 }
3140
3141 return result;
3142 },
3143
3144 /* Returns the parser source code. */
3145 toSource: function() { return this._source; }
3146 };
3147
3148 /* Thrown when a parser encounters a syntax error. */
3149
3150 result.SyntaxError = function(expected, found, offset, line, column) {
3151 function buildMessage(expected, found) {
3152 var expectedHumanized, foundHumanized;
3153
3154 switch (expected.length) {
3155 case 0:
3156 expectedHumanized = "end of input";
3157 break;
3158 case 1:
3159 expectedHumanized = expected[0];
3160 break;
3161 default:
3162 expectedHumanized = expected.slice(0, expected.length - 1).join(", ")
3163 + " or "
3164 + expected[expected.length - 1];
3165 }
3166
3167 foundHumanized = found ? quote(found) : "end of input";
3168
3169 return "Expected " + expectedHumanized + " but " + foundHumanized + " found.";
3170 }
3171
3172 this.name = "SyntaxError";
3173 this.expected = expected;
3174 this.found = found;
3175 this.message = buildMessage(expected, found);
3176 this.offset = offset;
3177 this.line = line;
3178 this.column = column;
3179 };
3180
3181 result.SyntaxError.prototype = Error.prototype;
3182
3183 return result;
3184 })();
3185 PEG.compiler = {
3186 /*
3187 * Names of passes that will get run during the compilation (in the specified
3188 * order).
3189 */
3190 appliedPassNames: [
3191 "reportMissingRules",
3192 "reportLeftRecursion",
3193 "removeProxyRules",
3194 "computeVarNames",
3195 "computeParams"
3196 ],
3197
3198 /*
3199 * Generates a parser from a specified grammar AST. Throws |PEG.GrammarError|
3200 * if the AST contains a semantic error. Note that not all errors are detected
3201 * during the generation and some may protrude to the generated parser and
3202 * cause its malfunction.
3203 */
3204 compile: function(ast, options) {
3205 var that = this;
3206
3207 each(this.appliedPassNames, function(passName) {
3208 that.passes[passName](ast);
3209 });
3210
3211 var source = this.emitter(ast, options);
3212 var result = eval(source);
3213 result._source = source;
3214
3215 return result;
3216 }
3217 };
3218
3219 /*
3220 * Compiler passes.
3221 *
3222 * Each pass is a function that is passed the AST. It can perform checks on it
3223 * or modify it as needed. If the pass encounters a semantic error, it throws
3224 * |PEG.GrammarError|.
3225 */
3226 PEG.compiler.passes = {
3227 /* Checks that all referenced rules exist. */
3228 reportMissingRules: function(ast) {
3229 function nop() {}
3230
3231 function checkExpression(node) { check(node.expression); }
3232
3233 function checkSubnodes(propertyName) {
3234 return function(node) { each(node[propertyName], check); };
3235 }
3236
3237 var check = buildNodeVisitor({
3238 grammar: checkSubnodes("rules"),
3239 rule: checkExpression,
3240 choice: checkSubnodes("alternatives"),
3241 sequence: checkSubnodes("elements"),
3242 labeled: checkExpression,
3243 simple_and: checkExpression,
3244 simple_not: checkExpression,
3245 semantic_and: nop,
3246 semantic_not: nop,
3247 optional: checkExpression,
3248 zero_or_more: checkExpression,
3249 one_or_more: checkExpression,
3250 action: checkExpression,
3251
3252 rule_ref:
3253 function(node) {
3254 if (!findRuleByName(ast, node.name)) {
3255 throw new PEG.GrammarError(
3256 "Referenced rule \"" + node.name + "\" does not exist."
3257 );
3258 }
3259 },
3260
3261 literal: nop,
3262 any: nop,
3263 "class": nop
3264 });
3265
3266 check(ast);
3267 },
3268
3269 /* Checks that no left recursion is present. */
3270 reportLeftRecursion: function(ast) {
3271 function nop() {}
3272
3273 function checkExpression(node, appliedRules) {
3274 check(node.expression, appliedRules);
3275 }
3276
3277 function checkSubnodes(propertyName) {
3278 return function(node, appliedRules) {
3279 each(node[propertyName], function(subnode) {
3280 check(subnode, appliedRules);
3281 });
3282 };
3283 }
3284
3285 var check = buildNodeVisitor({
3286 grammar: checkSubnodes("rules"),
3287
3288 rule:
3289 function(node, appliedRules) {
3290 check(node.expression, appliedRules.concat(node.name));
3291 },
3292
3293 choice: checkSubnodes("alternatives"),
3294
3295 sequence:
3296 function(node, appliedRules) {
3297 if (node.elements.length > 0) {
3298 check(node.elements[0], appliedRules);
3299 }
3300 },
3301
3302 labeled: checkExpression,
3303 simple_and: checkExpression,
3304 simple_not: checkExpression,
3305 semantic_and: nop,
3306 semantic_not: nop,
3307 optional: checkExpression,
3308 zero_or_more: checkExpression,
3309 one_or_more: checkExpression,
3310 action: checkExpression,
3311
3312 rule_ref:
3313 function(node, appliedRules) {
3314 if (contains(appliedRules, node.name)) {
3315 throw new PEG.GrammarError(
3316 "Left recursion detected for rule \"" + node.name + "\"."
3317 );
3318 }
3319 check(findRuleByName(ast, node.name), appliedRules);
3320 },
3321
3322 literal: nop,
3323 any: nop,
3324 "class": nop
3325 });
3326
3327 check(ast, []);
3328 },
3329
3330 /*
3331 * Removes proxy rules -- that is, rules that only delegate to other rule.
3332 */
3333 removeProxyRules: function(ast) {
3334 function isProxyRule(node) {
3335 return node.type === "rule" && node.expression.type === "rule_ref";
3336 }
3337
3338 function replaceRuleRefs(ast, from, to) {
3339 function nop() {}
3340
3341 function replaceInExpression(node, from, to) {
3342 replace(node.expression, from, to);
3343 }
3344
3345 function replaceInSubnodes(propertyName) {
3346 return function(node, from, to) {
3347 each(node[propertyName], function(subnode) {
3348 replace(subnode, from, to);
3349 });
3350 };
3351 }
3352
3353 var replace = buildNodeVisitor({
3354 grammar: replaceInSubnodes("rules"),
3355 rule: replaceInExpression,
3356 choice: replaceInSubnodes("alternatives"),
3357 sequence: replaceInSubnodes("elements"),
3358 labeled: replaceInExpression,
3359 simple_and: replaceInExpression,
3360 simple_not: replaceInExpression,
3361 semantic_and: nop,
3362 semantic_not: nop,
3363 optional: replaceInExpression,
3364 zero_or_more: replaceInExpression,
3365 one_or_more: replaceInExpression,
3366 action: replaceInExpression,
3367
3368 rule_ref:
3369 function(node, from, to) {
3370 if (node.name === from) {
3371 node.name = to;
3372 }
3373 },
3374
3375 literal: nop,
3376 any: nop,
3377 "class": nop
3378 });
3379
3380 replace(ast, from, to);
3381 }
3382
3383 var indices = [];
3384
3385 each(ast.rules, function(rule, i) {
3386 if (isProxyRule(rule)) {
3387 replaceRuleRefs(ast, rule.name, rule.expression.name);
3388 if (rule.name === ast.startRule) {
3389 ast.startRule = rule.expression.name;
3390 }
3391 indices.push(i);
3392 }
3393 });
3394
3395 indices.reverse();
3396
3397 each(indices, function(index) {
3398 ast.rules.splice(index, 1);
3399 });
3400 },
3401
3402 /*
3403 * Computes names of variables used for storing match results and parse
3404 * positions in generated code. These variables are organized as two stacks.
3405 * The following will hold after running this pass:
3406 *
3407 * * All nodes except "grammar" and "rule" nodes will have a |resultVar|
3408 * property. It will contain a name of the variable that will store a
3409 * match result of the expression represented by the node in generated
3410 * code.
3411 *
3412 * * Some nodes will have a |posVar| property. It will contain a name of the
3413 * variable that will store a parse position in generated code.
3414 *
3415 * * All "rule" nodes will contain |resultVars| and |posVars| properties.
3416 * They will contain a list of values of |resultVar| and |posVar|
3417 * properties used in rule's subnodes. (This is useful to declare
3418 * variables in generated code.)
3419 */
3420 computeVarNames: function(ast) {
3421 function resultVar(index) { return "result" + index; }
3422 function posVar(index) { return "pos" + index; }
3423
3424 function computeLeaf(node, index) {
3425 node.resultVar = resultVar(index.result);
3426
3427 return { result: 0, pos: 0 };
3428 }
3429
3430 function computeFromExpression(delta) {
3431 return function(node, index) {
3432 var depth = compute(
3433 node.expression,
3434 {
3435 result: index.result + delta.result,
3436 pos: index.pos + delta.pos
3437 }
3438 );
3439
3440 node.resultVar = resultVar(index.result);
3441 if (delta.pos !== 0) {
3442 node.posVar = posVar(index.pos);
3443 }
3444
3445 return {
3446 result: depth.result + delta.result,
3447 pos: depth.pos + delta.pos
3448 };
3449 };
3450 }
3451
3452 var compute = buildNodeVisitor({
3453 grammar:
3454 function(node, index) {
3455 each(node.rules, function(node) {
3456 compute(node, index);
3457 });
3458 },
3459
3460 rule:
3461 function(node, index) {
3462 var depth = compute(node.expression, index);
3463
3464 node.resultVar = resultVar(index.result);
3465 node.resultVars = map(range(depth.result + 1), resultVar);
3466 node.posVars = map(range(depth.pos), posVar);
3467 },
3468
3469 choice:
3470 function(node, index) {
3471 var depths = map(node.alternatives, function(alternative) {
3472 return compute(alternative, index);
3473 });
3474
3475 node.resultVar = resultVar(index.result);
3476
3477 return {
3478 result: Math.max.apply(null, pluck(depths, "result")),
3479 pos: Math.max.apply(null, pluck(depths, "pos"))
3480 };
3481 },
3482
3483 sequence:
3484 function(node, index) {
3485 var depths = map(node.elements, function(element, i) {
3486 return compute(
3487 element,
3488 { result: index.result + i, pos: index.pos + 1 }
3489 );
3490 });
3491
3492 node.resultVar = resultVar(index.result);
3493 node.posVar = posVar(index.pos);
3494
3495 return {
3496 result:
3497 node.elements.length > 0
3498 ? Math.max.apply(
3499 null,
3500 map(depths, function(d, i) { return i + d.result; })
3501 )
3502 : 0,
3503
3504 pos:
3505 node.elements.length > 0
3506 ? 1 + Math.max.apply(null, pluck(depths, "pos"))
3507 : 1
3508 };
3509 },
3510
3511 labeled: computeFromExpression({ result: 0, pos: 0 }),
3512 simple_and: computeFromExpression({ result: 0, pos: 1 }),
3513 simple_not: computeFromExpression({ result: 0, pos: 1 }),
3514 semantic_and: computeLeaf,
3515 semantic_not: computeLeaf,
3516 optional: computeFromExpression({ result: 0, pos: 0 }),
3517 zero_or_more: computeFromExpression({ result: 1, pos: 0 }),
3518 one_or_more: computeFromExpression({ result: 1, pos: 0 }),
3519 action: computeFromExpression({ result: 0, pos: 1 }),
3520 rule_ref: computeLeaf,
3521 literal: computeLeaf,
3522 any: computeLeaf,
3523 "class": computeLeaf
3524 });
3525
3526 compute(ast, { result: 0, pos: 0 });
3527 },
3528
3529 /*
3530 * This pass walks through the AST and tracks what labels are visible at each
3531 * point. For "action", "semantic_and" and "semantic_or" nodes it computes
3532 * parameter names and values for the function used in generated code. (In the
3533 * emitter, user's code is wrapped into a function that is immediately
3534 * executed. Its parameter names correspond to visible labels and its
3535 * parameter values to their captured values). Implicitly, this pass defines
3536 * scoping rules for labels.
3537 *
3538 * After running this pass, all "action", "semantic_and" and "semantic_or"
3539 * nodes will have a |params| property containing an object mapping parameter
3540 * names to the expressions that will be used as their values.
3541 */
3542 computeParams: function(ast) {
3543 var envs = [];
3544
3545 function scoped(f) {
3546 envs.push({});
3547 f();
3548 envs.pop();
3549 }
3550
3551 function nop() {}
3552
3553 function computeForScopedExpression(node) {
3554 scoped(function() { compute(node.expression); });
3555 }
3556
3557 function computeParams(node) {
3558 var env = envs[envs.length - 1], params = {}, name;
3559
3560 for (name in env) {
3561 params[name] = env[name];
3562 }
3563 node.params = params;
3564 }
3565
3566 var compute = buildNodeVisitor({
3567 grammar:
3568 function(node) {
3569 each(node.rules, compute);
3570 },
3571
3572 rule: computeForScopedExpression,
3573
3574 choice:
3575 function(node) {
3576 scoped(function() { each(node.alternatives, compute); });
3577 },
3578
3579 sequence:
3580 function(node) {
3581 var env = envs[envs.length - 1], name;
3582
3583 function fixup(name) {
3584 each(pluck(node.elements, "resultVar"), function(resultVar, i) {
3585 if ((new RegExp("^" + resultVar + "(\\[\\d+\\])*$")).test(env[name])) {
3586 env[name] = node.resultVar + "[" + i + "]"
3587 + env[name].substr(resultVar.length);
3588 }
3589 });
3590 }
3591
3592 each(node.elements, compute);
3593
3594 for (name in env) {
3595 fixup(name);
3596 }
3597 },
3598
3599 labeled:
3600 function(node) {
3601 envs[envs.length - 1][node.label] = node.resultVar;
3602
3603 scoped(function() { compute(node.expression); });
3604 },
3605
3606 simple_and: computeForScopedExpression,
3607 simple_not: computeForScopedExpression,
3608 semantic_and: computeParams,
3609 semantic_not: computeParams,
3610 optional: computeForScopedExpression,
3611 zero_or_more: computeForScopedExpression,
3612 one_or_more: computeForScopedExpression,
3613
3614 action:
3615 function(node) {
3616 scoped(function() {
3617 compute(node.expression);
3618 computeParams(node);
3619 });
3620 },
3621
3622 rule_ref: nop,
3623 literal: nop,
3624 any: nop,
3625 "class": nop
3626 });
3627
3628 compute(ast);
3629 }
3630 };
3631 /* Emits the generated code for the AST. */
3632 PEG.compiler.emitter = function(ast, options) {
3633 options = options || {};
3634 if (options.cache === undefined) {
3635 options.cache = false;
3636 }
3637 if (options.trackLineAndColumn === undefined) {
3638 options.trackLineAndColumn = false;
3639 }
3640
3641 /*
3642 * Codie 1.1.0
3643 *
3644 * https://github.com/dmajda/codie
3645 *
3646 * Copyright (c) 2011-2012 David Majda
3647 * Licensend under the MIT license.
3648 */
3649 var Codie = (function(undefined) {
3650
3651 function stringEscape(s) {
3652 function hex(ch) { return ch.charCodeAt(0).toString(16).toUpperCase(); }
3653
3654 /*
3655 * ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a
3656 * string literal except for the closing quote character, backslash,
3657 * carriage return, line separator, paragraph separator, and line feed.
3658 * Any character may appear in the form of an escape sequence.
3659 *
3660 * For portability, we also escape escape all control and non-ASCII
3661 * characters. Note that "\0" and "\v" escape sequences are not used
3662 * because JSHint does not like the first and IE the second.
3663 */
3664 return s
3665 .replace(/\\/g, '\\\\') // backslash
3666 .replace(/"/g, '\\"') // closing double quote
3667 .replace(/\x08/g, '\\b') // backspace
3668 .replace(/\t/g, '\\t') // horizontal tab
3669 .replace(/\n/g, '\\n') // line feed
3670 .replace(/\f/g, '\\f') // form feed
3671 .replace(/\r/g, '\\r') // carriage return
3672 .replace(/[\x00-\x07\x0B\x0E\x0F]/g, function(ch) { return '\\x0' + hex(ch); })
3673 .replace(/[\x10-\x1F\x80-\xFF]/g, function(ch) { return '\\x' + hex(ch); })
3674 .replace(/[\u0180-\u0FFF]/g, function(ch) { return '\\u0' + hex(ch); })
3675 .replace(/[\u1080-\uFFFF]/g, function(ch) { return '\\u' + hex(ch); });
3676 }
3677
3678 function push(s) { return '__p.push(' + s + ');'; }
3679
3680 function pushRaw(template, length, state) {
3681 function unindent(code, level, unindentFirst) {
3682 return code.replace(
3683 new RegExp('^.{' + level +'}', "gm"),
3684 function(str, offset) {
3685 if (offset === 0) {
3686 return unindentFirst ? '' : str;
3687 } else {
3688 return "";
3689 }
3690 }
3691 );
3692 }
3693
3694 var escaped = stringEscape(unindent(
3695 template.substring(0, length),
3696 state.indentLevel(),
3697 state.atBOL
3698 ));
3699
3700 return escaped.length > 0 ? push('"' + escaped + '"') : '';
3701 }
3702
3703
3704 var Codie = {
3705 /* Codie version (uses semantic versioning). */
3706 VERSION: "1.1.0",
3707
3708 /*
3709 * Specifies by how many characters do #if/#else and #for unindent their
3710 * content in the generated code.
3711 */
3712 indentStep: 2,
3713
3714 /* Description of #-commands. Extend to define your own commands. */
3715 commands: {
3716 "if": {
3717 params: /^(.*)$/,
3718 compile: function(state, prefix, params) {
3719 return ['if(' + params[0] + '){', []];
3720 },
3721 stackOp: "push"
3722 },
3723 "else": {
3724 params: /^$/,
3725 compile: function(state) {
3726 var stack = state.commandStack,
3727 insideElse = stack[stack.length - 1] === "else",
3728 insideIf = stack[stack.length - 1] === "if";
3729
3730 if (insideElse) { throw new Error("Multiple #elses."); }
3731 if (!insideIf) { throw new Error("Using #else outside of #if."); }
3732
3733 return ['}else{', []];
3734 },
3735 stackOp: "replace"
3736 },
3737 "for": {
3738 params: /^([a-zA-Z_][a-zA-Z0-9_]*)[ \t]+in[ \t]+(.*)$/,
3739 init: function(state) {
3740 state.forCurrLevel = 0; // current level of #for loop nesting
3741 state.forMaxLevel = 0; // maximum level of #for loop nesting
3742 },
3743 compile: function(state, prefix, params) {
3744 var c = '__c' + state.forCurrLevel, // __c for "collection"
3745 l = '__l' + state.forCurrLevel, // __l for "length"
3746 i = '__i' + state.forCurrLevel; // __i for "index"
3747
3748 state.forCurrLevel++;
3749 if (state.forMaxLevel < state.forCurrLevel) {
3750 state.forMaxLevel = state.forCurrLevel;
3751 }
3752
3753 return [
3754 c + '=' + params[1] + ';'
3755 + l + '=' + c + '.length;'
3756 + 'for(' + i + '=0;' + i + '<' + l + ';' + i + '++){'
3757 + params[0] + '=' + c + '[' + i + '];',
3758 [params[0], c, l, i]
3759 ];
3760 },
3761 exit: function(state) { state.forCurrLevel--; },
3762 stackOp: "push"
3763 },
3764 "end": {
3765 params: /^$/,
3766 compile: function(state) {
3767 var stack = state.commandStack, exit;
3768
3769 if (stack.length === 0) { throw new Error("Too many #ends."); }
3770
3771 exit = Codie.commands[stack[stack.length - 1]].exit;
3772 if (exit) { exit(state); }
3773
3774 return ['}', []];
3775 },
3776 stackOp: "pop"
3777 },
3778 "block": {
3779 params: /^(.*)$/,
3780 compile: function(state, prefix, params) {
3781 var x = '__x', // __x for "prefix",
3782 n = '__n', // __n for "lines"
3783 l = '__l', // __l for "length"
3784 i = '__i'; // __i for "index"
3785
3786 /*
3787 * Originally, the generated code used |String.prototype.replace|, but
3788 * it is buggy in certain versions of V8 so it was rewritten. See the
3789 * tests for details.
3790 */
3791 return [
3792 x + '="' + stringEscape(prefix.substring(state.indentLevel())) + '";'
3793 + n + '=(' + params[0] + ').toString().split("\\n");'
3794 + l + '=' + n + '.length;'
3795 + 'for(' + i + '=0;' + i + '<' + l + ';' + i + '++){'
3796 + n + '[' + i +']=' + x + '+' + n + '[' + i + ']+"\\n";'
3797 + '}'
3798 + push(n + '.join("")'),
3799 [x, n, l, i]
3800 ];
3801 },
3802 stackOp: "nop"
3803 }
3804 },
3805
3806 /*
3807 * Compiles a template into a function. When called, this function will
3808 * execute the template in the context of an object passed in a parameter and
3809 * return the result.
3810 */
3811 template: function(template) {
3812 var stackOps = {
3813 push: function(stack, name) { stack.push(name); },
3814 replace: function(stack, name) { stack[stack.length - 1] = name; },
3815 pop: function(stack) { stack.pop(); },
3816 nop: function() { }
3817 };
3818
3819 function compileExpr(state, expr) {
3820 state.atBOL = false;
3821 return [push(expr), []];
3822 }
3823
3824 function compileCommand(state, prefix, name, params) {
3825 var command, match, result;
3826
3827 command = Codie.commands[name];
3828 if (!command) { throw new Error("Unknown command: #" + name + "."); }
3829
3830 match = command.params.exec(params);
3831 if (match === null) {
3832 throw new Error(
3833 "Invalid params for command #" + name + ": " + params + "."
3834 );
3835 }
3836
3837 result = command.compile(state, prefix, match.slice(1));
3838 stackOps[command.stackOp](state.commandStack, name);
3839 state.atBOL = true;
3840 return result;
3841 }
3842
3843 var state = { // compilation state
3844 commandStack: [], // stack of commands as they were nested
3845 atBOL: true, // is the next character to process at BOL?
3846 indentLevel: function() {
3847 return Codie.indentStep * this.commandStack.length;
3848 }
3849 },
3850 code = '', // generated template function code
3851 vars = ['__p=[]'], // variables used by generated code
3852 name, match, result, i;
3853
3854 /* Initialize state. */
3855 for (name in Codie.commands) {
3856 if (Codie.commands[name].init) { Codie.commands[name].init(state); }
3857 }
3858
3859 /* Compile the template. */
3860 while ((match = /^([ \t]*)#([a-zA-Z_][a-zA-Z0-9_]*)(?:[ \t]+([^ \t\n][^\n]*))?[ \t]*(?:\n|$)|#\{([^}]*)\}/m.exec(template)) !== null) {
3861 code += pushRaw(template, match.index, state);
3862 result = match[2] !== undefined && match[2] !== ""
3863 ? compileCommand(state, match[1], match[2], match[3] || "") // #-command
3864 : compileExpr(state, match[4]); // #{...}
3865 code += result[0];
3866 vars = vars.concat(result[1]);
3867 template = template.substring(match.index + match[0].length);
3868 }
3869 code += pushRaw(template, template.length, state);
3870
3871 /* Check the final state. */
3872 if (state.commandStack.length > 0) { throw new Error("Missing #end."); }
3873
3874 /* Sanitize the list of variables used by commands. */
3875 vars.sort();
3876 for (i = 0; i < vars.length; i++) {
3877 if (vars[i] === vars[i - 1]) { vars.splice(i--, 1); }
3878 }
3879
3880 /* Create the resulting function. */
3881 return new Function("__v", [
3882 '__v=__v||{};',
3883 'var ' + vars.join(',') + ';',
3884 'with(__v){',
3885 code,
3886 'return __p.join("").replace(/^\\n+|\\n+$/g,"");};'
3887 ].join(''));
3888 }
3889 };
3890
3891 return Codie;
3892
3893 })();
3894
3895 var templates = (function() {
3896 var name,
3897 templates = {},
3898 sources = {
3899 grammar: [
3900 '(function(){',
3901 ' /*',
3902 ' * Generated by PEG.js 0.7.0.',
3903 ' *',
3904 ' * http://pegjs.majda.cz/',
3905 ' */',
3906 ' ',
3907 /* This needs to be in sync with |quote| in utils.js. */
3908 ' function quote(s) {',
3909 ' /*',
3910 ' * ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a',
3911 ' * string literal except for the closing quote character, backslash,',
3912 ' * carriage return, line separator, paragraph separator, and line feed.',
3913 ' * Any character may appear in the form of an escape sequence.',
3914 ' *',
3915 ' * For portability, we also escape escape all control and non-ASCII',
3916 ' * characters. Note that "\\0" and "\\v" escape sequences are not used',
3917 ' * because JSHint does not like the first and IE the second.',
3918 ' */',
3919 ' return \'"\' + s',
3920 ' .replace(/\\\\/g, \'\\\\\\\\\') // backslash',
3921 ' .replace(/"/g, \'\\\\"\') // closing quote character',
3922 ' .replace(/\\x08/g, \'\\\\b\') // backspace',
3923 ' .replace(/\\t/g, \'\\\\t\') // horizontal tab',
3924 ' .replace(/\\n/g, \'\\\\n\') // line feed',
3925 ' .replace(/\\f/g, \'\\\\f\') // form feed',
3926 ' .replace(/\\r/g, \'\\\\r\') // carriage return',
3927 ' .replace(/[\\x00-\\x07\\x0B\\x0E-\\x1F\\x80-\\uFFFF]/g, escape)',
3928 ' + \'"\';',
3929 ' }',
3930 ' ',
3931 ' var result = {',
3932 ' /*',
3933 ' * Parses the input with a generated parser. If the parsing is successfull,',
3934 ' * returns a value explicitly or implicitly specified by the grammar from',
3935 ' * which the parser was generated (see |PEG.buildParser|). If the parsing is',
3936 ' * unsuccessful, throws |PEG.parser.SyntaxError| describing the error.',
3937 ' */',
3938 ' parse: function(input, startRule) {',
3939 ' var parseFunctions = {',
3940 ' #for rule in node.rules',
3941 ' #{string(rule.name) + ": parse_" + rule.name + (rule !== node.rules[node.rules.length - 1] ? "," : "")}',
3942 ' #end',
3943 ' };',
3944 ' ',
3945 ' if (startRule !== undefined) {',
3946 ' if (parseFunctions[startRule] === undefined) {',
3947 ' throw new Error("Invalid rule name: " + quote(startRule) + ".");',
3948 ' }',
3949 ' } else {',
3950 ' startRule = #{string(node.startRule)};',
3951 ' }',
3952 ' ',
3953 ' #{posInit("pos")};',
3954 ' var reportFailures = 0;', // 0 = report, anything > 0 = do not report
3955 ' #{posInit("rightmostFailuresPos")};',
3956 ' var rightmostFailuresExpected = [];',
3957 ' #if options.cache',
3958 ' var cache = {};',
3959 ' #end',
3960 ' ',
3961 /* This needs to be in sync with |padLeft| in utils.js. */
3962 ' function padLeft(input, padding, length) {',
3963 ' var result = input;',
3964 ' ',
3965 ' var padLength = length - input.length;',
3966 ' for (var i = 0; i < padLength; i++) {',
3967 ' result = padding + result;',
3968 ' }',
3969 ' ',
3970 ' return result;',
3971 ' }',
3972 ' ',
3973 /* This needs to be in sync with |escape| in utils.js. */
3974 ' function escape(ch) {',
3975 ' var charCode = ch.charCodeAt(0);',
3976 ' var escapeChar;',
3977 ' var length;',
3978 ' ',
3979 ' if (charCode <= 0xFF) {',
3980 ' escapeChar = \'x\';',
3981 ' length = 2;',
3982 ' } else {',
3983 ' escapeChar = \'u\';',
3984 ' length = 4;',
3985 ' }',
3986 ' ',
3987 ' return \'\\\\\' + escapeChar + padLeft(charCode.toString(16).toUpperCase(), \'0\', length);',
3988 ' }',
3989 ' ',
3990 ' #if options.trackLineAndColumn',
3991 ' function clone(object) {',
3992 ' var result = {};',
3993 ' for (var key in object) {',
3994 ' result[key] = object[key];',
3995 ' }',
3996 ' return result;',
3997 ' }',
3998 ' ',
3999 ' function advance(pos, n) {',
4000 ' var endOffset = pos.offset + n;',
4001 ' ',
4002 ' for (var offset = pos.offset; offset < endOffset; offset++) {',
4003 ' var ch = input.charAt(offset);',
4004 ' if (ch === "\\n") {',
4005 ' if (!pos.seenCR) { pos.line++; }',
4006 ' pos.column = 1;',
4007 ' pos.seenCR = false;',
4008 ' } else if (ch === "\\r" || ch === "\\u2028" || ch === "\\u2029") {',
4009 ' pos.line++;',
4010 ' pos.column = 1;',
4011 ' pos.seenCR = true;',
4012 ' } else {',
4013 ' pos.column++;',
4014 ' pos.seenCR = false;',
4015 ' }',
4016 ' }',
4017 ' ',
4018 ' pos.offset += n;',
4019 ' }',
4020 ' ',
4021 ' #end',
4022 ' function matchFailed(failure) {',
4023 ' if (#{posOffset("pos")} < #{posOffset("rightmostFailuresPos")}) {',
4024 ' return;',
4025 ' }',
4026 ' ',
4027 ' if (#{posOffset("pos")} > #{posOffset("rightmostFailuresPos")}) {',
4028 ' rightmostFailuresPos = #{posClone("pos")};',
4029 ' rightmostFailuresExpected = [];',
4030 ' }',
4031 ' ',
4032 ' rightmostFailuresExpected.push(failure);',
4033 ' }',
4034 ' ',
4035 ' #for rule in node.rules',
4036 ' #block emit(rule)',
4037 ' ',
4038 ' #end',
4039 ' ',
4040 ' function cleanupExpected(expected) {',
4041 ' expected.sort();',
4042 ' ',
4043 ' var lastExpected = null;',
4044 ' var cleanExpected = [];',
4045 ' for (var i = 0; i < expected.length; i++) {',
4046 ' if (expected[i] !== lastExpected) {',
4047 ' cleanExpected.push(expected[i]);',
4048 ' lastExpected = expected[i];',
4049 ' }',
4050 ' }',
4051 ' return cleanExpected;',
4052 ' }',
4053 ' ',
4054 ' #if !options.trackLineAndColumn',
4055 ' function computeErrorPosition() {',
4056 ' /*',
4057 ' * The first idea was to use |String.split| to break the input up to the',
4058 ' * error position along newlines and derive the line and column from',
4059 ' * there. However IE\'s |split| implementation is so broken that it was',
4060 ' * enough to prevent it.',
4061 ' */',
4062 ' ',
4063 ' var line = 1;',
4064 ' var column = 1;',
4065 ' var seenCR = false;',
4066 ' ',
4067 ' for (var i = 0; i < Math.max(pos, rightmostFailuresPos); i++) {',
4068 ' var ch = input.charAt(i);',
4069 ' if (ch === "\\n") {',
4070 ' if (!seenCR) { line++; }',
4071 ' column = 1;',
4072 ' seenCR = false;',
4073 ' } else if (ch === "\\r" || ch === "\\u2028" || ch === "\\u2029") {',
4074 ' line++;',
4075 ' column = 1;',
4076 ' seenCR = true;',
4077 ' } else {',
4078 ' column++;',
4079 ' seenCR = false;',
4080 ' }',
4081 ' }',
4082 ' ',
4083 ' return { line: line, column: column };',
4084 ' }',
4085 ' #end',
4086 ' ',
4087 ' #if node.initializer',
4088 ' #block emit(node.initializer)',
4089 ' #end',
4090 ' ',
4091 ' var result = parseFunctions[startRule]();',
4092 ' ',
4093 ' /*',
4094 ' * The parser is now in one of the following three states:',
4095 ' *',
4096 ' * 1. The parser successfully parsed the whole input.',
4097 ' *',
4098 ' * - |result !== null|',
4099 ' * - |#{posOffset("pos")} === input.length|',
4100 ' * - |rightmostFailuresExpected| may or may not contain something',
4101 ' *',
4102 ' * 2. The parser successfully parsed only a part of the input.',
4103 ' *',
4104 ' * - |result !== null|',
4105 ' * - |#{posOffset("pos")} < input.length|',
4106 ' * - |rightmostFailuresExpected| may or may not contain something',
4107 ' *',
4108 ' * 3. The parser did not successfully parse any part of the input.',
4109 ' *',
4110 ' * - |result === null|',
4111 ' * - |#{posOffset("pos")} === 0|',
4112 ' * - |rightmostFailuresExpected| contains at least one failure',
4113 ' *',
4114 ' * All code following this comment (including called functions) must',
4115 ' * handle these states.',
4116 ' */',
4117 ' if (result === null || #{posOffset("pos")} !== input.length) {',
4118 ' var offset = Math.max(#{posOffset("pos")}, #{posOffset("rightmostFailuresPos")});',
4119 ' var found = offset < input.length ? input.charAt(offset) : null;',
4120 ' #if options.trackLineAndColumn',
4121 ' var errorPosition = #{posOffset("pos")} > #{posOffset("rightmostFailuresPos")} ? pos : rightmostFailuresPos;',
4122 ' #else',
4123 ' var errorPosition = computeErrorPosition();',
4124 ' #end',
4125 ' ',
4126 ' throw new this.SyntaxError(',
4127 ' cleanupExpected(rightmostFailuresExpected),',
4128 ' found,',
4129 ' offset,',
4130 ' errorPosition.line,',
4131 ' errorPosition.column',
4132 ' );',
4133 ' }',
4134 ' ',
4135 ' return result;',
4136 ' },',
4137 ' ',
4138 ' /* Returns the parser source code. */',
4139 ' toSource: function() { return this._source; }',
4140 ' };',
4141 ' ',
4142 ' /* Thrown when a parser encounters a syntax error. */',
4143 ' ',
4144 ' result.SyntaxError = function(expected, found, offset, line, column) {',
4145 ' function buildMessage(expected, found) {',
4146 ' var expectedHumanized, foundHumanized;',
4147 ' ',
4148 ' switch (expected.length) {',
4149 ' case 0:',
4150 ' expectedHumanized = "end of input";',
4151 ' break;',
4152 ' case 1:',
4153 ' expectedHumanized = expected[0];',
4154 ' break;',
4155 ' default:',
4156 ' expectedHumanized = expected.slice(0, expected.length - 1).join(", ")',
4157 ' + " or "',
4158 ' + expected[expected.length - 1];',
4159 ' }',
4160 ' ',
4161 ' foundHumanized = found ? quote(found) : "end of input";',
4162 ' ',
4163 ' return "Expected " + expectedHumanized + " but " + foundHumanized + " found.";',
4164 ' }',
4165 ' ',
4166 ' this.name = "SyntaxError";',
4167 ' this.expected = expected;',
4168 ' this.found = found;',
4169 ' this.message = buildMessage(expected, found);',
4170 ' this.offset = offset;',
4171 ' this.line = line;',
4172 ' this.column = column;',
4173 ' };',
4174 ' ',
4175 ' result.SyntaxError.prototype = Error.prototype;',
4176 ' ',
4177 ' return result;',
4178 '})()'
4179 ],
4180 rule: [
4181 'function parse_#{node.name}() {',
4182 ' #if options.cache',
4183 ' var cacheKey = "#{node.name}@" + #{posOffset("pos")};',
4184 ' var cachedResult = cache[cacheKey];',
4185 ' if (cachedResult) {',
4186 ' pos = #{posClone("cachedResult.nextPos")};',
4187 ' return cachedResult.result;',
4188 ' }',
4189 ' ',
4190 ' #end',
4191 ' #if node.resultVars.length > 0',
4192 ' var #{node.resultVars.join(", ")};',
4193 ' #end',
4194 ' #if node.posVars.length > 0',
4195 ' var #{node.posVars.join(", ")};',
4196 ' #end',
4197 ' ',
4198 ' #if node.displayName !== null',
4199 ' reportFailures++;',
4200 ' #end',
4201 ' #block emit(node.expression)',
4202 ' #if node.displayName !== null',
4203 ' reportFailures--;',
4204 ' if (reportFailures === 0 && #{node.resultVar} === null) {',
4205 ' matchFailed(#{string(node.displayName)});',
4206 ' }',
4207 ' #end',
4208 ' #if options.cache',
4209 ' ',
4210 ' cache[cacheKey] = {',
4211 ' nextPos: #{posClone("pos")},',
4212 ' result: #{node.resultVar}',
4213 ' };',
4214 ' #end',
4215 ' return #{node.resultVar};',
4216 '}'
4217 ],
4218 choice: [
4219 '#block emit(alternative)',
4220 '#block nextAlternativesCode'
4221 ],
4222 "choice.next": [
4223 'if (#{node.resultVar} === null) {',
4224 ' #block code',
4225 '}'
4226 ],
4227 sequence: [
4228 '#{posSave(node)};',
4229 '#block code'
4230 ],
4231 "sequence.iteration": [
4232 '#block emit(element)',
4233 'if (#{element.resultVar} !== null) {',
4234 ' #block code',
4235 '} else {',
4236 ' #{node.resultVar} = null;',
4237 ' #{posRestore(node)};',
4238 '}'
4239 ],
4240 "sequence.inner": [
4241 '#{node.resultVar} = [#{pluck(node.elements, "resultVar").join(", ")}];'
4242 ],
4243 simple_and: [
4244 '#{posSave(node)};',
4245 'reportFailures++;',
4246 '#block emit(node.expression)',
4247 'reportFailures--;',
4248 'if (#{node.resultVar} !== null) {',
4249 ' #{node.resultVar} = "";',
4250 ' #{posRestore(node)};',
4251 '} else {',
4252 ' #{node.resultVar} = null;',
4253 '}'
4254 ],
4255 simple_not: [
4256 '#{posSave(node)};',
4257 'reportFailures++;',
4258 '#block emit(node.expression)',
4259 'reportFailures--;',
4260 'if (#{node.resultVar} === null) {',
4261 ' #{node.resultVar} = "";',
4262 '} else {',
4263 ' #{node.resultVar} = null;',
4264 ' #{posRestore(node)};',
4265 '}'
4266 ],
4267 semantic_and: [
4268 '#{node.resultVar} = (function(#{(options.trackLineAndColumn ? ["offset", "line", "column"] : ["offset"]).concat(keys(node.params)).join(", ")}) {#{node.code}})(#{(options.trackLineAndColumn ? ["pos.offset", "pos.line", "pos.column"] : ["pos"]).concat(values(node.params)).join(", ")}) ? "" : null;'
4269 ],
4270 semantic_not: [
4271 '#{node.resultVar} = (function(#{(options.trackLineAndColumn ? ["offset", "line", "column"] : ["offset"]).concat(keys(node.params)).join(", ")}) {#{node.code}})(#{(options.trackLineAndColumn ? ["pos.offset", "pos.line", "pos.column"] : ["pos"]).concat(values(node.params)).join(", ")}) ? null : "";'
4272 ],
4273 optional: [
4274 '#block emit(node.expression)',
4275 '#{node.resultVar} = #{node.resultVar} !== null ? #{node.resultVar} : "";'
4276 ],
4277 zero_or_more: [
4278 '#{node.resultVar} = [];',
4279 '#block emit(node.expression)',
4280 'while (#{node.expression.resultVar} !== null) {',
4281 ' #{node.resultVar}.push(#{node.expression.resultVar});',
4282 ' #block emit(node.expression)',
4283 '}'
4284 ],
4285 one_or_more: [
4286 '#block emit(node.expression)',
4287 'if (#{node.expression.resultVar} !== null) {',
4288 ' #{node.resultVar} = [];',
4289 ' while (#{node.expression.resultVar} !== null) {',
4290 ' #{node.resultVar}.push(#{node.expression.resultVar});',
4291 ' #block emit(node.expression)',
4292 ' }',
4293 '} else {',
4294 ' #{node.resultVar} = null;',
4295 '}'
4296 ],
4297 action: [
4298 '#{posSave(node)};',
4299 '#block emit(node.expression)',
4300 'if (#{node.resultVar} !== null) {',
4301 ' #{node.resultVar} = (function(#{(options.trackLineAndColumn ? ["offset", "line", "column"] : ["offset"]).concat(keys(node.params)).join(", ")}) {#{node.code}})(#{(options.trackLineAndColumn ? [node.posVar + ".offset", node.posVar + ".line", node.posVar + ".column"] : [node.posVar]).concat(values(node.params)).join(", ")});',
4302 '}',
4303 'if (#{node.resultVar} === null) {',
4304 ' #{posRestore(node)};',
4305 '}'
4306 ],
4307 rule_ref: [
4308 '#{node.resultVar} = parse_#{node.name}();'
4309 ],
4310 literal: [
4311 '#if node.value.length === 0',
4312 ' #{node.resultVar} = "";',
4313 '#else',
4314 ' #if !node.ignoreCase',
4315 ' #if node.value.length === 1',
4316 ' if (input.charCodeAt(#{posOffset("pos")}) === #{node.value.charCodeAt(0)}) {',
4317 ' #else',
4318 ' if (input.substr(#{posOffset("pos")}, #{node.value.length}) === #{string(node.value)}) {',
4319 ' #end',
4320 ' #else',
4321 /*
4322 * One-char literals are not optimized when case-insensitive
4323 * matching is enabled. This is because there is no simple way to
4324 * lowercase a character code that works for character outside ASCII
4325 * letters. Moreover, |toLowerCase| can change string length,
4326 * meaning the result of lowercasing a character can be more
4327 * characters.
4328 */
4329 ' if (input.substr(#{posOffset("pos")}, #{node.value.length}).toLowerCase() === #{string(node.value.toLowerCase())}) {',
4330 ' #end',
4331 ' #if !node.ignoreCase',
4332 ' #{node.resultVar} = #{string(node.value)};',
4333 ' #else',
4334 ' #{node.resultVar} = input.substr(#{posOffset("pos")}, #{node.value.length});',
4335 ' #end',
4336 ' #{posAdvance(node.value.length)};',
4337 ' } else {',
4338 ' #{node.resultVar} = null;',
4339 ' if (reportFailures === 0) {',
4340 ' matchFailed(#{string(string(node.value))});',
4341 ' }',
4342 ' }',
4343 '#end'
4344 ],
4345 any: [
4346 'if (input.length > #{posOffset("pos")}) {',
4347 ' #{node.resultVar} = input.charAt(#{posOffset("pos")});',
4348 ' #{posAdvance(1)};',
4349 '} else {',
4350 ' #{node.resultVar} = null;',
4351 ' if (reportFailures === 0) {',
4352 ' matchFailed("any character");',
4353 ' }',
4354 '}'
4355 ],
4356 "class": [
4357 'if (#{regexp}.test(input.charAt(#{posOffset("pos")}))) {',
4358 ' #{node.resultVar} = input.charAt(#{posOffset("pos")});',
4359 ' #{posAdvance(1)};',
4360 '} else {',
4361 ' #{node.resultVar} = null;',
4362 ' if (reportFailures === 0) {',
4363 ' matchFailed(#{string(node.rawText)});',
4364 ' }',
4365 '}'
4366 ]
4367 };
4368
4369 for (name in sources) {
4370 templates[name] = Codie.template(sources[name].join('\n'));
4371 }
4372
4373 return templates;
4374 })();
4375
4376 function fill(name, vars) {
4377 vars.string = quote;
4378 vars.pluck = pluck;
4379 vars.keys = keys;
4380 vars.values = values;
4381 vars.emit = emit;
4382 vars.options = options;
4383
4384 /* Position-handling macros */
4385 if (options.trackLineAndColumn) {
4386 vars.posInit = function(name) {
4387 return "var "
4388 + name
4389 + " = "
4390 + "{ offset: 0, line: 1, column: 1, seenCR: false }";
4391 };
4392 vars.posClone = function(name) { return "clone(" + name + ")"; };
4393 vars.posOffset = function(name) { return name + ".offset"; };
4394
4395 vars.posAdvance = function(n) { return "advance(pos, " + n + ")"; };
4396 } else {
4397 vars.posInit = function(name) { return "var " + name + " = 0"; };
4398 vars.posClone = function(name) { return name; };
4399 vars.posOffset = function(name) { return name; };
4400
4401 vars.posAdvance = function(n) {
4402 return n === 1 ? "pos++" : "pos += " + n;
4403 };
4404 }
4405 vars.posSave = function(node) {
4406 return node.posVar + " = " + vars.posClone("pos");
4407 };
4408 vars.posRestore = function(node) {
4409 return "pos" + " = " + vars.posClone(node.posVar);
4410 };
4411
4412 return templates[name](vars);
4413 }
4414
4415 function emitSimple(name) {
4416 return function(node) { return fill(name, { node: node }); };
4417 }
4418
4419 var emit = buildNodeVisitor({
4420 grammar: emitSimple("grammar"),
4421
4422 initializer: function(node) { return node.code; },
4423
4424 rule: emitSimple("rule"),
4425
4426 /*
4427 * The contract for all code fragments generated by the following functions
4428 * is as follows.
4429 *
4430 * The code fragment tries to match a part of the input starting with the
4431 * position indicated in |pos|. That position may point past the end of the
4432 * input.
4433 *
4434 * * If the code fragment matches the input, it advances |pos| to point to
4435 * the first chracter following the matched part of the input and sets
4436 * variable with a name stored in |node.resultVar| to an appropriate
4437 * value. This value is always non-|null|.
4438 *
4439 * * If the code fragment does not match the input, it returns with |pos|
4440 * set to the original value and it sets a variable with a name stored in
4441 * |node.resultVar| to |null|.
4442 *
4443 * The code can use variables with names stored in |resultVar| and |posVar|
4444 * properties of the current node's subnodes. It can't use any other
4445 * variables.
4446 */
4447
4448 choice: function(node) {
4449 var code, nextAlternativesCode;
4450
4451 for (var i = node.alternatives.length - 1; i >= 0; i--) {
4452 nextAlternativesCode = i !== node.alternatives.length - 1
4453 ? fill("choice.next", { node: node, code: code })
4454 : '';
4455 code = fill("choice", {
4456 alternative: node.alternatives[i],
4457 nextAlternativesCode: nextAlternativesCode
4458 });
4459 }
4460
4461 return code;
4462 },
4463
4464 sequence: function(node) {
4465 var code = fill("sequence.inner", { node: node });
4466
4467 for (var i = node.elements.length - 1; i >= 0; i--) {
4468 code = fill("sequence.iteration", {
4469 node: node,
4470 element: node.elements[i],
4471 code: code
4472 });
4473 }
4474
4475 return fill("sequence", { node: node, code: code });
4476 },
4477
4478 labeled: function(node) { return emit(node.expression); },
4479
4480 simple_and: emitSimple("simple_and"),
4481 simple_not: emitSimple("simple_not"),
4482 semantic_and: emitSimple("semantic_and"),
4483 semantic_not: emitSimple("semantic_not"),
4484 optional: emitSimple("optional"),
4485 zero_or_more: emitSimple("zero_or_more"),
4486 one_or_more: emitSimple("one_or_more"),
4487 action: emitSimple("action"),
4488 rule_ref: emitSimple("rule_ref"),
4489 literal: emitSimple("literal"),
4490 any: emitSimple("any"),
4491
4492 "class": function(node) {
4493 var regexp;
4494
4495 if (node.parts.length > 0) {
4496 regexp = '/^['
4497 + (node.inverted ? '^' : '')
4498 + map(node.parts, function(part) {
4499 return part instanceof Array
4500 ? quoteForRegexpClass(part[0])
4501 + '-'
4502 + quoteForRegexpClass(part[1])
4503 : quoteForRegexpClass(part);
4504 }).join('')
4505 + ']/' + (node.ignoreCase ? 'i' : '');
4506 } else {
4507 /*
4508 * Stupid IE considers regexps /[]/ and /[^]/ syntactically invalid, so
4509 * we translate them into euqivalents it can handle.
4510 */
4511 regexp = node.inverted ? '/^[\\S\\s]/' : '/^(?!)/';
4512 }
4513
4514 return fill("class", { node: node, regexp: regexp });
4515 }
4516 });
4517
4518 return emit(ast);
4519 };
4520
4521 return PEG;
4522
4523 })();
4524
4525 if (typeof module !== "undefined") {
4526 module.exports = PEG;
4527 }
57 module.exports = peg;
0 "use strict";
1
2 /* Array utilities. */
3 var arrays = {
4 range: function(start, stop) {
5 var length = stop - start,
6 result = new Array(length),
7 i, j;
8
9 for (i = 0, j = start; i < length; i++, j++) {
10 result[i] = j;
11 }
12
13 return result;
14 },
15
16 find: function(array, valueOrPredicate) {
17 var length = array.length, i;
18
19 if (typeof valueOrPredicate === "function") {
20 for (i = 0; i < length; i++) {
21 if (valueOrPredicate(array[i])) {
22 return array[i];
23 }
24 }
25 } else {
26 for (i = 0; i < length; i++) {
27 if (array[i] === valueOrPredicate) {
28 return array[i];
29 }
30 }
31 }
32 },
33
34 indexOf: function(array, valueOrPredicate) {
35 var length = array.length, i;
36
37 if (typeof valueOrPredicate === "function") {
38 for (i = 0; i < length; i++) {
39 if (valueOrPredicate(array[i])) {
40 return i;
41 }
42 }
43 } else {
44 for (i = 0; i < length; i++) {
45 if (array[i] === valueOrPredicate) {
46 return i;
47 }
48 }
49 }
50
51 return -1;
52 },
53
54 contains: function(array, valueOrPredicate) {
55 return arrays.indexOf(array, valueOrPredicate) !== -1;
56 },
57
58 each: function(array, iterator) {
59 var length = array.length, i;
60
61 for (i = 0; i < length; i++) {
62 iterator(array[i], i);
63 }
64 },
65
66 map: function(array, iterator) {
67 var length = array.length,
68 result = new Array(length),
69 i;
70
71 for (i = 0; i < length; i++) {
72 result[i] = iterator(array[i], i);
73 }
74
75 return result;
76 },
77
78 pluck: function(array, key) {
79 return arrays.map(array, function (e) { return e[key]; });
80 },
81
82 every: function(array, predicate) {
83 var length = array.length, i;
84
85 for (i = 0; i < length; i++) {
86 if (!predicate(array[i])) {
87 return false;
88 }
89 }
90
91 return true;
92 },
93
94 some: function(array, predicate) {
95 var length = array.length, i;
96
97 for (i = 0; i < length; i++) {
98 if (predicate(array[i])) {
99 return true;
100 }
101 }
102
103 return false;
104 }
105 };
106
107 module.exports = arrays;
0 "use strict";
1
2 /* Class utilities */
3 var classes = {
4 subclass: function(child, parent) {
5 function ctor() { this.constructor = child; }
6 ctor.prototype = parent.prototype;
7 child.prototype = new ctor();
8 }
9 };
10
11 module.exports = classes;
0 "use strict";
1
2 /* Object utilities. */
3 var objects = {
4 keys: function(object) {
5 var result = [], key;
6
7 for (key in object) {
8 if (object.hasOwnProperty(key)) {
9 result.push(key);
10 }
11 }
12
13 return result;
14 },
15
16 values: function(object) {
17 var result = [], key;
18
19 for (key in object) {
20 if (object.hasOwnProperty(key)) {
21 result.push(object[key]);
22 }
23 }
24
25 return result;
26 },
27
28 clone: function(object) {
29 var result = {}, key;
30
31 for (key in object) {
32 if (object.hasOwnProperty(key)) {
33 result[key] = object[key];
34 }
35 }
36
37 return result;
38 },
39
40 defaults: function(object, defaults) {
41 var key;
42
43 for (key in defaults) {
44 if (defaults.hasOwnProperty(key)) {
45 if (!(key in object)) {
46 object[key] = defaults[key];
47 }
48 }
49 }
50 }
51 };
52
53 module.exports = objects;
00 {
1 "name": "pegjs",
2 "version": "@VERSION",
1 "name": "pegjs",
2 "version": "0.10.0",
33 "description": "Parser generator for JavaScript",
4 "homepage": "http://pegjs.majda.cz/",
5 "author": {
6 "name": "David Majda",
7 "email": "david@majda.cz",
8 "url": "http://majda.cz/"
9 },
10 "main": "lib/peg",
11 "bin": "bin/pegjs",
12 "repository": {
13 "type": "git",
14 "url": "http://github.com/dmajda/pegjs.git"
4 "keywords": [
5 "parser generator",
6 "PEG"
7 ],
8 "homepage": "http://pegjs.org/",
9 "bugs": "https://github.com/pegjs/pegjs/issues",
10 "license": "MIT",
11 "author": "David Majda <david@majda.cz> (http://majda.cz/)",
12 "files": [
13 "CHANGELOG.md",
14 "LICENSE",
15 "README.md",
16 "VERSION",
17 "bin/pegjs",
18 "examples/arithmetics.pegjs",
19 "examples/css.pegjs",
20 "examples/javascript.pegjs",
21 "examples/json.pegjs",
22 "lib/compiler/asts.js",
23 "lib/compiler/index.js",
24 "lib/compiler/js.js",
25 "lib/compiler/opcodes.js",
26 "lib/compiler/passes/generate-bytecode.js",
27 "lib/compiler/passes/generate-js.js",
28 "lib/compiler/passes/remove-proxy-rules.js",
29 "lib/compiler/passes/report-duplicate-labels.js",
30 "lib/compiler/passes/report-duplicate-rules.js",
31 "lib/compiler/passes/report-infinite-recursion.js",
32 "lib/compiler/passes/report-infinite-repetition.js",
33 "lib/compiler/passes/report-undefined-rules.js",
34 "lib/compiler/visitor.js",
35 "lib/grammar-error.js",
36 "lib/parser.js",
37 "lib/peg.js",
38 "lib/utils/arrays.js",
39 "lib/utils/classes.js",
40 "lib/utils/objects.js",
41 "package.json"
42 ],
43 "main": "lib/peg",
44 "bin": "bin/pegjs",
45 "repository": "pegjs/pegjs",
46 "scripts": {
47 "test": "make lint && make spec"
1548 },
1649 "devDependencies": {
17 "uglify-js": ">= 1.2.4",
18 "jshint": ">= 0.5.5"
50 "browserify": "13.1.0",
51 "eslint": "2.13.1",
52 "http-server": "0.9.0",
53 "jasmine-node": "1.14.5",
54 "uglify-js": "2.7.0"
1955 },
2056 "engines": {
21 "node": ">= 0.6.6"
57 "node": ">=0.10"
2258 }
2359 }
0 {
1 "env": {
2 "jasmine": true
3 }
4 }
0 PEG.js Spec Suite
1 =================
2
3 This is the PEG.js spec suite. It ensures PEG.js works correctly. All specs
4 should always pass on all supported platforms.
5
6 Running in Node.js
7 ------------------
8
9 All commands in the following steps need to be executed in PEG.js root directory
10 (one level up from this one).
11
12 1. Install all PEG.js dependencies, including development ones:
13
14 ```console
15 $ npm install
16 ```
17
18 2. Execute the spec suite:
19
20 ```console
21 $ make spec
22 ```
23
24 3. Watch the specs pass (or fail).
25
26 Running in the Browser
27 ----------------------
28
29 All commands in the following steps need to be executed in PEG.js root directory
30 (one level up from this one).
31
32 1. Make sure you have Node.js installed.
33
34 2. Install all PEG.js dependencies, including development ones:
35
36 ```console
37 $ npm install
38 ```
39
40 3. Build browser version of PEG.js:
41
42 ```console
43 $ make browser
44 ```
45
46 4. Serve PEG.js root directory using a web server:
47
48 ```console
49 $ node_modules/.bin/http-server
50 ```
51
52 5. Point your browser to the [spec suite](http://localhost:8080/spec/index.html).
53
54 6. Watch the specs pass (or fail).
0 /* eslint no-console: 0 */
1 /* global peg, console */
2
3 "use strict";
4
5 describe("generated parser API", function() {
6 describe("parse", function() {
7 it("parses input", function() {
8 var parser = peg.generate('start = "a"');
9
10 expect(parser.parse("a")).toBe("a");
11 });
12
13 it("throws an exception on syntax error", function() {
14 var parser = peg.generate('start = "a"');
15
16 expect(function() { parser.parse("b"); }).toThrow();
17 });
18
19 describe("start rule", function() {
20 var parser = peg.generate([
21 'a = "x" { return "a"; }',
22 'b = "x" { return "b"; }',
23 'c = "x" { return "c"; }'
24 ].join("\n"), { allowedStartRules: ["b", "c"] });
25
26 describe("when |startRule| is not set", function() {
27 it("starts parsing from the first allowed rule", function() {
28 expect(parser.parse("x")).toBe("b");
29 });
30 });
31
32 describe("when |startRule| is set to an allowed rule", function() {
33 it("starts parsing from specified rule", function() {
34 expect(parser.parse("x", { startRule: "b" })).toBe("b");
35 expect(parser.parse("x", { startRule: "c" })).toBe("c");
36 });
37 });
38
39 describe("when |startRule| is set to a disallowed start rule", function() {
40 it("throws an exception", function() {
41 expect(
42 function() { parser.parse("x", { startRule: "a" }); }
43 ).toThrow();
44 });
45 });
46 });
47
48 describe("tracing", function() {
49 var parser = peg.generate([
50 'start = a / b',
51 'a = "a"',
52 'b = "b"'
53 ].join("\n"), { trace: true });
54
55 describe("default tracer", function() {
56 it("traces using console.log (if console is defined)", function() {
57 if (typeof console === "object") {
58 spyOn(console, "log");
59 }
60
61 parser.parse("b");
62
63 if (typeof console === "object") {
64 expect(console.log).toHaveBeenCalledWith("1:1-1:1 rule.enter start");
65 expect(console.log).toHaveBeenCalledWith("1:1-1:1 rule.enter a");
66 expect(console.log).toHaveBeenCalledWith("1:1-1:1 rule.fail a");
67 expect(console.log).toHaveBeenCalledWith("1:1-1:1 rule.enter b");
68 expect(console.log).toHaveBeenCalledWith("1:1-1:2 rule.match b");
69 expect(console.log).toHaveBeenCalledWith("1:1-1:2 rule.match start");
70 }
71 });
72 });
73
74 describe("custom tracers", function() {
75 describe("trace", function() {
76 it("receives tracing events", function() {
77 var tracer = jasmine.createSpyObj("tracer", ["trace"]);
78
79 parser.parse("b", { tracer: tracer });
80
81 expect(tracer.trace).toHaveBeenCalledWith({
82 type: "rule.enter",
83 rule: "start",
84 location: {
85 start: { offset: 0, line: 1, column: 1 },
86 end: { offset: 0, line: 1, column: 1 }
87 }
88 });
89 expect(tracer.trace).toHaveBeenCalledWith({
90 type: "rule.enter",
91 rule: "a",
92 location: {
93 start: { offset: 0, line: 1, column: 1 },
94 end: { offset: 0, line: 1, column: 1 }
95 }
96 });
97 expect(tracer.trace).toHaveBeenCalledWith({
98 type: "rule.fail",
99 rule: "a",
100 location: {
101 start: { offset: 0, line: 1, column: 1 },
102 end: { offset: 0, line: 1, column: 1 }
103 }
104 });
105 expect(tracer.trace).toHaveBeenCalledWith({
106 type: "rule.enter",
107 rule: "b",
108 location: {
109 start: { offset: 0, line: 1, column: 1 },
110 end: { offset: 0, line: 1, column: 1 }
111 }
112 });
113 expect(tracer.trace).toHaveBeenCalledWith({
114 type: "rule.match",
115 rule: "b",
116 result: "b",
117 location: {
118 start: { offset: 0, line: 1, column: 1 },
119 end: { offset: 1, line: 1, column: 2 }
120 }
121 });
122 expect(tracer.trace).toHaveBeenCalledWith({
123 type: "rule.match",
124 rule: "start",
125 result: "b",
126 location: {
127 start: { offset: 0, line: 1, column: 1 },
128 end: { offset: 1, line: 1, column: 2 }
129 }
130 });
131 });
132 });
133 });
134 });
135
136 it("accepts custom options", function() {
137 var parser = peg.generate('start = "a"');
138
139 parser.parse("a", { foo: 42 });
140 });
141 });
142 });
0 /* global peg */
1
2 "use strict";
3
4 describe("PEG.js API", function() {
5 describe("generate", function() {
6 it("generates a parser", function() {
7 var parser = peg.generate('start = "a"');
8
9 expect(typeof parser).toBe("object");
10 expect(parser.parse("a")).toBe("a");
11 });
12
13 it("throws an exception on syntax error", function() {
14 expect(function() { peg.generate('start = @'); }).toThrow();
15 });
16
17 it("throws an exception on semantic error", function() {
18 expect(function() { peg.generate('start = undefined'); }).toThrow();
19 });
20
21 describe("allowed start rules", function() {
22 var grammar = [
23 'a = "x"',
24 'b = "x"',
25 'c = "x"'
26 ].join("\n");
27
28 /*
29 * The |allowedStartRules| option is implemented separately for each
30 * optimization mode, so we need to test it in both.
31 */
32
33 describe("when optimizing for parsing speed", function() {
34 describe("when |allowedStartRules| is not set", function() {
35 it("generated parser can start only from the first rule", function() {
36 var parser = peg.generate(grammar, { optimize: "speed" });
37
38 expect(parser.parse("x", { startRule: "a" })).toBe("x");
39 expect(
40 function() { parser.parse("x", { startRule: "b" }); }
41 ).toThrow();
42 expect(
43 function() { parser.parse("x", { startRule: "c" }); }
44 ).toThrow();
45 });
46 });
47
48 describe("when |allowedStartRules| is set", function() {
49 it("generated parser can start only from specified rules", function() {
50 var parser = peg.generate(grammar, {
51 optimize: "speed",
52 allowedStartRules: ["b", "c"]
53 });
54
55 expect(
56 function() { parser.parse("x", { startRule: "a" }); }
57 ).toThrow();
58 expect(parser.parse("x", { startRule: "b" })).toBe("x");
59 expect(parser.parse("x", { startRule: "c" })).toBe("x");
60 });
61 });
62 });
63
64 describe("when optimizing for code size", function() {
65 describe("when |allowedStartRules| is not set", function() {
66 it("generated parser can start only from the first rule", function() {
67 var parser = peg.generate(grammar, { optimize: "size" });
68
69 expect(parser.parse("x", { startRule: "a" })).toBe("x");
70 expect(
71 function() { parser.parse("x", { startRule: "b" }); }
72 ).toThrow();
73 expect(
74 function() { parser.parse("x", { startRule: "c" }); }
75 ).toThrow();
76 });
77 });
78
79 describe("when |allowedStartRules| is set", function() {
80 it("generated parser can start only from specified rules", function() {
81 var parser = peg.generate(grammar, {
82 optimize: "size",
83 allowedStartRules: ["b", "c"]
84 });
85
86 expect(
87 function() { parser.parse("x", { startRule: "a" }); }
88 ).toThrow();
89 expect(parser.parse("x", { startRule: "b" })).toBe("x");
90 expect(parser.parse("x", { startRule: "c" })).toBe("x");
91 });
92 });
93 });
94 });
95
96 describe("intermediate results caching", function() {
97 var grammar = [
98 '{ var n = 0; }',
99 'start = (a "b") / (a "c") { return n; }',
100 'a = "a" { n++; }'
101 ].join("\n");
102
103 describe("when |cache| is not set", function() {
104 it("generated parser doesn't cache intermediate parse results", function() {
105 var parser = peg.generate(grammar);
106
107 expect(parser.parse("ac")).toBe(2);
108 });
109 });
110
111 describe("when |cache| is set to |false|", function() {
112 it("generated parser doesn't cache intermediate parse results", function() {
113 var parser = peg.generate(grammar, { cache: false });
114
115 expect(parser.parse("ac")).toBe(2);
116 });
117 });
118
119 describe("when |cache| is set to |true|", function() {
120 it("generated parser caches intermediate parse results", function() {
121 var parser = peg.generate(grammar, { cache: true });
122
123 expect(parser.parse("ac")).toBe(1);
124 });
125 });
126 });
127
128 describe("tracing", function() {
129 var grammar = 'start = "a"';
130
131 describe("when |trace| is not set", function() {
132 it("generated parser doesn't trace", function() {
133 var parser = peg.generate(grammar),
134 tracer = jasmine.createSpyObj("tracer", ["trace"]);
135
136 parser.parse("a", { tracer: tracer });
137
138 expect(tracer.trace).not.toHaveBeenCalled();
139 });
140 });
141
142 describe("when |trace| is set to |false|", function() {
143 it("generated parser doesn't trace", function() {
144 var parser = peg.generate(grammar, { trace: false }),
145 tracer = jasmine.createSpyObj("tracer", ["trace"]);
146
147 parser.parse("a", { tracer: tracer });
148
149 expect(tracer.trace).not.toHaveBeenCalled();
150 });
151 });
152
153 describe("when |trace| is set to |true|", function() {
154 it("generated parser traces", function() {
155 var parser = peg.generate(grammar, { trace: true }),
156 tracer = jasmine.createSpyObj("tracer", ["trace"]);
157
158 parser.parse("a", { tracer: tracer });
159
160 expect(tracer.trace).toHaveBeenCalled();
161 });
162 });
163 });
164
165 /*
166 * The |optimize| option isn't tested because there is no meaningful way to
167 * write the specs without turning this into a performance test.
168 */
169
170 describe("output", function() {
171 var grammar = 'start = "a"';
172
173 describe("when |output| is not set", function() {
174 it("returns generated parser object", function() {
175 var parser = peg.generate(grammar);
176
177 expect(typeof parser).toBe("object");
178 expect(parser.parse("a")).toBe("a");
179 });
180 });
181
182 describe("when |output| is set to |\"parser\"|", function() {
183 it("returns generated parser object", function() {
184 var parser = peg.generate(grammar, { output: "parser" });
185
186 expect(typeof parser).toBe("object");
187 expect(parser.parse("a")).toBe("a");
188 });
189 });
190
191 describe("when |output| is set to |\"source\"|", function() {
192 it("returns generated parser source code", function() {
193 var source = peg.generate(grammar, { output: "source" });
194
195 expect(typeof source).toBe("string");
196 expect(eval(source).parse("a")).toBe("a");
197 });
198 });
199 });
200
201 /*
202 * The |format|, |exportVars|, and |dependencies| options are not tested
203 * becasue there is no meaningful way to thest their effects without turning
204 * this into an integration test.
205 */
206
207 /* The |plugins| option is tested in plugin API specs. */
208
209 it("accepts custom options", function() {
210 peg.generate('start = "a"', { foo: 42 });
211 });
212 });
213 });
0 /* global peg */
1
2 "use strict";
3
4 describe("plugin API", function() {
5 beforeEach(function() {
6 this.addMatchers({
7 toBeObject: function() {
8 this.message = function() {
9 return "Expected " + jasmine.pp(this.actual) + " "
10 + (this.isNot ? "not " : "")
11 + "to be an object.";
12 };
13
14 return this.actual !== null && typeof this.actual === "object";
15 },
16
17 toBeArray: function() {
18 this.message = function() {
19 return "Expected " + jasmine.pp(this.actual) + " "
20 + (this.isNot ? "not " : "")
21 + "to be an array.";
22 };
23
24 return Object.prototype.toString.apply(this.actual) === "[object Array]";
25 },
26
27 toBeFunction: function() {
28 this.message = function() {
29 return "Expected " + jasmine.pp(this.actual) + " "
30 + (this.isNot ? "not " : "")
31 + "to be a function.";
32 };
33
34 return typeof this.actual === "function";
35 }
36 });
37 });
38
39 describe("use", function() {
40 var grammar = 'start = "a"';
41
42 it("is called for each plugin", function() {
43 var pluginsUsed = [false, false, false],
44 plugins = [
45 { use: function() { pluginsUsed[0] = true; } },
46 { use: function() { pluginsUsed[1] = true; } },
47 { use: function() { pluginsUsed[2] = true; } }
48 ];
49
50 peg.generate(grammar, { plugins: plugins });
51
52 expect(pluginsUsed).toEqual([true, true, true]);
53 });
54
55 it("receives configuration", function() {
56 var plugin = {
57 use: function(config) {
58 var i;
59
60 expect(config).toBeObject();
61
62 expect(config.parser).toBeObject();
63 expect(config.parser.parse('start = "a"')).toBeObject();
64
65 expect(config.passes).toBeObject();
66
67 expect(config.passes.check).toBeArray();
68 for (i = 0; i < config.passes.check.length; i++) {
69 expect(config.passes.check[i]).toBeFunction();
70 }
71
72 expect(config.passes.transform).toBeArray();
73 for (i = 0; i < config.passes.transform.length; i++) {
74 expect(config.passes.transform[i]).toBeFunction();
75 }
76
77 expect(config.passes.generate).toBeArray();
78 for (i = 0; i < config.passes.generate.length; i++) {
79 expect(config.passes.generate[i]).toBeFunction();
80 }
81 }
82 };
83
84 peg.generate(grammar, { plugins: [plugin] });
85 });
86
87 it("receives options", function() {
88 var plugin = {
89 use: function(config, options) {
90 expect(options).toEqual(generateOptions);
91 }
92 },
93 generateOptions = { plugins: [plugin], foo: 42 };
94
95 peg.generate(grammar, generateOptions);
96 });
97
98 it("can replace parser", function() {
99 var plugin = {
100 use: function(config) {
101 var parser = peg.generate([
102 'start = .* {',
103 ' return {',
104 ' type: "grammar",',
105 ' rules: [',
106 ' {',
107 ' type: "rule",',
108 ' name: "start",',
109 ' expression: { type: "literal", value: text(), ignoreCase: false }',
110 ' }',
111 ' ]',
112 ' };',
113 '}'
114 ].join("\n"));
115
116 config.parser = parser;
117 }
118 },
119 parser = peg.generate('a', { plugins: [plugin] });
120
121 expect(parser.parse("a")).toBe("a");
122 });
123
124 it("can change compiler passes", function() {
125 var plugin = {
126 use: function(config) {
127 var pass = function(ast) {
128 ast.code = '({ parse: function() { return 42; } })';
129 };
130
131 config.passes.generate = [pass];
132 }
133 },
134 parser = peg.generate(grammar, { plugins: [plugin] });
135
136 expect(parser.parse("a")).toBe(42);
137 });
138
139 it("can change options", function() {
140 var grammar = [
141 'a = "x"',
142 'b = "x"',
143 'c = "x"'
144 ].join("\n"),
145 plugin = {
146 use: function(config, options) {
147 options.allowedStartRules = ["b", "c"];
148 }
149 },
150 parser = peg.generate(grammar, {
151 allowedStartRules: ["a"],
152 plugins: [plugin]
153 });
154
155 expect(function() { parser.parse("x", { startRule: "a" }); }).toThrow();
156 expect(parser.parse("x", { startRule: "b" })).toBe("x");
157 expect(parser.parse("x", { startRule: "c" })).toBe("x");
158 });
159 });
160 });
0 /* eslint no-console: 0 */
1 /* global peg, console */
2
3 "use strict";
4
5 describe("generated parser behavior", function() {
6 function varyOptimizationOptions(block) {
7 function clone(object) {
8 var result = {}, key;
9
10 for (key in object) {
11 if (object.hasOwnProperty(key)) {
12 result[key] = object[key];
13 }
14 }
15
16 return result;
17 }
18
19 var optionsVariants = [
20 { cache: false, optimize: "speed", trace: false },
21 { cache: false, optimize: "speed", trace: true },
22 { cache: false, optimize: "size", trace: false },
23 { cache: false, optimize: "size", trace: true },
24 { cache: true, optimize: "speed", trace: false },
25 { cache: true, optimize: "speed", trace: true },
26 { cache: true, optimize: "size", trace: false },
27 { cache: true, optimize: "size", trace: true }
28 ],
29 i;
30
31 for (i = 0; i < optionsVariants.length; i++) {
32 describe(
33 "with options " + jasmine.pp(optionsVariants[i]),
34 function() { block(clone(optionsVariants[i])); }
35 );
36 }
37 }
38
39 beforeEach(function() {
40 this.addMatchers({
41 toParse: function(input, expected, options) {
42 options = options !== undefined ? options : {};
43
44 var result;
45
46 try {
47 result = this.actual.parse(input, options);
48 } catch (e) {
49 this.message = function() {
50 return "Expected " + jasmine.pp(input) + " "
51 + "with options " + jasmine.pp(options) + " "
52 + "to parse" + (expected !== undefined ? " as " + jasmine.pp(expected) : "") + ", "
53 + "but it failed to parse with message "
54 + jasmine.pp(e.message) + ".";
55 };
56
57 return false;
58 }
59
60 if (expected !== undefined) {
61 this.message = function() {
62 return "Expected " + jasmine.pp(input) + " "
63 + "with options " + jasmine.pp(options) + " "
64 + (this.isNot ? "not " : "")
65 + "to parse as " + jasmine.pp(expected) + ", "
66 + "but it parsed as " + jasmine.pp(result) + ".";
67 };
68
69 return this.env.equals_(result, expected);
70 } else {
71 return true;
72 }
73 },
74
75 toFailToParse: function(input, details, options) {
76 options = options !== undefined ? options : {};
77
78 var result, key;
79
80 try {
81 result = this.actual.parse(input, options);
82 } catch (e) {
83 if (this.isNot) {
84 this.message = function() {
85 return "Expected " + jasmine.pp(input)
86 + "with options " + jasmine.pp(options) + " "
87 + "to parse, "
88 + "but it failed with message "
89 + jasmine.pp(e.message) + ".";
90 };
91 } else {
92 if (details) {
93 for (key in details) {
94 if (details.hasOwnProperty(key)) {
95 if (!this.env.equals_(e[key], details[key])) {
96 this.message = function() {
97 return "Expected " + jasmine.pp(input) + " "
98 + "with options " + jasmine.pp(options) + " "
99 + "to fail to parse"
100 + (details ? " with details " + jasmine.pp(details) : "") + ", "
101 + "but " + jasmine.pp(key) + " "
102 + "is " + jasmine.pp(e[key]) + ".";
103 };
104
105 return false;
106 }
107 }
108 }
109 }
110 }
111
112 return true;
113 }
114
115 this.message = function() {
116 return "Expected " + jasmine.pp(input) + " "
117 + "with options " + jasmine.pp(options) + " "
118 + "to fail to parse"
119 + (details ? " with details " + jasmine.pp(details) : "") + ", "
120 + "but it parsed as " + jasmine.pp(result) + ".";
121 };
122
123 return false;
124 }
125 });
126
127 /*
128 * Stub out |console.log| so that the default tracer doesn't clutter
129 * test output.
130 */
131 if (typeof console === "object") {
132 spyOn(console, "log");
133 }
134 });
135
136 varyOptimizationOptions(function(options) {
137 describe("initializer", function() {
138 it("executes the code before parsing starts", function() {
139 var parser = peg.generate([
140 '{ var result = 42; }',
141 'start = "a" { return result; }'
142 ].join("\n"), options);
143
144 expect(parser).toParse("a", 42);
145 });
146
147 describe("available variables and functions", function() {
148 it("|options| contains options", function() {
149 var parser = peg.generate([
150 '{ var result = options; }',
151 'start = "a" { return result; }'
152 ].join("\n"), options);
153
154 expect(parser).toParse("a", { a: 42 }, { a: 42 });
155 });
156 });
157 });
158
159 describe("rule", function() {
160 if (options.cache) {
161 it("caches rule match results", function() {
162 var parser = peg.generate([
163 '{ var n = 0; }',
164 'start = (a "b") / (a "c") { return n; }',
165 'a = "a" { n++; }'
166 ].join("\n"), options);
167
168 expect(parser).toParse("ac", 1);
169 });
170 } else {
171 it("doesn't cache rule match results", function() {
172 var parser = peg.generate([
173 '{ var n = 0; }',
174 'start = (a "b") / (a "c") { return n; }',
175 'a = "a" { n++; }'
176 ].join("\n"), options);
177
178 expect(parser).toParse("ac", 2);
179 });
180 }
181
182 describe("when the expression matches", function() {
183 it("returns its match result", function() {
184 var parser = peg.generate('start = "a"');
185
186 expect(parser).toParse("a", "a");
187 });
188 });
189
190 describe("when the expression doesn't match", function() {
191 describe("without display name", function() {
192 it("reports match failure and doesn't record any expectation", function() {
193 var parser = peg.generate('start = "a"');
194
195 expect(parser).toFailToParse("b", {
196 expected: [{ type: "literal", text: "a", ignoreCase: false }]
197 });
198 });
199 });
200
201 describe("with display name", function() {
202 it("reports match failure and records an expectation of type \"other\"", function() {
203 var parser = peg.generate('start "start" = "a"');
204
205 expect(parser).toFailToParse("b", {
206 expected: [{ type: "other", description: "start" }]
207 });
208 });
209
210 it("discards any expectations recorded when matching the expression", function() {
211 var parser = peg.generate('start "start" = "a"');
212
213 expect(parser).toFailToParse("b", {
214 expected: [{ type: "other", description: "start" }]
215 });
216 });
217 });
218 });
219 });
220
221 describe("literal", function() {
222 describe("matching", function() {
223 it("matches empty literals", function() {
224 var parser = peg.generate('start = ""', options);
225
226 expect(parser).toParse("");
227 });
228
229 it("matches one-character literals", function() {
230 var parser = peg.generate('start = "a"', options);
231
232 expect(parser).toParse("a");
233 expect(parser).toFailToParse("b");
234 });
235
236 it("matches multi-character literals", function() {
237 var parser = peg.generate('start = "abcd"', options);
238
239 expect(parser).toParse("abcd");
240 expect(parser).toFailToParse("efgh");
241 });
242
243 it("is case sensitive without the \"i\" flag", function() {
244 var parser = peg.generate('start = "a"', options);
245
246 expect(parser).toParse("a");
247 expect(parser).toFailToParse("A");
248 });
249
250 it("is case insensitive with the \"i\" flag", function() {
251 var parser = peg.generate('start = "a"i', options);
252
253 expect(parser).toParse("a");
254 expect(parser).toParse("A");
255 });
256 });
257
258 describe("when it matches", function() {
259 it("returns the matched text", function() {
260 var parser = peg.generate('start = "a"', options);
261
262 expect(parser).toParse("a", "a");
263 });
264
265 it("consumes the matched text", function() {
266 var parser = peg.generate('start = "a" .', options);
267
268 expect(parser).toParse("ab");
269 });
270 });
271
272 describe("when it doesn't match", function() {
273 it("reports match failure and records an expectation of type \"literal\"", function() {
274 var parser = peg.generate('start = "a"', options);
275
276 expect(parser).toFailToParse("b", {
277 expected: [{ type: "literal", text: "a", ignoreCase: false }]
278 });
279 });
280 });
281 });
282
283 describe("character class", function() {
284 describe("matching", function() {
285 it("matches empty classes", function() {
286 var parser = peg.generate('start = []', options);
287
288 expect(parser).toFailToParse("a");
289 });
290
291 it("matches classes with a character list", function() {
292 var parser = peg.generate('start = [abc]', options);
293
294 expect(parser).toParse("a");
295 expect(parser).toParse("b");
296 expect(parser).toParse("c");
297 expect(parser).toFailToParse("d");
298 });
299
300 it("matches classes with a character range", function() {
301 var parser = peg.generate('start = [a-c]', options);
302
303 expect(parser).toParse("a");
304 expect(parser).toParse("b");
305 expect(parser).toParse("c");
306 expect(parser).toFailToParse("d");
307 });
308
309 it("matches inverted classes", function() {
310 var parser = peg.generate('start = [^a]', options);
311
312 expect(parser).toFailToParse("a");
313 expect(parser).toParse("b");
314 });
315
316 it("is case sensitive without the \"i\" flag", function() {
317 var parser = peg.generate('start = [a]', options);
318
319 expect(parser).toParse("a");
320 expect(parser).toFailToParse("A");
321 });
322
323 it("is case insensitive with the \"i\" flag", function() {
324 var parser = peg.generate('start = [a]i', options);
325
326 expect(parser).toParse("a");
327 expect(parser).toParse("A");
328 });
329 });
330
331 describe("when it matches", function() {
332 it("returns the matched character", function() {
333 var parser = peg.generate('start = [a]', options);
334
335 expect(parser).toParse("a", "a");
336 });
337
338 it("consumes the matched character", function() {
339 var parser = peg.generate('start = [a] .', options);
340
341 expect(parser).toParse("ab");
342 });
343 });
344
345 describe("when it doesn't match", function() {
346 it("reports match failure and records an expectation of type \"class\"", function() {
347 var parser = peg.generate('start = [a]', options);
348
349 expect(parser).toFailToParse("b", {
350 expected: [{ type: "class", parts: ["a"], inverted: false, ignoreCase: false }]
351 });
352 });
353 });
354 });
355
356 describe("dot", function() {
357 describe("matching", function() {
358 it("matches any character", function() {
359 var parser = peg.generate('start = .', options);
360
361 expect(parser).toParse("a");
362 expect(parser).toParse("b");
363 expect(parser).toParse("c");
364 });
365 });
366
367 describe("when it matches", function() {
368 it("returns the matched character", function() {
369 var parser = peg.generate('start = .', options);
370
371 expect(parser).toParse("a", "a");
372 });
373
374 it("consumes the matched character", function() {
375 var parser = peg.generate('start = . .', options);
376
377 expect(parser).toParse("ab");
378 });
379 });
380
381 describe("when it doesn't match", function() {
382 it("reports match failure and records an expectation of type \"any\"", function() {
383 var parser = peg.generate('start = .', options);
384
385 expect(parser).toFailToParse("", {
386 expected: [{ type: "any" }]
387 });
388 });
389 });
390 });
391
392 describe("rule reference", function() {
393 describe("when referenced rule's expression matches", function() {
394 it("returns its result", function() {
395 var parser = peg.generate([
396 'start = a',
397 'a = "a"'
398 ].join("\n"), options);
399
400 expect(parser).toParse("a", "a");
401 });
402 });
403
404 describe("when referenced rule's expression doesn't match", function() {
405 it("reports match failure", function() {
406 var parser = peg.generate([
407 'start = a',
408 'a = "a"'
409 ].join("\n"), options);
410
411 expect(parser).toFailToParse("b");
412 });
413 });
414 });
415
416 describe("positive semantic predicate", function() {
417 describe("when the code returns a truthy value", function() {
418 it("returns |undefined|", function() {
419 /*
420 * The |""| is needed so that the parser doesn't return just
421 * |undefined| which we can't compare against in |toParse| due to the
422 * way optional parameters work.
423 */
424 var parser = peg.generate('start = &{ return true; } ""', options);
425
426 expect(parser).toParse("", [undefined, ""]);
427 });
428 });
429
430 describe("when the code returns a falsey value", function() {
431 it("reports match failure", function() {
432 var parser = peg.generate('start = &{ return false; }', options);
433
434 expect(parser).toFailToParse("");
435 });
436 });
437
438 describe("label variables", function() {
439 describe("in containing sequence", function() {
440 it("can access variables defined by preceding labeled elements", function() {
441 var parser = peg.generate(
442 'start = a:"a" &{ return a === "a"; }',
443 options
444 );
445
446 expect(parser).toParse("a");
447 });
448
449 it("cannot access variable defined by labeled predicate element", function() {
450 var parser = peg.generate(
451 'start = "a" b:&{ return b === undefined; } "c"',
452 options
453 );
454
455 expect(parser).toFailToParse("ac");
456 });
457
458 it("cannot access variables defined by following labeled elements", function() {
459 var parser = peg.generate(
460 'start = &{ return a === "a"; } a:"a"',
461 options
462 );
463
464 expect(parser).toFailToParse("a");
465 });
466
467 it("cannot access variables defined by subexpressions", function() {
468 var testcases = [
469 {
470 grammar: 'start = (a:"a") &{ return a === "a"; }',
471 input: "a"
472 },
473 {
474 grammar: 'start = (a:"a")? &{ return a === "a"; }',
475 input: "a"
476 },
477 {
478 grammar: 'start = (a:"a")* &{ return a === "a"; }',
479 input: "a"
480 },
481 {
482 grammar: 'start = (a:"a")+ &{ return a === "a"; }',
483 input: "a"
484 },
485 {
486 grammar: 'start = $(a:"a") &{ return a === "a"; }',
487 input: "a"
488 },
489 {
490 grammar: 'start = &(a:"a") "a" &{ return a === "a"; }',
491 input: "a"
492 },
493 {
494 grammar: 'start = !(a:"a") "b" &{ return a === "a"; }',
495 input: "b"
496 },
497 {
498 grammar: 'start = b:(a:"a") &{ return a === "a"; }',
499 input: "a"
500 },
501 {
502 grammar: 'start = ("a" b:"b" "c") &{ return b === "b"; }',
503 input: "abc"
504 },
505 {
506 grammar: 'start = (a:"a" { return a; }) &{ return a === "a"; }',
507 input: "a"
508 },
509 {
510 grammar: 'start = ("a" / b:"b" / "c") &{ return b === "b"; }',
511 input: "b"
512 }
513 ],
514 parser, i;
515
516 for (i = 0; i < testcases.length; i++) {
517 parser = peg.generate(testcases[i].grammar, options);
518 expect(parser).toFailToParse(testcases[i].input);
519 }
520 });
521 });
522
523 describe("in outer sequence", function() {
524 it("can access variables defined by preceding labeled elements", function() {
525 var parser = peg.generate(
526 'start = a:"a" ("b" &{ return a === "a"; })',
527 options
528 );
529
530 expect(parser).toParse("ab");
531 });
532
533 it("cannot access variable defined by labeled predicate element", function() {
534 var parser = peg.generate(
535 'start = "a" b:("b" &{ return b === undefined; }) "c"',
536 options
537 );
538
539 expect(parser).toFailToParse("abc");
540 });
541
542 it("cannot access variables defined by following labeled elements", function() {
543 var parser = peg.generate(
544 'start = ("a" &{ return b === "b"; }) b:"b"',
545 options
546 );
547
548 expect(parser).toFailToParse("ab");
549 });
550 });
551 });
552
553 describe("initializer variables & functions", function() {
554 it("can access variables defined in the initializer", function() {
555 var parser = peg.generate([
556 '{ var v = 42 }',
557 'start = &{ return v === 42; }'
558 ].join("\n"), options);
559
560 expect(parser).toParse("");
561 });
562
563 it("can access functions defined in the initializer", function() {
564 var parser = peg.generate([
565 '{ function f() { return 42; } }',
566 'start = &{ return f() === 42; }'
567 ].join("\n"), options);
568
569 expect(parser).toParse("");
570 });
571 });
572
573 describe("available variables & functions", function() {
574 it("|options| contains options", function() {
575 var parser = peg.generate([
576 '{ var result; }',
577 'start = &{ result = options; return true; } { return result; }'
578 ].join("\n"), options);
579
580 expect(parser).toParse("", { a: 42 }, { a: 42 });
581 });
582
583 it("|location| returns current location info", function() {
584 var parser = peg.generate([
585 '{ var result; }',
586 'start = line (nl+ line)* { return result; }',
587 'line = thing (" "+ thing)*',
588 'thing = digit / mark',
589 'digit = [0-9]',
590 'mark = &{ result = location(); return true; } "x"',
591 'nl = "\\r"? "\\n"'
592 ].join("\n"), options);
593
594 expect(parser).toParse("1\n2\n\n3\n\n\n4 5 x", {
595 start: { offset: 13, line: 7, column: 5 },
596 end: { offset: 13, line: 7, column: 5 }
597 });
598
599 /* Newline representations */
600 expect(parser).toParse("1\nx", { // Unix
601 start: { offset: 2, line: 2, column: 1 },
602 end: { offset: 2, line: 2, column: 1 }
603 });
604 expect(parser).toParse("1\r\nx", { // Windows
605 start: { offset: 3, line: 2, column: 1 },
606 end: { offset: 3, line: 2, column: 1 }
607 });
608 });
609 });
610 });
611
612 describe("negative semantic predicate", function() {
613 describe("when the code returns a falsey value", function() {
614 it("returns |undefined|", function() {
615 /*
616 * The |""| is needed so that the parser doesn't return just
617 * |undefined| which we can't compare against in |toParse| due to the
618 * way optional parameters work.
619 */
620 var parser = peg.generate('start = !{ return false; } ""', options);
621
622 expect(parser).toParse("", [undefined, ""]);
623 });
624 });
625
626 describe("when the code returns a truthy value", function() {
627 it("reports match failure", function() {
628 var parser = peg.generate('start = !{ return true; }', options);
629
630 expect(parser).toFailToParse("");
631 });
632 });
633
634 describe("label variables", function() {
635 describe("in containing sequence", function() {
636 it("can access variables defined by preceding labeled elements", function() {
637 var parser = peg.generate(
638 'start = a:"a" !{ return a !== "a"; }',
639 options
640 );
641
642 expect(parser).toParse("a");
643 });
644
645 it("cannot access variable defined by labeled predicate element", function() {
646 var parser = peg.generate(
647 'start = "a" b:!{ return b !== undefined; } "c"',
648 options
649 );
650
651 expect(parser).toFailToParse("ac");
652 });
653
654 it("cannot access variables defined by following labeled elements", function() {
655 var parser = peg.generate(
656 'start = !{ return a !== "a"; } a:"a"',
657 options
658 );
659
660 expect(parser).toFailToParse("a");
661 });
662
663 it("cannot access variables defined by subexpressions", function() {
664 var testcases = [
665 {
666 grammar: 'start = (a:"a") !{ return a !== "a"; }',
667 input: "a"
668 },
669 {
670 grammar: 'start = (a:"a")? !{ return a !== "a"; }',
671 input: "a"
672 },
673 {
674 grammar: 'start = (a:"a")* !{ return a !== "a"; }',
675 input: "a"
676 },
677 {
678 grammar: 'start = (a:"a")+ !{ return a !== "a"; }',
679 input: "a"
680 },
681 {
682 grammar: 'start = $(a:"a") !{ return a !== "a"; }',
683 input: "a"
684 },
685 {
686 grammar: 'start = &(a:"a") "a" !{ return a !== "a"; }',
687 input: "a"
688 },
689 {
690 grammar: 'start = !(a:"a") "b" !{ return a !== "a"; }',
691 input: "b"
692 },
693 {
694 grammar: 'start = b:(a:"a") !{ return a !== "a"; }',
695 input: "a"
696 },
697 {
698 grammar: 'start = ("a" b:"b" "c") !{ return b !== "b"; }',
699 input: "abc"
700 },
701 {
702 grammar: 'start = (a:"a" { return a; }) !{ return a !== "a"; }',
703 input: "a"
704 },
705 {
706 grammar: 'start = ("a" / b:"b" / "c") !{ return b !== "b"; }',
707 input: "b"
708 }
709 ],
710 parser, i;
711
712 for (i = 0; i < testcases.length; i++) {
713 parser = peg.generate(testcases[i].grammar, options);
714 expect(parser).toFailToParse(testcases[i].input);
715 }
716 });
717 });
718
719 describe("in outer sequence", function() {
720 it("can access variables defined by preceding labeled elements", function() {
721 var parser = peg.generate(
722 'start = a:"a" ("b" !{ return a !== "a"; })',
723 options
724 );
725
726 expect(parser).toParse("ab");
727 });
728
729 it("cannot access variable defined by labeled predicate element", function() {
730 var parser = peg.generate(
731 'start = "a" b:("b" !{ return b !== undefined; }) "c"',
732 options
733 );
734
735 expect(parser).toFailToParse("abc");
736 });
737
738 it("cannot access variables defined by following labeled elements", function() {
739 var parser = peg.generate(
740 'start = ("a" !{ return b !== "b"; }) b:"b"',
741 options
742 );
743
744 expect(parser).toFailToParse("ab");
745 });
746 });
747 });
748
749 describe("initializer variables & functions", function() {
750 it("can access variables defined in the initializer", function() {
751 var parser = peg.generate([
752 '{ var v = 42 }',
753 'start = !{ return v !== 42; }'
754 ].join("\n"), options);
755
756 expect(parser).toParse("");
757 });
758
759 it("can access functions defined in the initializer", function() {
760 var parser = peg.generate([
761 '{ function f() { return 42; } }',
762 'start = !{ return f() !== 42; }'
763 ].join("\n"), options);
764
765 expect(parser).toParse("");
766 });
767 });
768
769 describe("available variables & functions", function() {
770 it("|options| contains options", function() {
771 var parser = peg.generate([
772 '{ var result; }',
773 'start = !{ result = options; return false; } { return result; }'
774 ].join("\n"), options);
775
776 expect(parser).toParse("", { a: 42 }, { a: 42 });
777 });
778
779 it("|location| returns current location info", function() {
780 var parser = peg.generate([
781 '{ var result; }',
782 'start = line (nl+ line)* { return result; }',
783 'line = thing (" "+ thing)*',
784 'thing = digit / mark',
785 'digit = [0-9]',
786 'mark = !{ result = location(); return false; } "x"',
787 'nl = "\\r"? "\\n"'
788 ].join("\n"), options);
789
790 expect(parser).toParse("1\n2\n\n3\n\n\n4 5 x", {
791 start: { offset: 13, line: 7, column: 5 },
792 end: { offset: 13, line: 7, column: 5 }
793 });
794
795 /* Newline representations */
796 expect(parser).toParse("1\nx", { // Unix
797 start: { offset: 2, line: 2, column: 1 },
798 end: { offset: 2, line: 2, column: 1 }
799 });
800 expect(parser).toParse("1\r\nx", { // Windows
801 start: { offset: 3, line: 2, column: 1 },
802 end: { offset: 3, line: 2, column: 1 }
803 });
804 });
805 });
806 });
807
808 describe("group", function() {
809 describe("when the expression matches", function() {
810 it("returns its match result", function() {
811 var parser = peg.generate('start = ("a")', options);
812
813 expect(parser).toParse("a", "a");
814 });
815 });
816
817 describe("when the expression doesn't match", function() {
818 it("reports match failure", function() {
819 var parser = peg.generate('start = ("a")', options);
820
821 expect(parser).toFailToParse("b");
822 });
823 });
824 });
825
826 describe("optional", function() {
827 describe("when the expression matches", function() {
828 it("returns its match result", function() {
829 var parser = peg.generate('start = "a"?', options);
830
831 expect(parser).toParse("a", "a");
832 });
833 });
834
835 describe("when the expression doesn't match", function() {
836 it("returns |null|", function() {
837 var parser = peg.generate('start = "a"?', options);
838
839 expect(parser).toParse("", null);
840 });
841 });
842 });
843
844 describe("zero or more", function() {
845 describe("when the expression matches zero or more times", function() {
846 it("returns an array of its match results", function() {
847 var parser = peg.generate('start = "a"*', options);
848
849 expect(parser).toParse("", []);
850 expect(parser).toParse("a", ["a"]);
851 expect(parser).toParse("aaa", ["a", "a", "a"]);
852 });
853 });
854 });
855
856 describe("one or more", function() {
857 describe("when the expression matches one or more times", function() {
858 it("returns an array of its match results", function() {
859 var parser = peg.generate('start = "a"+', options);
860
861 expect(parser).toParse("a", ["a"]);
862 expect(parser).toParse("aaa", ["a", "a", "a"]);
863 });
864 });
865
866 describe("when the expression doesn't match", function() {
867 it("reports match failure", function() {
868 var parser = peg.generate('start = "a"+', options);
869
870 expect(parser).toFailToParse("");
871 });
872 });
873 });
874
875 describe("text", function() {
876 describe("when the expression matches", function() {
877 it("returns the matched text", function() {
878 var parser = peg.generate('start = $("a" "b" "c")', options);
879
880 expect(parser).toParse("abc", "abc");
881 });
882 });
883
884 describe("when the expression doesn't match", function() {
885 it("reports match failure", function() {
886 var parser = peg.generate('start = $("a")', options);
887
888 expect(parser).toFailToParse("b");
889 });
890 });
891 });
892
893 describe("positive simple predicate", function() {
894 describe("when the expression matches", function() {
895 it("returns |undefined|", function() {
896 var parser = peg.generate('start = &"a" "a"', options);
897
898 expect(parser).toParse("a", [undefined, "a"]);
899 });
900
901 it("resets parse position", function() {
902 var parser = peg.generate('start = &"a" "a"', options);
903
904 expect(parser).toParse("a");
905 });
906 });
907
908 describe("when the expression doesn't match", function() {
909 it("reports match failure", function() {
910 var parser = peg.generate('start = &"a"', options);
911
912 expect(parser).toFailToParse("b");
913 });
914
915 it("discards any expectations recorded when matching the expression", function() {
916 var parser = peg.generate('start = "a" / &"b" / "c"', options);
917
918 expect(parser).toFailToParse("d", {
919 expected: [
920 { type: "literal", text: "a", ignoreCase: false },
921 { type: "literal", text: "c", ignoreCase: false }
922 ]
923 });
924 });
925 });
926 });
927
928 describe("negative simple predicate", function() {
929 describe("when the expression matches", function() {
930 it("reports match failure", function() {
931 var parser = peg.generate('start = !"a"', options);
932
933 expect(parser).toFailToParse("a");
934 });
935 });
936
937 describe("when the expression doesn't match", function() {
938 it("returns |undefined|", function() {
939 var parser = peg.generate('start = !"a" "b"', options);
940
941 expect(parser).toParse("b", [undefined, "b"]);
942 });
943
944 it("resets parse position", function() {
945 var parser = peg.generate('start = !"a" "b"', options);
946
947 expect(parser).toParse("b");
948 });
949
950 it("discards any expectations recorded when matching the expression", function() {
951 var parser = peg.generate('start = "a" / !"b" / "c"', options);
952
953 expect(parser).toFailToParse("b", {
954 expected: [
955 { type: "literal", text: "a", ignoreCase: false },
956 { type: "literal", text: "c", ignoreCase: false }
957 ]
958 });
959 });
960 });
961 });
962
963 describe("label", function() {
964 describe("when the expression matches", function() {
965 it("returns its match result", function() {
966 var parser = peg.generate('start = a:"a"', options);
967
968 expect(parser).toParse("a", "a");
969 });
970 });
971
972 describe("when the expression doesn't match", function() {
973 it("reports match failure", function() {
974 var parser = peg.generate('start = a:"a"', options);
975
976 expect(parser).toFailToParse("b");
977 });
978 });
979 });
980
981 describe("sequence", function() {
982 describe("when all expressions match", function() {
983 it("returns an array of their match results", function() {
984 var parser = peg.generate('start = "a" "b" "c"', options);
985
986 expect(parser).toParse("abc", ["a", "b", "c"]);
987 });
988 });
989
990 describe("when any expression doesn't match", function() {
991 it("reports match failure", function() {
992 var parser = peg.generate('start = "a" "b" "c"', options);
993
994 expect(parser).toFailToParse("dbc");
995 expect(parser).toFailToParse("adc");
996 expect(parser).toFailToParse("abd");
997 });
998
999 it("resets parse position", function() {
1000 var parser = peg.generate('start = "a" "b" / "a"', options);
1001
1002 expect(parser).toParse("a", "a");
1003 });
1004 });
1005 });
1006
1007 describe("action", function() {
1008 describe("when the expression matches", function() {
1009 it("returns the value returned by the code", function() {
1010 var parser = peg.generate('start = "a" { return 42; }', options);
1011
1012 expect(parser).toParse("a", 42);
1013 });
1014
1015 describe("label variables", function() {
1016 describe("in the expression", function() {
1017 it("can access variable defined by labeled expression", function() {
1018 var parser = peg.generate('start = a:"a" { return a; }', options);
1019
1020 expect(parser).toParse("a", "a");
1021 });
1022
1023 it("can access variables defined by labeled sequence elements", function() {
1024 var parser = peg.generate(
1025 'start = a:"a" b:"b" c:"c" { return [a, b, c]; }',
1026 options
1027 );
1028
1029 expect(parser).toParse("abc", ["a", "b", "c"]);
1030 });
1031
1032 it("cannot access variables defined by subexpressions", function() {
1033 var testcases = [
1034 {
1035 grammar: 'start = (a:"a") { return a; }',
1036 input: "a"
1037 },
1038 {
1039 grammar: 'start = (a:"a")? { return a; }',
1040 input: "a"
1041 },
1042 {
1043 grammar: 'start = (a:"a")* { return a; }',
1044 input: "a"
1045 },
1046 {
1047 grammar: 'start = (a:"a")+ { return a; }',
1048 input: "a"
1049 },
1050 {
1051 grammar: 'start = $(a:"a") { return a; }',
1052 input: "a"
1053 },
1054 {
1055 grammar: 'start = &(a:"a") "a" { return a; }',
1056 input: "a"
1057 },
1058 {
1059 grammar: 'start = !(a:"a") "b" { return a; }',
1060 input: "b"
1061 },
1062 {
1063 grammar: 'start = b:(a:"a") { return a; }',
1064 input: "a"
1065 },
1066 {
1067 grammar: 'start = ("a" b:"b" "c") { return b; }',
1068 input: "abc"
1069 },
1070 {
1071 grammar: 'start = (a:"a" { return a; }) { return a; }',
1072 input: "a"
1073 },
1074 {
1075 grammar: 'start = ("a" / b:"b" / "c") { return b; }',
1076 input: "b"
1077 }
1078 ],
1079 parser, i;
1080
1081 for (i = 0; i < testcases.length; i++) {
1082 parser = peg.generate(testcases[i].grammar, options);
1083 expect(parser).toFailToParse(testcases[i].input);
1084 }
1085 });
1086 });
1087
1088 describe("in outer sequence", function() {
1089 it("can access variables defined by preceding labeled elements", function() {
1090 var parser = peg.generate(
1091 'start = a:"a" ("b" { return a; })',
1092 options
1093 );
1094
1095 expect(parser).toParse("ab", ["a", "a"]);
1096 });
1097
1098 it("cannot access variable defined by labeled action element", function() {
1099 var parser = peg.generate(
1100 'start = "a" b:("b" { return b; }) c:"c"',
1101 options
1102 );
1103
1104 expect(parser).toFailToParse("abc");
1105 });
1106
1107 it("cannot access variables defined by following labeled elements", function() {
1108 var parser = peg.generate(
1109 'start = ("a" { return b; }) b:"b"',
1110 options
1111 );
1112
1113 expect(parser).toFailToParse("ab");
1114 });
1115 });
1116 });
1117
1118 describe("initializer variables & functions", function() {
1119 it("can access variables defined in the initializer", function() {
1120 var parser = peg.generate([
1121 '{ var v = 42 }',
1122 'start = "a" { return v; }'
1123 ].join("\n"), options);
1124
1125 expect(parser).toParse("a", 42);
1126 });
1127
1128 it("can access functions defined in the initializer", function() {
1129 var parser = peg.generate([
1130 '{ function f() { return 42; } }',
1131 'start = "a" { return f(); }'
1132 ].join("\n"), options);
1133
1134 expect(parser).toParse("a", 42);
1135 });
1136 });
1137
1138 describe("available variables & functions", function() {
1139 it("|options| contains options", function() {
1140 var parser = peg.generate(
1141 'start = "a" { return options; }',
1142 options
1143 );
1144
1145 expect(parser).toParse("a", { a: 42 }, { a: 42 });
1146 });
1147
1148 it("|text| returns text matched by the expression", function() {
1149 var parser = peg.generate(
1150 'start = "a" { return text(); }',
1151 options
1152 );
1153
1154 expect(parser).toParse("a", "a");
1155 });
1156
1157 it("|location| returns location info of the expression", function() {
1158 var parser = peg.generate([
1159 '{ var result; }',
1160 'start = line (nl+ line)* { return result; }',
1161 'line = thing (" "+ thing)*',
1162 'thing = digit / mark',
1163 'digit = [0-9]',
1164 'mark = "x" { result = location(); }',
1165 'nl = "\\r"? "\\n"'
1166 ].join("\n"), options);
1167
1168 expect(parser).toParse("1\n2\n\n3\n\n\n4 5 x", {
1169 start: { offset: 13, line: 7, column: 5 },
1170 end: { offset: 14, line: 7, column: 6 }
1171 });
1172
1173 /* Newline representations */
1174 expect(parser).toParse("1\nx", { // Unix
1175 start: { offset: 2, line: 2, column: 1 },
1176 end: { offset: 3, line: 2, column: 2 }
1177 });
1178 expect(parser).toParse("1\r\nx", { // Windows
1179 start: { offset: 3, line: 2, column: 1 },
1180 end: { offset: 4, line: 2, column: 2 }
1181 });
1182 });
1183
1184 describe("|expected|", function() {
1185 it("terminates parsing and throws an exception", function() {
1186 var parser = peg.generate(
1187 'start = "a" { expected("a"); }',
1188 options
1189 );
1190
1191 expect(parser).toFailToParse("a", {
1192 message: 'Expected a but "a" found.',
1193 expected: [{ type: "other", description: "a" }],
1194 found: "a",
1195 location: {
1196 start: { offset: 0, line: 1, column: 1 },
1197 end: { offset: 1, line: 1, column: 2 }
1198 }
1199 });
1200 });
1201
1202 it("allows to set custom location info", function() {
1203 var parser = peg.generate([
1204 'start = "a" {',
1205 ' expected("a", {',
1206 ' start: { offset: 1, line: 1, column: 2 },',
1207 ' end: { offset: 2, line: 1, column: 3 }',
1208 ' });',
1209 '}'
1210 ].join("\n"), options);
1211
1212 expect(parser).toFailToParse("a", {
1213 message: 'Expected a but "a" found.',
1214 expected: [{ type: "other", description: "a" }],
1215 found: "a",
1216 location: {
1217 start: { offset: 1, line: 1, column: 2 },
1218 end: { offset: 2, line: 1, column: 3 }
1219 }
1220 });
1221 });
1222 });
1223
1224 describe("|error|", function() {
1225 it("terminates parsing and throws an exception", function() {
1226 var parser = peg.generate(
1227 'start = "a" { error("a"); }',
1228 options
1229 );
1230
1231 expect(parser).toFailToParse("a", {
1232 message: "a",
1233 found: null,
1234 expected: null,
1235 location: {
1236 start: { offset: 0, line: 1, column: 1 },
1237 end: { offset: 1, line: 1, column: 2 }
1238 }
1239 });
1240 });
1241
1242 it("allows to set custom location info", function() {
1243 var parser = peg.generate([
1244 'start = "a" {',
1245 ' error("a", {',
1246 ' start: { offset: 1, line: 1, column: 2 },',
1247 ' end: { offset: 2, line: 1, column: 3 }',
1248 ' });',
1249 '}'
1250 ].join("\n"), options);
1251
1252 expect(parser).toFailToParse("a", {
1253 message: "a",
1254 expected: null,
1255 found: null,
1256 location: {
1257 start: { offset: 1, line: 1, column: 2 },
1258 end: { offset: 2, line: 1, column: 3 }
1259 }
1260 });
1261 });
1262 });
1263 });
1264 });
1265
1266 describe("when the expression doesn't match", function() {
1267 it("reports match failure", function() {
1268 var parser = peg.generate('start = "a" { return 42; }', options);
1269
1270 expect(parser).toFailToParse("b");
1271 });
1272
1273 it("doesn't execute the code", function() {
1274 var parser = peg.generate(
1275 'start = "a" { throw "Boom!"; } / "b"',
1276 options
1277 );
1278
1279 expect(parser).toParse("b");
1280 });
1281 });
1282 });
1283
1284 describe("choice", function() {
1285 describe("when any expression matches", function() {
1286 it("returns its match result", function() {
1287 var parser = peg.generate('start = "a" / "b" / "c"', options);
1288
1289 expect(parser).toParse("a", "a");
1290 expect(parser).toParse("b", "b");
1291 expect(parser).toParse("c", "c");
1292 });
1293 });
1294
1295 describe("when all expressions don't match", function() {
1296 it("reports match failure", function() {
1297 var parser = peg.generate('start = "a" / "b" / "c"', options);
1298
1299 expect(parser).toFailToParse("d");
1300 });
1301 });
1302 });
1303
1304 describe("error reporting", function() {
1305 describe("behavior", function() {
1306 it("reports only the rightmost error", function() {
1307 var parser = peg.generate('start = "a" "b" / "a" "c" "d"', options);
1308
1309 expect(parser).toFailToParse("ace", {
1310 expected: [{ type: "literal", text: "d", ignoreCase: false }]
1311 });
1312 });
1313 });
1314
1315 describe("expectations reporting", function() {
1316 it("reports expectations correctly with no alternative", function() {
1317 var parser = peg.generate('start = "a"', options);
1318
1319 expect(parser).toFailToParse("ab", {
1320 expected: [{ type: "end" }]
1321 });
1322 });
1323
1324 it("reports expectations correctly with one alternative", function() {
1325 var parser = peg.generate('start = "a"', options);
1326
1327 expect(parser).toFailToParse("b", {
1328 expected: [{ type: "literal", text: "a", ignoreCase: false }]
1329 });
1330 });
1331
1332 it("reports expectations correctly with multiple alternatives", function() {
1333 var parser = peg.generate('start = "a" / "b" / "c"', options);
1334
1335 expect(parser).toFailToParse("d", {
1336 expected: [
1337 { type: "literal", text: "a", ignoreCase: false },
1338 { type: "literal", text: "b", ignoreCase: false },
1339 { type: "literal", text: "c", ignoreCase: false }
1340 ]
1341 });
1342 });
1343 });
1344
1345 describe("found string reporting", function() {
1346 it("reports found string correctly at the end of input", function() {
1347 var parser = peg.generate('start = "a"', options);
1348
1349 expect(parser).toFailToParse("", { found: null });
1350 });
1351
1352 it("reports found string correctly in the middle of input", function() {
1353 var parser = peg.generate('start = "a"', options);
1354
1355 expect(parser).toFailToParse("b", { found: "b" });
1356 });
1357 });
1358
1359 describe("message building", function() {
1360 it("builds message correctly with no alternative", function() {
1361 var parser = peg.generate('start = "a"', options);
1362
1363 expect(parser).toFailToParse("ab", {
1364 message: 'Expected end of input but "b" found.'
1365 });
1366 });
1367
1368 it("builds message correctly with one alternative", function() {
1369 var parser = peg.generate('start = "a"', options);
1370
1371 expect(parser).toFailToParse("b", {
1372 message: 'Expected "a" but "b" found.'
1373 });
1374 });
1375
1376 it("builds message correctly with multiple alternatives", function() {
1377 var parser = peg.generate('start = "a" / "b" / "c"', options);
1378
1379 expect(parser).toFailToParse("d", {
1380 message: 'Expected "a", "b", or "c" but "d" found.'
1381 });
1382 });
1383
1384 it("builds message correctly at the end of input", function() {
1385 var parser = peg.generate('start = "a"', options);
1386
1387 expect(parser).toFailToParse("", {
1388 message: 'Expected "a" but end of input found.'
1389 });
1390 });
1391
1392 it("builds message correctly in the middle of input", function() {
1393 var parser = peg.generate('start = "a"', options);
1394
1395 expect(parser).toFailToParse("b", {
1396 message: 'Expected "a" but "b" found.'
1397 });
1398 });
1399
1400 it("removes duplicates from expectations", function() {
1401 var parser = peg.generate('start = "a" / "a"', options);
1402
1403 expect(parser).toFailToParse("b", {
1404 message: 'Expected "a" but "b" found.'
1405 });
1406 });
1407
1408 it("sorts expectations", function() {
1409 var parser = peg.generate('start = "c" / "b" / "a"', options);
1410
1411 expect(parser).toFailToParse("d", {
1412 message: 'Expected "a", "b", or "c" but "d" found.'
1413 });
1414 });
1415
1416 });
1417
1418 describe("position reporting", function() {
1419 it("reports position correctly at the end of input", function() {
1420 var parser = peg.generate('start = "a"', options);
1421
1422 expect(parser).toFailToParse("", {
1423 location: {
1424 start: { offset: 0, line: 1, column: 1 },
1425 end: { offset: 0, line: 1, column: 1 }
1426 }
1427 });
1428 });
1429
1430 it("reports position correctly in the middle of input", function() {
1431 var parser = peg.generate('start = "a"', options);
1432
1433 expect(parser).toFailToParse("b", {
1434 location: {
1435 start: { offset: 0, line: 1, column: 1 },
1436 end: { offset: 1, line: 1, column: 2 }
1437 }
1438 });
1439 });
1440
1441 it("reports position correctly with trailing input", function() {
1442 var parser = peg.generate('start = "a"', options);
1443
1444 expect(parser).toFailToParse("aa", {
1445 location: {
1446 start: { offset: 1, line: 1, column: 2 },
1447 end: { offset: 2, line: 1, column: 3 }
1448 }
1449 });
1450 });
1451
1452 it("reports position correctly in complex cases", function() {
1453 var parser = peg.generate([
1454 'start = line (nl+ line)*',
1455 'line = digit (" "+ digit)*',
1456 'digit = [0-9]',
1457 'nl = "\\r"? "\\n"'
1458 ].join("\n"), options);
1459
1460 expect(parser).toFailToParse("1\n2\n\n3\n\n\n4 5 x", {
1461 location: {
1462 start: { offset: 13, line: 7, column: 5 },
1463 end: { offset: 14, line: 7, column: 6 }
1464 }
1465 });
1466
1467 /* Newline representations */
1468 expect(parser).toFailToParse("1\nx", { // Old Mac
1469 location: {
1470 start: { offset: 2, line: 2, column: 1 },
1471 end: { offset: 3, line: 2, column: 2 }
1472 }
1473 });
1474 expect(parser).toFailToParse("1\r\nx", { // Windows
1475 location: {
1476 start: { offset: 3, line: 2, column: 1 },
1477 end: { offset: 4, line: 2, column: 2 }
1478 }
1479 });
1480 });
1481 });
1482 });
1483
1484 /*
1485 * Following examples are from Wikipedia, see
1486 * http://en.wikipedia.org/w/index.php?title=Parsing_expression_grammar&oldid=335106938.
1487 */
1488 describe("complex examples", function() {
1489 it("handles arithmetics example correctly", function() {
1490 /*
1491 * Value ← [0-9]+ / '(' Expr ')'
1492 * Product ← Value (('*' / '/') Value)*
1493 * Sum ← Product (('+' / '-') Product)*
1494 * Expr ← Sum
1495 */
1496 var parser = peg.generate([
1497 'Expr = Sum',
1498 'Sum = first:Product rest:(("+" / "-") Product)* {',
1499 ' var result = first, i;',
1500 ' for (i = 0; i < rest.length; i++) {',
1501 ' if (rest[i][0] == "+") { result += rest[i][1]; }',
1502 ' if (rest[i][0] == "-") { result -= rest[i][1]; }',
1503 ' }',
1504 ' return result;',
1505 ' }',
1506 'Product = first:Value rest:(("*" / "/") Value)* {',
1507 ' var result = first, i;',
1508 ' for (i = 0; i < rest.length; i++) {',
1509 ' if (rest[i][0] == "*") { result *= rest[i][1]; }',
1510 ' if (rest[i][0] == "/") { result /= rest[i][1]; }',
1511 ' }',
1512 ' return result;',
1513 ' }',
1514 'Value = digits:[0-9]+ { return parseInt(digits.join(""), 10); }',
1515 ' / "(" expr:Expr ")" { return expr; }'
1516 ].join("\n"), options);
1517
1518 /* The "value" rule */
1519 expect(parser).toParse("0", 0);
1520 expect(parser).toParse("123", 123);
1521 expect(parser).toParse("(42+43)", 42+43);
1522
1523 /* The "product" rule */
1524 expect(parser).toParse("42", 42);
1525 expect(parser).toParse("42*43", 42*43);
1526 expect(parser).toParse("42*43*44*45", 42*43*44*45);
1527 expect(parser).toParse("42/43", 42/43);
1528 expect(parser).toParse("42/43/44/45", 42/43/44/45);
1529
1530 /* The "sum" rule */
1531 expect(parser).toParse("42*43", 42*43);
1532 expect(parser).toParse("42*43+44*45", 42*43+44*45);
1533 expect(parser).toParse("42*43+44*45+46*47+48*49", 42*43+44*45+46*47+48*49);
1534 expect(parser).toParse("42*43-44*45", 42*43-44*45);
1535 expect(parser).toParse("42*43-44*45-46*47-48*49", 42*43-44*45-46*47-48*49);
1536
1537 /* The "expr" rule */
1538 expect(parser).toParse("42+43", 42+43);
1539
1540 /* Complex test */
1541 expect(parser).toParse("(1+2)*(3+4)", (1+2)*(3+4));
1542 });
1543
1544 it("handles non-context-free language correctly", function() {
1545 /* The following parsing expression grammar describes the classic
1546 * non-context-free language { a^n b^n c^n : n >= 1 }:
1547 *
1548 * S ← &(A c) a+ B !(a/b/c)
1549 * A ← a A? b
1550 * B ← b B? c
1551 */
1552 var parser = peg.generate([
1553 'S = &(A "c") a:"a"+ B:B !("a" / "b" / "c") { return a.join("") + B; }',
1554 'A = a:"a" A:A? b:"b" { return [a, A, b].join(""); }',
1555 'B = b:"b" B:B? c:"c" { return [b, B, c].join(""); }'
1556 ].join("\n"), options);
1557
1558 expect(parser).toParse("abc", "abc");
1559 expect(parser).toParse("aaabbbccc", "aaabbbccc");
1560 expect(parser).toFailToParse("aabbbccc");
1561 expect(parser).toFailToParse("aaaabbbccc");
1562 expect(parser).toFailToParse("aaabbccc");
1563 expect(parser).toFailToParse("aaabbbbccc");
1564 expect(parser).toFailToParse("aaabbbcc");
1565 expect(parser).toFailToParse("aaabbbcccc");
1566 });
1567
1568 it("handles nested comments example correctly", function() {
1569 /*
1570 * Begin ← "(*"
1571 * End ← "*)"
1572 * C ← Begin N* End
1573 * N ← C / (!Begin !End Z)
1574 * Z ← any single character
1575 */
1576 var parser = peg.generate([
1577 'C = begin:Begin ns:N* end:End { return begin + ns.join("") + end; }',
1578 'N = C',
1579 ' / !Begin !End z:Z { return z; }',
1580 'Z = .',
1581 'Begin = "(*"',
1582 'End = "*)"'
1583 ].join("\n"), options);
1584
1585 expect(parser).toParse("(**)", "(**)");
1586 expect(parser).toParse("(*abc*)", "(*abc*)");
1587 expect(parser).toParse("(*(**)*)", "(*(**)*)");
1588 expect(parser).toParse(
1589 "(*abc(*def*)ghi(*(*(*jkl*)*)*)mno*)",
1590 "(*abc(*def*)ghi(*(*(*jkl*)*)*)mno*)"
1591 );
1592 });
1593 });
1594 });
1595 });
0 /* global require */
1
2 "use strict";
3
4 (function(root) {
5 if (typeof module !== 'undefined') {
6 root.peg = require("../lib/peg.js");
7 }
8 }(this));
0 <html>
1 <head>
2 <meta charset="utf-8">
3 <title>PEG.js Spec Suite</title>
4 <link rel="stylesheet" href="vendor/jasmine/jasmine.css">
5 <script src="vendor/jasmine/jasmine.js"></script>
6 <script src="vendor/jasmine/jasmine-html.js"></script>
7 <script src="../browser/peg-0.10.0.js"></script>
8 <script src="helpers.js"></script>
9 <script src="unit/parser.spec.js"></script>
10 <script src="unit/compiler/passes/helpers.js"></script>
11 <script src="unit/compiler/passes/report-undefined-rules.spec.js"></script>
12 <script src="unit/compiler/passes/report-duplicate-rules.spec.js"></script>
13 <script src="unit/compiler/passes/report-duplicate-labels.spec.js"></script>
14 <script src="unit/compiler/passes/report-infinite-recursion.spec.js"></script>
15 <script src="unit/compiler/passes/report-infinite-repetition.spec.js"></script>
16 <script src="unit/compiler/passes/remove-proxy-rules.spec.js"></script>
17 <script src="unit/compiler/passes/generate-bytecode.spec.js"></script>
18 <script src="api/pegjs-api.spec.js"></script>
19 <script src="api/plugin-api.spec.js"></script>
20 <script src="api/generated-parser-api.spec.js"></script>
21 <script src="behavior/generated-parser-behavior.spec.js"></script>
22 <script>
23 (function() {
24 var env = jasmine.getEnv(),
25 reporter = new jasmine.HtmlReporter();
26
27 env.addReporter(reporter);
28 env.specFilter = reporter.specFilter;
29
30 window.onload = function() { env.execute(); };
31 })();
32 </script>
33 </head>
34 <body>
35 </body>
36 </html>
0 /* global peg */
1
2 "use strict";
3
4 describe("compiler pass |generateBytecode|", function() {
5 var pass = peg.compiler.passes.generate.generateBytecode;
6
7 function bytecodeDetails(bytecode) {
8 return {
9 rules: [{ bytecode: bytecode }]
10 };
11 }
12
13 function constsDetails(consts) { return { consts: consts }; }
14
15 describe("for grammar", function() {
16 it("generates correct bytecode", function() {
17 expect(pass).toChangeAST([
18 'a = "a"',
19 'b = "b"',
20 'c = "c"'
21 ].join("\n"), {
22 rules: [
23 { bytecode: [18, 0, 2, 2, 22, 0, 23, 1] },
24 { bytecode: [18, 2, 2, 2, 22, 2, 23, 3] },
25 { bytecode: [18, 4, 2, 2, 22, 4, 23, 5] }
26 ]
27 });
28 });
29
30 it("defines correct constants", function() {
31 expect(pass).toChangeAST([
32 'a = "a"',
33 'b = "b"',
34 'c = "c"'
35 ].join("\n"), constsDetails([
36 '"a"',
37 'peg$literalExpectation("a", false)',
38 '"b"',
39 'peg$literalExpectation("b", false)',
40 '"c"',
41 'peg$literalExpectation("c", false)'
42 ]));
43 });
44 });
45
46 describe("for rule", function() {
47 it("generates correct bytecode", function() {
48 expect(pass).toChangeAST('start = "a"', bytecodeDetails([
49 18, 0, 2, 2, 22, 0, 23, 1 // <expression>
50 ]));
51 });
52 });
53
54 describe("for named", function() {
55 var grammar = 'start "start" = "a"';
56
57 it("generates correct bytecode", function() {
58 expect(pass).toChangeAST(grammar, bytecodeDetails([
59 28, // SILENT_FAILS_ON
60 18, 1, 2, 2, 22, 1, 23, 2, // <expression>
61 29, // SILENT_FAILS_OFF
62 14, 2, 0, // IF_ERROR
63 23, 0 // * FAIL
64 ]));
65 });
66
67 it("defines correct constants", function() {
68 expect(pass).toChangeAST(grammar, constsDetails([
69 'peg$otherExpectation("start")',
70 '"a"',
71 'peg$literalExpectation("a", false)'
72 ]));
73 });
74 });
75
76 describe("for choice", function() {
77 it("generates correct bytecode", function() {
78 expect(pass).toChangeAST('start = "a" / "b" / "c"', bytecodeDetails([
79 18, 0, 2, 2, 22, 0, 23, 1, // <alternatives[0]>
80 14, 21, 0, // IF_ERROR
81 6, // * POP
82 18, 2, 2, 2, 22, 2, 23, 3, // <alternatives[1]>
83 14, 9, 0, // IF_ERROR
84 6, // * POP
85 18, 4, 2, 2, 22, 4, 23, 5 // <alternatives[2]>
86 ]));
87 });
88 });
89
90 describe("for action", function() {
91 describe("without labels", function() {
92 var grammar = 'start = "a" { code }';
93
94 it("generates correct bytecode", function() {
95 expect(pass).toChangeAST(grammar, bytecodeDetails([
96 5, // PUSH_CURR_POS
97 18, 0, 2, 2, 22, 0, 23, 1, // <expression>
98 15, 6, 0, // IF_NOT_ERROR
99 24, 1, // * LOAD_SAVED_POS
100 26, 2, 1, 0, // CALL
101 9 // NIP
102 ]));
103 });
104
105 it("defines correct constants", function() {
106 expect(pass).toChangeAST(grammar, constsDetails([
107 '"a"',
108 'peg$literalExpectation("a", false)',
109 'function() { code }'
110 ]));
111 });
112 });
113
114 describe("with one label", function() {
115 var grammar = 'start = a:"a" { code }';
116
117 it("generates correct bytecode", function() {
118 expect(pass).toChangeAST(grammar, bytecodeDetails([
119 5, // PUSH_CURR_POS
120 18, 0, 2, 2, 22, 0, 23, 1, // <expression>
121 15, 7, 0, // IF_NOT_ERROR
122 24, 1, // * LOAD_SAVED_POS
123 26, 2, 1, 1, 0, // CALL
124 9 // NIP
125 ]));
126 });
127
128 it("defines correct constants", function() {
129 expect(pass).toChangeAST(grammar, constsDetails([
130 '"a"',
131 'peg$literalExpectation("a", false)',
132 'function(a) { code }'
133 ]));
134 });
135 });
136
137 describe("with multiple labels", function() {
138 var grammar = 'start = a:"a" b:"b" c:"c" { code }';
139
140 it("generates correct bytecode", function() {
141 expect(pass).toChangeAST(grammar, bytecodeDetails([
142 5, // PUSH_CURR_POS
143 18, 0, 2, 2, 22, 0, 23, 1, // <elements[0]>
144 15, 40, 3, // IF_NOT_ERROR
145 18, 2, 2, 2, 22, 2, 23, 3, // * <elements[1]>
146 15, 25, 4, // IF_NOT_ERROR
147 18, 4, 2, 2, 22, 4, 23, 5, // * <elements[2]>
148 15, 10, 4, // IF_NOT_ERROR
149 24, 3, // * LOAD_SAVED_POS
150 26, 6, 3, 3, 2, 1, 0, // CALL
151 9, // NIP
152 8, 3, // * POP_N
153 7, // POP_CURR_POS
154 3, // PUSH_FAILED
155 8, 2, // * POP_N
156 7, // POP_CURR_POS
157 3, // PUSH_FAILED
158 6, // * POP
159 7, // POP_CURR_POS
160 3 // PUSH_FAILED
161 ]));
162 });
163
164 it("defines correct constants", function() {
165 expect(pass).toChangeAST(grammar, constsDetails([
166 '"a"',
167 'peg$literalExpectation("a", false)',
168 '"b"',
169 'peg$literalExpectation("b", false)',
170 '"c"',
171 'peg$literalExpectation("c", false)',
172 'function(a, b, c) { code }'
173 ]));
174 });
175 });
176 });
177
178 describe("for sequence", function() {
179 var grammar = 'start = "a" "b" "c"';
180
181 it("generates correct bytecode", function() {
182 expect(pass).toChangeAST(grammar, bytecodeDetails([
183 5, // PUSH_CURR_POS
184 18, 0, 2, 2, 22, 0, 23, 1, // <elements[0]>
185 15, 33, 3, // IF_NOT_ERROR
186 18, 2, 2, 2, 22, 2, 23, 3, // * <elements[1]>
187 15, 18, 4, // IF_NOT_ERROR
188 18, 4, 2, 2, 22, 4, 23, 5, // * <elements[2]>
189 15, 3, 4, // IF_NOT_ERROR
190 11, 3, // * WRAP
191 9, // NIP
192 8, 3, // * POP_N
193 7, // POP_CURR_POS
194 3, // PUSH_FAILED
195 8, 2, // * POP_N
196 7, // POP_CURR_POS
197 3, // PUSH_FAILED
198 6, // * POP
199 7, // POP_CURR_POS
200 3 // PUSH_FAILED
201 ]));
202 });
203
204 it("defines correct constants", function() {
205 expect(pass).toChangeAST(grammar, constsDetails([
206 '"a"',
207 'peg$literalExpectation("a", false)',
208 '"b"',
209 'peg$literalExpectation("b", false)',
210 '"c"',
211 'peg$literalExpectation("c", false)'
212 ]));
213 });
214 });
215
216 describe("for labeled", function() {
217 it("generates correct bytecode", function() {
218 expect(pass).toChangeAST('start = a:"a"', bytecodeDetails([
219 18, 0, 2, 2, 22, 0, 23, 1 // <expression>
220 ]));
221 });
222 });
223
224 describe("for text", function() {
225 it("generates correct bytecode", function() {
226 expect(pass).toChangeAST('start = $"a"', bytecodeDetails([
227 5, // PUSH_CURR_POS
228 18, 0, 2, 2, 22, 0, 23, 1, // <expression>
229 15, 2, 1, // IF_NOT_ERROR
230 6, // * POP
231 12, // TEXT
232 9 // * NIP
233 ]));
234 });
235 });
236
237 describe("for simple_and", function() {
238 var grammar = 'start = &"a"';
239
240 it("generates correct bytecode", function() {
241 expect(pass).toChangeAST(grammar, bytecodeDetails([
242 5, // PUSH_CURR_POS
243 28, // SILENT_FAILS_ON
244 18, 0, 2, 2, 22, 0, 23, 1, // <expression>
245 29, // SILENT_FAILS_OFF
246 15, 3, 3, // IF_NOT_ERROR
247 6, // * POP
248 7, // POP_CURR_POS
249 1, // PUSH_UNDEFINED
250 6, // * POP
251 6, // POP
252 3 // PUSH_FAILED
253 ]));
254 });
255
256 it("defines correct constants", function() {
257 expect(pass).toChangeAST(grammar, constsDetails([
258 '"a"',
259 'peg$literalExpectation("a", false)'
260 ]));
261 });
262 });
263
264 describe("for simple_not", function() {
265 var grammar = 'start = !"a"';
266
267 it("generates correct bytecode", function() {
268 expect(pass).toChangeAST(grammar, bytecodeDetails([
269 5, // PUSH_CURR_POS
270 28, // SILENT_FAILS_ON
271 18, 0, 2, 2, 22, 0, 23, 1, // <expression>
272 29, // SILENT_FAILS_OFF
273 14, 3, 3, // IF_ERROR
274 6, // * POP
275 6, // POP
276 1, // PUSH_UNDEFINED
277 6, // * POP
278 7, // POP_CURR_POS
279 3 // PUSH_FAILED
280 ]));
281 });
282
283 it("defines correct constants", function() {
284 expect(pass).toChangeAST(grammar, constsDetails([
285 '"a"',
286 'peg$literalExpectation("a", false)'
287 ]));
288 });
289 });
290
291 describe("for optional", function() {
292 var grammar = 'start = "a"?';
293
294 it("generates correct bytecode", function() {
295 expect(pass).toChangeAST(grammar, bytecodeDetails([
296 18, 0, 2, 2, 22, 0, 23, 1, // <expression>
297 14, 2, 0, // IF_ERROR
298 6, // * POP
299 2 // PUSH_NULL
300 ]));
301 });
302
303 it("defines correct constants", function() {
304 expect(pass).toChangeAST(grammar, constsDetails([
305 '"a"',
306 'peg$literalExpectation("a", false)'
307 ]));
308 });
309 });
310
311 describe("for zero_or_more", function() {
312 var grammar = 'start = "a"*';
313
314 it("generates correct bytecode", function() {
315 expect(pass).toChangeAST(grammar, bytecodeDetails([
316 4, // PUSH_EMPTY_ARRAY
317 18, 0, 2, 2, 22, 0, 23, 1, // <expression>
318 16, 9, // WHILE_NOT_ERROR
319 10, // * APPEND
320 18, 0, 2, 2, 22, 0, 23, 1, // <expression>
321 6 // POP
322 ]));
323 });
324
325 it("defines correct constants", function() {
326 expect(pass).toChangeAST(grammar, constsDetails([
327 '"a"',
328 'peg$literalExpectation("a", false)'
329 ]));
330 });
331 });
332
333 describe("for one_or_more", function() {
334 var grammar = 'start = "a"+';
335
336 it("generates correct bytecode", function() {
337 expect(pass).toChangeAST(grammar, bytecodeDetails([
338 4, // PUSH_EMPTY_ARRAY
339 18, 0, 2, 2, 22, 0, 23, 1, // <expression>
340 15, 12, 3, // IF_NOT_ERROR
341 16, 9, // * WHILE_NOT_ERROR
342 10, // * APPEND
343 18, 0, 2, 2, 22, 0, 23, 1, // <expression>
344 6, // POP
345 6, // * POP
346 6, // POP
347 3 // PUSH_FAILED
348 ]));
349 });
350
351 it("defines correct constants", function() {
352 expect(pass).toChangeAST(grammar, constsDetails([
353 '"a"',
354 'peg$literalExpectation("a", false)'
355 ]));
356 });
357 });
358
359 describe("for group", function() {
360 it("generates correct bytecode", function() {
361 expect(pass).toChangeAST('start = ("a")', bytecodeDetails([
362 18, 0, 2, 2, 22, 0, 23, 1 // <expression>
363 ]));
364 });
365 });
366
367 describe("for semantic_and", function() {
368 describe("without labels", function() {
369 var grammar = 'start = &{ code }';
370
371 it("generates correct bytecode", function() {
372 expect(pass).toChangeAST(grammar, bytecodeDetails([
373 25, // UPDATE_SAVED_POS
374 26, 0, 0, 0, // CALL
375 13, 2, 2, // IF
376 6, // * POP
377 1, // PUSH_UNDEFINED
378 6, // * POP
379 3 // PUSH_FAILED
380 ]));
381 });
382
383 it("defines correct constants", function() {
384 expect(pass).toChangeAST(
385 grammar,
386 constsDetails(['function() { code }'])
387 );
388 });
389 });
390
391 describe("with labels", function() {
392 var grammar = 'start = a:"a" b:"b" c:"c" &{ code }';
393
394 it("generates correct bytecode", function() {
395 expect(pass).toChangeAST(grammar, bytecodeDetails([
396 5, // PUSH_CURR_POS
397 18, 0, 2, 2, 22, 0, 23, 1, // <elements[0]>
398 15, 55, 3, // IF_NOT_ERROR
399 18, 2, 2, 2, 22, 2, 23, 3, // * <elements[1]>
400 15, 40, 4, // IF_NOT_ERROR
401 18, 4, 2, 2, 22, 4, 23, 5, // * <elements[2]>
402 15, 25, 4, // IF_NOT_ERROR
403 25, // * UPDATE_SAVED_POS
404 26, 6, 0, 3, 2, 1, 0, // CALL
405 13, 2, 2, // IF
406 6, // * POP
407 1, // PUSH_UNDEFINED
408 6, // * POP
409 3, // PUSH_FAILED
410 15, 3, 4, // IF_NOT_ERROR
411 11, 4, // * WRAP
412 9, // NIP
413 8, 4, // * POP_N
414 7, // POP_CURR_POS
415 3, // PUSH_FAILED
416 8, 3, // * POP_N
417 7, // POP_CURR_POS
418 3, // PUSH_FAILED
419 8, 2, // * POP_N
420 7, // POP_CURR_POS
421 3, // PUSH_FAILED
422 6, // * POP
423 7, // POP_CURR_POS
424 3 // PUSH_FAILED
425 ]));
426 });
427
428 it("defines correct constants", function() {
429 expect(pass).toChangeAST(grammar, constsDetails([
430 '"a"',
431 'peg$literalExpectation("a", false)',
432 '"b"',
433 'peg$literalExpectation("b", false)',
434 '"c"',
435 'peg$literalExpectation("c", false)',
436 'function(a, b, c) { code }'
437 ]));
438 });
439 });
440 });
441
442 describe("for semantic_not", function() {
443 describe("without labels", function() {
444 var grammar = 'start = !{ code }';
445
446 it("generates correct bytecode", function() {
447 expect(pass).toChangeAST(grammar, bytecodeDetails([
448 25, // UPDATE_SAVED_POS
449 26, 0, 0, 0, // CALL
450 13, 2, 2, // IF
451 6, // * POP
452 3, // PUSH_FAILED
453 6, // * POP
454 1 // PUSH_UNDEFINED
455 ]));
456 });
457
458 it("defines correct constants", function() {
459 expect(pass).toChangeAST(
460 grammar,
461 constsDetails(['function() { code }'])
462 );
463 });
464 });
465
466 describe("with labels", function() {
467 var grammar = 'start = a:"a" b:"b" c:"c" !{ code }';
468
469 it("generates correct bytecode", function() {
470 expect(pass).toChangeAST(grammar, bytecodeDetails([
471 5, // PUSH_CURR_POS
472 18, 0, 2, 2, 22, 0, 23, 1, // <elements[0]>
473 15, 55, 3, // IF_NOT_ERROR
474 18, 2, 2, 2, 22, 2, 23, 3, // * <elements[1]>
475 15, 40, 4, // IF_NOT_ERROR
476 18, 4, 2, 2, 22, 4, 23, 5, // * <elements[2]>
477 15, 25, 4, // IF_NOT_ERROR
478 25, // * UPDATE_SAVED_POS
479 26, 6, 0, 3, 2, 1, 0, // CALL
480 13, 2, 2, // IF
481 6, // * POP
482 3, // PUSH_FAILED
483 6, // * POP
484 1, // PUSH_UNDEFINED
485 15, 3, 4, // IF_NOT_ERROR
486 11, 4, // * WRAP
487 9, // NIP
488 8, 4, // * POP_N
489 7, // POP_CURR_POS
490 3, // PUSH_FAILED
491 8, 3, // * POP_N
492 7, // POP_CURR_POS
493 3, // PUSH_FAILED
494 8, 2, // * POP_N
495 7, // POP_CURR_POS
496 3, // PUSH_FAILED
497 6, // * POP
498 7, // POP_CURR_POS
499 3 // PUSH_FAILED
500 ]));
501 });
502
503 it("defines correct constants", function() {
504 expect(pass).toChangeAST(grammar, constsDetails([
505 '"a"',
506 'peg$literalExpectation("a", false)',
507 '"b"',
508 'peg$literalExpectation("b", false)',
509 '"c"',
510 'peg$literalExpectation("c", false)',
511 'function(a, b, c) { code }'
512 ]));
513 });
514 });
515 });
516
517 describe("for rule_ref", function() {
518 it("generates correct bytecode", function() {
519 expect(pass).toChangeAST([
520 'start = other',
521 'other = "other"'
522 ].join("\n"), {
523 rules: [
524 {
525 bytecode: [27, 1] // RULE
526 },
527 { }
528 ]
529 });
530 });
531 });
532
533 describe("for literal", function() {
534 describe("empty", function() {
535 var grammar = 'start = ""';
536
537 it("generates correct bytecode", function() {
538 expect(pass).toChangeAST(grammar, bytecodeDetails([
539 0, 0 // PUSH
540 ]));
541 });
542
543 it("defines correct constants", function() {
544 expect(pass).toChangeAST(grammar, constsDetails(['""']));
545 });
546 });
547
548 describe("non-empty case-sensitive", function() {
549 var grammar = 'start = "a"';
550
551 it("generates correct bytecode", function() {
552 expect(pass).toChangeAST(grammar, bytecodeDetails([
553 18, 0, 2, 2, // MATCH_STRING
554 22, 0, // * ACCEPT_STRING
555 23, 1 // * FAIL
556 ]));
557 });
558
559 it("defines correct constants", function() {
560 expect(pass).toChangeAST(grammar, constsDetails([
561 '"a"',
562 'peg$literalExpectation("a", false)'
563 ]));
564 });
565 });
566
567 describe("non-empty case-insensitive", function() {
568 var grammar = 'start = "A"i';
569
570 it("generates correct bytecode", function() {
571 expect(pass).toChangeAST(grammar, bytecodeDetails([
572 19, 0, 2, 2, // MATCH_STRING_IC
573 21, 1, // * ACCEPT_N
574 23, 1 // * FAIL
575 ]));
576 });
577
578 it("defines correct constants", function() {
579 expect(pass).toChangeAST(grammar, constsDetails([
580 '"a"',
581 'peg$literalExpectation("A", true)'
582 ]));
583 });
584 });
585 });
586
587 describe("for class", function() {
588 it("generates correct bytecode", function() {
589 expect(pass).toChangeAST('start = [a]', bytecodeDetails([
590 20, 0, 2, 2, // MATCH_REGEXP
591 21, 1, // * ACCEPT_N
592 23, 1 // * FAIL
593 ]));
594 });
595
596 describe("non-empty non-inverted case-sensitive", function() {
597 it("defines correct constants", function() {
598 expect(pass).toChangeAST('start = [a]', constsDetails([
599 '/^[a]/',
600 'peg$classExpectation(["a"], false, false)'
601 ]));
602 });
603 });
604
605 describe("non-empty inverted case-sensitive", function() {
606 it("defines correct constants", function() {
607 expect(pass).toChangeAST('start = [^a]', constsDetails([
608 '/^[^a]/',
609 'peg$classExpectation(["a"], true, false)'
610 ]));
611 });
612 });
613
614 describe("non-empty non-inverted case-insensitive", function() {
615 it("defines correct constants", function() {
616 expect(pass).toChangeAST('start = [a]i', constsDetails([
617 '/^[a]/i',
618 'peg$classExpectation(["a"], false, true)'
619 ]));
620 });
621 });
622
623 describe("non-empty complex", function() {
624 it("defines correct constants", function() {
625 expect(pass).toChangeAST('start = [ab-def-hij-l]', constsDetails([
626 '/^[ab-def-hij-l]/',
627 'peg$classExpectation(["a", ["b", "d"], "e", ["f", "h"], "i", ["j", "l"]], false, false)'
628 ]));
629 });
630 });
631
632 describe("empty non-inverted", function() {
633 it("defines correct constants", function() {
634 expect(pass).toChangeAST('start = []', constsDetails([
635 '/^(?!)/',
636 'peg$classExpectation([], false, false)'
637 ]));
638 });
639 });
640
641 describe("empty inverted", function() {
642 it("defines correct constants", function() {
643 expect(pass).toChangeAST('start = [^]', constsDetails([
644 '/^[\\S\\s]/',
645 'peg$classExpectation([], true, false)'
646 ]));
647 });
648 });
649 });
650
651 describe("for any", function() {
652 var grammar = 'start = .';
653
654 it("generates bytecode", function() {
655 expect(pass).toChangeAST(grammar, bytecodeDetails([
656 17, 2, 2, // MATCH_ANY
657 21, 1, // * ACCEPT_N
658 23, 0 // * FAIL
659 ]));
660 });
661
662 it("defines correct constants", function() {
663 expect(pass).toChangeAST(
664 grammar,
665 constsDetails(['peg$anyExpectation()'])
666 );
667 });
668 });
669 });
0 /* global peg */
1
2 "use strict";
3
4 beforeEach(function() {
5 this.addMatchers({
6 toChangeAST: function(grammar, details, options) {
7 options = options !== undefined ? options : {};
8
9 function matchDetails(value, details) {
10 function isArray(value) {
11 return Object.prototype.toString.apply(value) === "[object Array]";
12 }
13
14 function isObject(value) {
15 return value !== null && typeof value === "object";
16 }
17
18 var i, key;
19
20 if (isArray(details)) {
21 if (!isArray(value)) { return false; }
22
23 if (value.length !== details.length) { return false; }
24 for (i = 0; i < details.length; i++) {
25 if (!matchDetails(value[i], details[i])) { return false; }
26 }
27
28 return true;
29 } else if (isObject(details)) {
30 if (!isObject(value)) { return false; }
31
32 for (key in details) {
33 if (details.hasOwnProperty(key)) {
34 if (!(key in value)) { return false; }
35
36 if (!matchDetails(value[key], details[key])) { return false; }
37 }
38 }
39
40 return true;
41 } else {
42 return value === details;
43 }
44 }
45
46 var ast = peg.parser.parse(grammar);
47
48 this.actual(ast, options);
49
50 this.message = function() {
51 return "Expected the pass "
52 + "with options " + jasmine.pp(options) + " "
53 + (this.isNot ? "not " : "")
54 + "to change the AST " + jasmine.pp(ast) + " "
55 + "to match " + jasmine.pp(details) + ", "
56 + "but it " + (this.isNot ? "did" : "didn't") + ".";
57 };
58
59 return matchDetails(ast, details);
60 },
61
62 toReportError: function(grammar, details) {
63 var ast = peg.parser.parse(grammar),
64 key;
65
66 try {
67 this.actual(ast);
68 } catch (e) {
69 if (this.isNot) {
70 this.message = function() {
71 return "Expected the pass not to report an error "
72 + "for grammar " + jasmine.pp(grammar) + ", "
73 + "but it did.";
74 };
75 } else {
76 if (details) {
77 for (key in details) {
78 if (details.hasOwnProperty(key)) {
79 if (!this.env.equals_(e[key], details[key])) {
80 this.message = function() {
81 return "Expected the pass to report an error "
82 + "with details " + jasmine.pp(details) + " "
83 + "for grammar " + jasmine.pp(grammar) + ", "
84 + "but " + jasmine.pp(key) + " "
85 + "is " + jasmine.pp(e[key]) + ".";
86 };
87
88 return false;
89 }
90 }
91 }
92 }
93 }
94
95 return true;
96 }
97
98 this.message = function() {
99 return "Expected the pass to report an error "
100 + (details ? "with details " + jasmine.pp(details) + " ": "")
101 + "for grammar " + jasmine.pp(grammar) + ", "
102 + "but it didn't.";
103 };
104
105 return false;
106 }
107 });
108 });
0 /* global peg */
1
2 "use strict";
3
4 describe("compiler pass |removeProxyRules|", function() {
5 var pass = peg.compiler.passes.transform.removeProxyRules;
6
7 describe("when a proxy rule isn't listed in |allowedStartRules|", function() {
8 it("updates references and removes it", function() {
9 expect(pass).toChangeAST(
10 [
11 'start = proxy',
12 'proxy = proxied',
13 'proxied = "a"'
14 ].join("\n"),
15 {
16 rules: [
17 {
18 name: "start",
19 expression: { type: "rule_ref", name: "proxied" }
20 },
21 { name: "proxied" }
22 ]
23 },
24 { allowedStartRules: ["start"] }
25 );
26 });
27 });
28
29 describe("when a proxy rule is listed in |allowedStartRules|", function() {
30 it("updates references but doesn't remove it", function() {
31 expect(pass).toChangeAST(
32 [
33 'start = proxy',
34 'proxy = proxied',
35 'proxied = "a"'
36 ].join("\n"),
37 {
38 rules: [
39 {
40 name: "start",
41 expression: { type: "rule_ref", name: "proxied" }
42 },
43 {
44 name: "proxy",
45 expression: { type: "rule_ref", name: "proxied" }
46 },
47 { name: "proxied" }
48 ]
49 },
50 { allowedStartRules: ["start", "proxy"] }
51 );
52 });
53 });
54 });
0 /* global peg */
1
2 "use strict";
3
4 describe("compiler pass |reportDuplicateLabels|", function() {
5 var pass = peg.compiler.passes.check.reportDuplicateLabels;
6
7 describe("in a sequence", function() {
8 it("reports labels duplicate with labels of preceding elements", function() {
9 expect(pass).toReportError('start = a:"a" a:"a"', {
10 message: 'Label "a" is already defined at line 1, column 9.',
11 location: {
12 start: { offset: 14, line: 1, column: 15 },
13 end: { offset: 19, line: 1, column: 20 }
14 }
15 });
16 });
17
18 it("doesn't report labels duplicate with labels in subexpressions", function() {
19 expect(pass).not.toReportError('start = ("a" / a:"a" / "a") a:"a"');
20 expect(pass).not.toReportError('start = (a:"a" { }) a:"a"');
21 expect(pass).not.toReportError('start = ("a" a:"a" "a") a:"a"');
22 expect(pass).not.toReportError('start = b:(a:"a") a:"a"');
23 expect(pass).not.toReportError('start = $(a:"a") a:"a"');
24 expect(pass).not.toReportError('start = &(a:"a") a:"a"');
25 expect(pass).not.toReportError('start = !(a:"a") a:"a"');
26 expect(pass).not.toReportError('start = (a:"a")? a:"a"');
27 expect(pass).not.toReportError('start = (a:"a")* a:"a"');
28 expect(pass).not.toReportError('start = (a:"a")+ a:"a"');
29 expect(pass).not.toReportError('start = (a:"a") a:"a"');
30 });
31 });
32
33 describe("in a choice", function() {
34 it("doesn't report labels duplicate with labels of preceding alternatives", function() {
35 expect(pass).not.toReportError('start = a:"a" / a:"a"');
36 });
37 });
38
39 describe("in outer sequence", function() {
40 it("reports labels duplicate with labels of preceding elements", function() {
41 expect(pass).toReportError('start = a:"a" (a:"a")', {
42 message: 'Label "a" is already defined at line 1, column 9.',
43 location: {
44 start: { offset: 15, line: 1, column: 16 },
45 end: { offset: 20, line: 1, column: 21 }
46 }
47 });
48 });
49
50 it("doesn't report labels duplicate with the label of the current element", function() {
51 expect(pass).not.toReportError('start = a:(a:"a")');
52 });
53
54 it("doesn't report labels duplicate with labels of following elements", function() {
55 expect(pass).not.toReportError('start = (a:"a") a:"a"');
56 });
57 });
58 });
0 /* global peg */
1
2 "use strict";
3
4 describe("compiler pass |reportDuplicateRules|", function() {
5 var pass = peg.compiler.passes.check.reportDuplicateRules;
6
7 it("reports duplicate rules", function() {
8 expect(pass).toReportError([
9 'start = "a"',
10 'start = "b"'
11 ].join('\n'), {
12 message: 'Rule "start" is already defined at line 1, column 1.',
13 location: {
14 start: { offset: 12, line: 2, column: 1 },
15 end: { offset: 23, line: 2, column: 12 }
16 }
17 });
18 });
19 });
0 /* global peg */
1
2 "use strict";
3
4 describe("compiler pass |reportInfiniteRecursion|", function() {
5 var pass = peg.compiler.passes.check.reportInfiniteRecursion;
6
7 it("reports direct left recursion", function() {
8 expect(pass).toReportError('start = start', {
9 message: 'Possible infinite loop when parsing (left recursion: start -> start).',
10 location: {
11 start: { offset: 8, line: 1, column: 9 },
12 end: { offset: 13, line: 1, column: 14 }
13 }
14 });
15 });
16
17 it("reports indirect left recursion", function() {
18 expect(pass).toReportError([
19 'start = stop',
20 'stop = start'
21 ].join("\n"), {
22 message: 'Possible infinite loop when parsing (left recursion: start -> stop -> start).',
23 location: {
24 start: { offset: 21, line: 2, column: 9 },
25 end: { offset: 26, line: 2, column: 14 }
26 }
27 });
28 });
29
30 describe("in sequences", function() {
31 it("reports left recursion if all preceding elements match empty string", function() {
32 expect(pass).toReportError('start = "" "" "" start');
33 });
34
35 it("doesn't report left recursion if some preceding element doesn't match empty string", function() {
36 expect(pass).not.toReportError('start = "a" "" "" start');
37 expect(pass).not.toReportError('start = "" "a" "" start');
38 expect(pass).not.toReportError('start = "" "" "a" start');
39 });
40
41 /* Regression test for #359. */
42 it("reports left recursion when rule reference is wrapped in an expression", function() {
43 expect(pass).toReportError('start = "" start?');
44 });
45
46 it("computes expressions that always consume input on success correctly", function() {
47 expect(pass).toReportError([
48 'start = a start',
49 'a "a" = ""'
50 ].join('\n'));
51 expect(pass).not.toReportError([
52 'start = a start',
53 'a "a" = "a"'
54 ].join('\n'));
55
56 expect(pass).toReportError('start = ("" / "a" / "b") start');
57 expect(pass).toReportError('start = ("a" / "" / "b") start');
58 expect(pass).toReportError('start = ("a" / "b" / "") start');
59 expect(pass).not.toReportError('start = ("a" / "b" / "c") start');
60
61 expect(pass).toReportError('start = ("" { }) start');
62 expect(pass).not.toReportError('start = ("a" { }) start');
63
64 expect(pass).toReportError('start = ("" "" "") start');
65 expect(pass).not.toReportError('start = ("a" "" "") start');
66 expect(pass).not.toReportError('start = ("" "a" "") start');
67 expect(pass).not.toReportError('start = ("" "" "a") start');
68
69 expect(pass).toReportError('start = a:"" start');
70 expect(pass).not.toReportError('start = a:"a" start');
71
72 expect(pass).toReportError('start = $"" start');
73 expect(pass).not.toReportError('start = $"a" start');
74
75 expect(pass).toReportError('start = &"" start');
76 expect(pass).toReportError('start = &"a" start');
77
78 expect(pass).toReportError('start = !"" start');
79 expect(pass).toReportError('start = !"a" start');
80
81 expect(pass).toReportError('start = ""? start');
82 expect(pass).toReportError('start = "a"? start');
83
84 expect(pass).toReportError('start = ""* start');
85 expect(pass).toReportError('start = "a"* start');
86
87 expect(pass).toReportError('start = ""+ start');
88 expect(pass).not.toReportError('start = "a"+ start');
89
90 expect(pass).toReportError('start = ("") start');
91 expect(pass).not.toReportError('start = ("a") start');
92
93 expect(pass).toReportError('start = &{ } start');
94
95 expect(pass).toReportError('start = !{ } start');
96
97 expect(pass).toReportError([
98 'start = a start',
99 'a = ""'
100 ].join('\n'));
101 expect(pass).not.toReportError([
102 'start = a start',
103 'a = "a"'
104 ].join('\n'));
105
106 expect(pass).toReportError('start = "" start');
107 expect(pass).not.toReportError('start = "a" start');
108
109 expect(pass).not.toReportError('start = [a-d] start');
110
111 expect(pass).not.toReportError('start = . start');
112 });
113 });
114 });
0 /* global peg */
1
2 "use strict";
3
4 describe("compiler pass |reportInfiniteRepetition|", function() {
5 var pass = peg.compiler.passes.check.reportInfiniteRepetition;
6
7 it("reports infinite loops for zero_or_more", function() {
8 expect(pass).toReportError('start = ("")*', {
9 message: "Possible infinite loop when parsing (repetition used with an expression that may not consume any input).",
10 location: {
11 start: { offset: 8, line: 1, column: 9 },
12 end: { offset: 13, line: 1, column: 14 }
13 }
14 });
15 });
16
17 it("reports infinite loops for one_or_more", function() {
18 expect(pass).toReportError('start = ("")+', {
19 message: "Possible infinite loop when parsing (repetition used with an expression that may not consume any input).",
20 location: {
21 start: { offset: 8, line: 1, column: 9 },
22 end: { offset: 13, line: 1, column: 14 }
23 }
24 });
25 });
26
27 it("computes expressions that always consume input on success correctly", function() {
28 expect(pass).toReportError([
29 'start = a*',
30 'a "a" = ""'
31 ].join('\n'));
32 expect(pass).not.toReportError([
33 'start = a*',
34 'a "a" = "a"'
35 ].join('\n'));
36
37 expect(pass).toReportError('start = ("" / "a" / "b")*');
38 expect(pass).toReportError('start = ("a" / "" / "b")*');
39 expect(pass).toReportError('start = ("a" / "b" / "")*');
40 expect(pass).not.toReportError('start = ("a" / "b" / "c")*');
41
42 expect(pass).toReportError('start = ("" { })*');
43 expect(pass).not.toReportError('start = ("a" { })*');
44
45 expect(pass).toReportError('start = ("" "" "")*');
46 expect(pass).not.toReportError('start = ("a" "" "")*');
47 expect(pass).not.toReportError('start = ("" "a" "")*');
48 expect(pass).not.toReportError('start = ("" "" "a")*');
49
50 expect(pass).toReportError('start = (a:"")*');
51 expect(pass).not.toReportError('start = (a:"a")*');
52
53 expect(pass).toReportError('start = ($"")*');
54 expect(pass).not.toReportError('start = ($"a")*');
55
56 expect(pass).toReportError('start = (&"")*');
57 expect(pass).toReportError('start = (&"a")*');
58
59 expect(pass).toReportError('start = (!"")*');
60 expect(pass).toReportError('start = (!"a")*');
61
62 expect(pass).toReportError('start = (""?)*');
63 expect(pass).toReportError('start = ("a"?)*');
64
65 expect(pass).toReportError('start = (""*)*');
66 expect(pass).toReportError('start = ("a"*)*');
67
68 expect(pass).toReportError('start = (""+)*');
69 expect(pass).not.toReportError('start = ("a"+)*');
70
71 expect(pass).toReportError('start = ("")*');
72 expect(pass).not.toReportError('start = ("a")*');
73
74 expect(pass).toReportError('start = (&{ })*');
75
76 expect(pass).toReportError('start = (!{ })*');
77
78 expect(pass).toReportError([
79 'start = a*',
80 'a = ""'
81 ].join('\n'));
82 expect(pass).not.toReportError([
83 'start = a*',
84 'a = "a"'
85 ].join('\n'));
86
87 expect(pass).toReportError('start = ""*');
88 expect(pass).not.toReportError('start = "a"*');
89
90 expect(pass).not.toReportError('start = [a-d]*');
91
92 expect(pass).not.toReportError('start = .*');
93 });
94 });
0 /* global peg */
1
2 "use strict";
3
4 describe("compiler pass |reportUndefinedRules|", function() {
5 var pass = peg.compiler.passes.check.reportUndefinedRules;
6
7 it("reports undefined rules", function() {
8 expect(pass).toReportError('start = undefined', {
9 message: 'Rule "undefined" is not defined.',
10 location: {
11 start: { offset: 8, line: 1, column: 9 },
12 end: { offset: 17, line: 1, column: 18 }
13 }
14 });
15 });
16 });
0 /* global peg */
1
2 "use strict";
3
4 describe("PEG.js grammar parser", function() {
5 var literalAbcd = { type: "literal", value: "abcd", ignoreCase: false },
6 literalEfgh = { type: "literal", value: "efgh", ignoreCase: false },
7 literalIjkl = { type: "literal", value: "ijkl", ignoreCase: false },
8 literalMnop = { type: "literal", value: "mnop", ignoreCase: false },
9 semanticAnd = { type: "semantic_and", code: " code " },
10 semanticNot = { type: "semantic_not", code: " code " },
11 optional = { type: "optional", expression: literalAbcd },
12 zeroOrMore = { type: "zero_or_more", expression: literalAbcd },
13 oneOrMore = { type: "one_or_more", expression: literalAbcd },
14 textOptional = { type: "text", expression: optional },
15 simpleNotAbcd = { type: "simple_not", expression: literalAbcd },
16 simpleAndOptional = { type: "simple_and", expression: optional },
17 simpleNotOptional = { type: "simple_not", expression: optional },
18 labeledAbcd = { type: "labeled", label: "a", expression: literalAbcd },
19 labeledEfgh = { type: "labeled", label: "b", expression: literalEfgh },
20 labeledIjkl = { type: "labeled", label: "c", expression: literalIjkl },
21 labeledMnop = { type: "labeled", label: "d", expression: literalMnop },
22 labeledSimpleNot = { type: "labeled", label: "a", expression: simpleNotAbcd },
23 sequence = {
24 type: "sequence",
25 elements: [literalAbcd, literalEfgh, literalIjkl]
26 },
27 sequence2 = {
28 type: "sequence",
29 elements: [labeledAbcd, labeledEfgh]
30 },
31 sequence4 = {
32 type: "sequence",
33 elements: [labeledAbcd, labeledEfgh, labeledIjkl, labeledMnop]
34 },
35 groupLabeled = { type: "group", expression: labeledAbcd },
36 groupSequence = { type: "group", expression: sequence },
37 actionAbcd = { type: "action", expression: literalAbcd, code: " code " },
38 actionEfgh = { type: "action", expression: literalEfgh, code: " code " },
39 actionIjkl = { type: "action", expression: literalIjkl, code: " code " },
40 actionMnop = { type: "action", expression: literalMnop, code: " code " },
41 actionSequence = { type: "action", expression: sequence, code: " code " },
42 choice = {
43 type: "choice",
44 alternatives: [literalAbcd, literalEfgh, literalIjkl]
45 },
46 choice2 = {
47 type: "choice",
48 alternatives: [actionAbcd, actionEfgh]
49 },
50 choice4 = {
51 type: "choice",
52 alternatives: [actionAbcd, actionEfgh, actionIjkl, actionMnop]
53 },
54 named = { type: "named", name: "start rule", expression: literalAbcd },
55 ruleA = { type: "rule", name: "a", expression: literalAbcd },
56 ruleB = { type: "rule", name: "b", expression: literalEfgh },
57 ruleC = { type: "rule", name: "c", expression: literalIjkl },
58 ruleStart = { type: "rule", name: "start", expression: literalAbcd },
59 initializer = { type: "initializer", code: " code " };
60
61 function oneRuleGrammar(expression) {
62 return {
63 type: "grammar",
64 initializer: null,
65 rules: [{ type: "rule", name: "start", expression: expression }]
66 };
67 }
68
69 function actionGrammar(code) {
70 return oneRuleGrammar(
71 { type: "action", expression: literalAbcd, code: code }
72 );
73 }
74
75 function literalGrammar(value, ignoreCase) {
76 return oneRuleGrammar(
77 { type: "literal", value: value, ignoreCase: ignoreCase }
78 );
79 }
80
81 function classGrammar(parts, inverted, ignoreCase) {
82 return oneRuleGrammar({
83 type: "class",
84 parts: parts,
85 inverted: inverted,
86 ignoreCase: ignoreCase
87 });
88 }
89
90 function anyGrammar() {
91 return oneRuleGrammar({ type: "any" });
92 }
93
94 function ruleRefGrammar(name) {
95 return oneRuleGrammar({ type: "rule_ref", name: name });
96 }
97
98 var trivialGrammar = literalGrammar("abcd", false),
99 twoRuleGrammar = {
100 type: "grammar",
101 initializer: null,
102 rules: [ruleA, ruleB]
103 };
104
105 var stripLocation = (function() {
106 function buildVisitor(functions) {
107 return function(node) {
108 return functions[node.type].apply(null, arguments);
109 };
110 }
111
112 function stripLeaf(node) {
113 delete node.location;
114 }
115
116 function stripExpression(node) {
117 delete node.location;
118
119 strip(node.expression);
120 }
121
122 function stripChildren(property) {
123 return function(node) {
124 var i;
125
126 delete node.location;
127
128 for (i = 0; i < node[property].length; i++) {
129 strip(node[property][i]);
130 }
131 };
132 }
133
134 var strip = buildVisitor({
135 grammar: function(node) {
136 var i;
137
138 delete node.location;
139
140 if (node.initializer) {
141 strip(node.initializer);
142 }
143
144 for (i = 0; i < node.rules.length; i++) {
145 strip(node.rules[i]);
146 }
147 },
148
149 initializer: stripLeaf,
150 rule: stripExpression,
151 named: stripExpression,
152 choice: stripChildren("alternatives"),
153 action: stripExpression,
154 sequence: stripChildren("elements"),
155 labeled: stripExpression,
156 text: stripExpression,
157 simple_and: stripExpression,
158 simple_not: stripExpression,
159 optional: stripExpression,
160 zero_or_more: stripExpression,
161 one_or_more: stripExpression,
162 group: stripExpression,
163 semantic_and: stripLeaf,
164 semantic_not: stripLeaf,
165 rule_ref: stripLeaf,
166 literal: stripLeaf,
167 "class": stripLeaf,
168 any: stripLeaf
169 });
170
171 return strip;
172 })();
173
174 beforeEach(function() {
175 this.addMatchers({
176 toParseAs: function(expected) {
177 var result;
178
179 try {
180 result = peg.parser.parse(this.actual);
181 } catch (e) {
182 this.message = function() {
183 return "Expected " + jasmine.pp(this.actual) + " "
184 + "to parse as " + jasmine.pp(expected) + ", "
185 + "but it failed to parse with message "
186 + jasmine.pp(e.message) + ".";
187 };
188
189 return false;
190 }
191
192 stripLocation(result);
193
194 this.message = function() {
195 return "Expected " + jasmine.pp(this.actual) + " "
196 + (this.isNot ? "not " : "")
197 + "to parse as " + jasmine.pp(expected) + ", "
198 + "but it parsed as " + jasmine.pp(result) + ".";
199 };
200
201 return this.env.equals_(result, expected);
202 },
203
204 toFailToParse: function(details) {
205 var result, key;
206
207 try {
208 result = peg.parser.parse(this.actual);
209 } catch (e) {
210 if (this.isNot) {
211 this.message = function() {
212 return "Expected " + jasmine.pp(this.actual) + " to parse, "
213 + "but it failed with message "
214 + jasmine.pp(e.message) + ".";
215 };
216 } else {
217 if (details) {
218 for (key in details) {
219 if (details.hasOwnProperty(key)) {
220 if (!this.env.equals_(e[key], details[key])) {
221 this.message = function() {
222 return "Expected " + jasmine.pp(this.actual) + " to fail to parse"
223 + (details ? " with details " + jasmine.pp(details) : "") + ", "
224 + "but " + jasmine.pp(key) + " "
225 + "is " + jasmine.pp(e[key]) + ".";
226 };
227
228 return false;
229 }
230 }
231 }
232 }
233 }
234
235 return true;
236 }
237
238 stripLocation(result);
239
240 this.message = function() {
241 return "Expected " + jasmine.pp(this.actual) + " to fail to parse"
242 + (details ? " with details " + jasmine.pp(details) : "") + ", "
243 + "but it parsed as " + jasmine.pp(result) + ".";
244 };
245
246 return false;
247 }
248 });
249 });
250
251 /* Canonical Grammar is "a = \"abcd\"; b = \"efgh\"; c = \"ijkl\";". */
252 it("parses Grammar", function() {
253 expect('\na = "abcd";\n').toParseAs(
254 { type: "grammar", initializer: null, rules: [ruleA] }
255 );
256 expect('\na = "abcd";\nb = "efgh";\nc = "ijkl";\n').toParseAs(
257 { type: "grammar", initializer: null, rules: [ruleA, ruleB, ruleC] }
258 );
259 expect('\n{ code };\na = "abcd";\n').toParseAs(
260 { type: "grammar", initializer: initializer, rules: [ruleA] }
261 );
262 });
263
264 /* Canonical Initializer is "{ code }". */
265 it("parses Initializer", function() {
266 expect('{ code };start = "abcd"').toParseAs(
267 { type: "grammar", initializer: initializer, rules: [ruleStart] }
268 );
269 });
270
271 /* Canonical Rule is "a = \"abcd\";". */
272 it("parses Rule", function() {
273 expect('start\n=\n"abcd";').toParseAs(
274 oneRuleGrammar(literalAbcd)
275 );
276 expect('start\n"start rule"\n=\n"abcd";').toParseAs(
277 oneRuleGrammar(named)
278 );
279 });
280
281 /* Canonical Expression is "\"abcd\"". */
282 it("parses Expression", function() {
283 expect('start = "abcd" / "efgh" / "ijkl"').toParseAs(
284 oneRuleGrammar(choice)
285 );
286 });
287
288 /* Canonical ChoiceExpression is "\"abcd\" / \"efgh\" / \"ijkl\"". */
289 it("parses ChoiceExpression", function() {
290 expect('start = "abcd" { code }').toParseAs(
291 oneRuleGrammar(actionAbcd)
292 );
293 expect('start = "abcd" { code }\n/\n"efgh" { code }').toParseAs(
294 oneRuleGrammar(choice2)
295 );
296 expect(
297 'start = "abcd" { code }\n/\n"efgh" { code }\n/\n"ijkl" { code }\n/\n"mnop" { code }'
298 ).toParseAs(
299 oneRuleGrammar(choice4)
300 );
301 });
302
303 /* Canonical ActionExpression is "\"abcd\" { code }". */
304 it("parses ActionExpression", function() {
305 expect('start = "abcd" "efgh" "ijkl"').toParseAs(
306 oneRuleGrammar(sequence)
307 );
308 expect('start = "abcd" "efgh" "ijkl"\n{ code }').toParseAs(
309 oneRuleGrammar(actionSequence)
310 );
311 });
312
313 /* Canonical SequenceExpression is "\"abcd\" \"efgh\" \"ijkl\"". */
314 it("parses SequenceExpression", function() {
315 expect('start = a:"abcd"').toParseAs(
316 oneRuleGrammar(labeledAbcd)
317 );
318 expect('start = a:"abcd"\nb:"efgh"').toParseAs(
319 oneRuleGrammar(sequence2)
320 );
321 expect('start = a:"abcd"\nb:"efgh"\nc:"ijkl"\nd:"mnop"').toParseAs(
322 oneRuleGrammar(sequence4)
323 );
324 });
325
326 /* Canonical LabeledExpression is "a:\"abcd\"". */
327 it("parses LabeledExpression", function() {
328 expect('start = a\n:\n!"abcd"').toParseAs(oneRuleGrammar(labeledSimpleNot));
329 expect('start = !"abcd"' ).toParseAs(oneRuleGrammar(simpleNotAbcd));
330 });
331
332 /* Canonical PrefixedExpression is "!\"abcd\"". */
333 it("parses PrefixedExpression", function() {
334 expect('start = !\n"abcd"?' ).toParseAs(oneRuleGrammar(simpleNotOptional));
335 expect('start = "abcd"?' ).toParseAs(oneRuleGrammar(optional));
336 });
337
338 /* Canonical PrefixedOperator is "!". */
339 it("parses PrefixedOperator", function() {
340 expect('start = $"abcd"?').toParseAs(oneRuleGrammar(textOptional));
341 expect('start = &"abcd"?').toParseAs(oneRuleGrammar(simpleAndOptional));
342 expect('start = !"abcd"?').toParseAs(oneRuleGrammar(simpleNotOptional));
343 });
344
345 /* Canonical SuffixedExpression is "\"ebcd\"?". */
346 it("parses SuffixedExpression", function() {
347 expect('start = "abcd"\n?').toParseAs(oneRuleGrammar(optional));
348 expect('start = "abcd"' ).toParseAs(oneRuleGrammar(literalAbcd));
349 });
350
351 /* Canonical SuffixedOperator is "?". */
352 it("parses SuffixedOperator", function() {
353 expect('start = "abcd"?').toParseAs(oneRuleGrammar(optional));
354 expect('start = "abcd"*').toParseAs(oneRuleGrammar(zeroOrMore));
355 expect('start = "abcd"+').toParseAs(oneRuleGrammar(oneOrMore));
356 });
357
358 /* Canonical PrimaryExpression is "\"abcd\"". */
359 it("parses PrimaryExpression", function() {
360 expect('start = "abcd"' ).toParseAs(trivialGrammar);
361 expect('start = [a-d]' ).toParseAs(classGrammar([["a", "d"]], false, false));
362 expect('start = .' ).toParseAs(anyGrammar());
363 expect('start = a' ).toParseAs(ruleRefGrammar("a"));
364 expect('start = &{ code }').toParseAs(oneRuleGrammar(semanticAnd));
365
366 expect('start = (\na:"abcd"\n)' ).toParseAs(oneRuleGrammar(groupLabeled));
367 expect('start = (\n"abcd" "efgh" "ijkl"\n)').toParseAs(oneRuleGrammar(groupSequence));
368 expect('start = (\n"abcd"\n)' ).toParseAs(trivialGrammar);
369 });
370
371 /* Canonical RuleReferenceExpression is "a". */
372 it("parses RuleReferenceExpression", function() {
373 expect('start = a').toParseAs(ruleRefGrammar("a"));
374
375 expect('start = a\n=' ).toFailToParse();
376 expect('start = a\n"abcd"\n=').toFailToParse();
377 });
378
379 /* Canonical SemanticPredicateExpression is "!{ code }". */
380 it("parses SemanticPredicateExpression", function() {
381 expect('start = !\n{ code }').toParseAs(oneRuleGrammar(semanticNot));
382 });
383
384 /* Canonical SemanticPredicateOperator is "!". */
385 it("parses SemanticPredicateOperator", function() {
386 expect('start = &{ code }').toParseAs(oneRuleGrammar(semanticAnd));
387 expect('start = !{ code }').toParseAs(oneRuleGrammar(semanticNot));
388 });
389
390 /* The SourceCharacter rule is not tested. */
391
392 /* Canonical WhiteSpace is " ". */
393 it("parses WhiteSpace", function() {
394 expect('start =\t"abcd"' ).toParseAs(trivialGrammar);
395 expect('start =\x0B"abcd"' ).toParseAs(trivialGrammar); // no "\v" in IE
396 expect('start =\f"abcd"' ).toParseAs(trivialGrammar);
397 expect('start = "abcd"' ).toParseAs(trivialGrammar);
398 expect('start =\u00A0"abcd"').toParseAs(trivialGrammar);
399 expect('start =\uFEFF"abcd"').toParseAs(trivialGrammar);
400 expect('start =\u1680"abcd"').toParseAs(trivialGrammar);
401 });
402
403 /* Canonical LineTerminator is "\n". */
404 it("parses LineTerminator", function() {
405 expect('start = "\n"' ).toFailToParse();
406 expect('start = "\r"' ).toFailToParse();
407 expect('start = "\u2028"').toFailToParse();
408 expect('start = "\u2029"').toFailToParse();
409 });
410
411 /* Canonical LineTerminatorSequence is "\r\n". */
412 it("parses LineTerminatorSequence", function() {
413 expect('start =\n"abcd"' ).toParseAs(trivialGrammar);
414 expect('start =\r\n"abcd"' ).toParseAs(trivialGrammar);
415 expect('start =\r"abcd"' ).toParseAs(trivialGrammar);
416 expect('start =\u2028"abcd"').toParseAs(trivialGrammar);
417 expect('start =\u2029"abcd"').toParseAs(trivialGrammar);
418 });
419
420 // Canonical Comment is "/* comment */".
421 it("parses Comment", function() {
422 expect('start =// comment\n"abcd"' ).toParseAs(trivialGrammar);
423 expect('start =/* comment */"abcd"').toParseAs(trivialGrammar);
424 });
425
426 // Canonical MultiLineComment is "/* comment */".
427 it("parses MultiLineComment", function() {
428 expect('start =/**/"abcd"' ).toParseAs(trivialGrammar);
429 expect('start =/*a*/"abcd"' ).toParseAs(trivialGrammar);
430 expect('start =/*abc*/"abcd"').toParseAs(trivialGrammar);
431
432 expect('start =/**/*/"abcd"').toFailToParse();
433 });
434
435 // Canonical MultiLineCommentNoLineTerminator is "/* comment */".
436 it("parses MultiLineCommentNoLineTerminator", function() {
437 expect('a = "abcd"/**/\r\nb = "efgh"' ).toParseAs(twoRuleGrammar);
438 expect('a = "abcd"/*a*/\r\nb = "efgh"' ).toParseAs(twoRuleGrammar);
439 expect('a = "abcd"/*abc*/\r\nb = "efgh"').toParseAs(twoRuleGrammar);
440
441 expect('a = "abcd"/**/*/\r\nb = "efgh"').toFailToParse();
442 expect('a = "abcd"/*\n*/\r\nb = "efgh"').toFailToParse();
443 });
444
445 /* Canonical SingleLineComment is "// comment". */
446 it("parses SingleLineComment", function() {
447 expect('start =//\n"abcd"' ).toParseAs(trivialGrammar);
448 expect('start =//a\n"abcd"' ).toParseAs(trivialGrammar);
449 expect('start =//abc\n"abcd"').toParseAs(trivialGrammar);
450
451 expect('start =//\n@\n"abcd"').toFailToParse();
452 });
453
454 /* Canonical Identifier is "a". */
455 it("parses Identifier", function() {
456 expect('start = a:"abcd"').toParseAs(oneRuleGrammar(labeledAbcd));
457 });
458
459 /* Canonical IdentifierName is "a". */
460 it("parses IdentifierName", function() {
461 expect('start = a' ).toParseAs(ruleRefGrammar("a"));
462 expect('start = ab' ).toParseAs(ruleRefGrammar("ab"));
463 expect('start = abcd').toParseAs(ruleRefGrammar("abcd"));
464 });
465
466 /* Canonical IdentifierStart is "a". */
467 it("parses IdentifierStart", function() {
468 expect('start = a' ).toParseAs(ruleRefGrammar("a"));
469 expect('start = $' ).toParseAs(ruleRefGrammar("$"));
470 expect('start = _' ).toParseAs(ruleRefGrammar("_"));
471 expect('start = \\u0061').toParseAs(ruleRefGrammar("a"));
472 });
473
474 /* Canonical IdentifierPart is "a". */
475 it("parses IdentifierPart", function() {
476 expect('start = aa' ).toParseAs(ruleRefGrammar("aa"));
477 expect('start = a\u0300').toParseAs(ruleRefGrammar("a\u0300"));
478 expect('start = a0' ).toParseAs(ruleRefGrammar("a0"));
479 expect('start = a\u203F').toParseAs(ruleRefGrammar("a\u203F"));
480 expect('start = a\u200C').toParseAs(ruleRefGrammar("a\u200C"));
481 expect('start = a\u200D').toParseAs(ruleRefGrammar("a\u200D"));
482 });
483
484 /* Unicode rules and reserved word rules are not tested. */
485
486 /* Canonical LiteralMatcher is "\"abcd\"". */
487 it("parses LiteralMatcher", function() {
488 expect('start = "abcd"' ).toParseAs(literalGrammar("abcd", false));
489 expect('start = "abcd"i').toParseAs(literalGrammar("abcd", true));
490 });
491
492 /* Canonical StringLiteral is "\"abcd\"". */
493 it("parses StringLiteral", function() {
494 expect('start = ""' ).toParseAs(literalGrammar("", false));
495 expect('start = "a"' ).toParseAs(literalGrammar("a", false));
496 expect('start = "abc"').toParseAs(literalGrammar("abc", false));
497
498 expect("start = ''" ).toParseAs(literalGrammar("", false));
499 expect("start = 'a'" ).toParseAs(literalGrammar("a", false));
500 expect("start = 'abc'").toParseAs(literalGrammar("abc", false));
501 });
502
503 /* Canonical DoubleStringCharacter is "a". */
504 it("parses DoubleStringCharacter", function() {
505 expect('start = "a"' ).toParseAs(literalGrammar("a", false));
506 expect('start = "\\n"' ).toParseAs(literalGrammar("\n", false));
507 expect('start = "\\\n"').toParseAs(literalGrammar("", false));
508
509 expect('start = """' ).toFailToParse();
510 expect('start = "\\"').toFailToParse();
511 expect('start = "\n"').toFailToParse();
512 });
513
514 /* Canonical SingleStringCharacter is "a". */
515 it("parses SingleStringCharacter", function() {
516 expect("start = 'a'" ).toParseAs(literalGrammar("a", false));
517 expect("start = '\\n'" ).toParseAs(literalGrammar("\n", false));
518 expect("start = '\\\n'").toParseAs(literalGrammar("", false));
519
520 expect("start = '''" ).toFailToParse();
521 expect("start = '\\'").toFailToParse();
522 expect("start = '\n'").toFailToParse();
523 });
524
525 /* Canonical CharacterClassMatcher is "[a-d]". */
526 it("parses CharacterClassMatcher", function() {
527 expect('start = []').toParseAs(
528 classGrammar([], false, false)
529 );
530 expect('start = [a-d]').toParseAs(
531 classGrammar([["a", "d"]], false, false)
532 );
533 expect('start = [a]').toParseAs(
534 classGrammar(["a"], false, false)
535 );
536 expect('start = [a-de-hi-l]').toParseAs(
537 classGrammar(
538 [["a", "d"], ["e", "h"], ["i", "l"]],
539 false,
540 false
541 )
542 );
543 expect('start = [^a-d]').toParseAs(
544 classGrammar([["a", "d"]], true, false)
545 );
546 expect('start = [a-d]i').toParseAs(
547 classGrammar([["a", "d"]], false, true)
548 );
549
550 expect('start = [\\\n]').toParseAs(
551 classGrammar([], false, false)
552 );
553 });
554
555 /* Canonical ClassCharacterRange is "a-d". */
556 it("parses ClassCharacterRange", function() {
557 expect('start = [a-d]').toParseAs(classGrammar([["a", "d"]], false, false));
558
559 expect('start = [a-a]').toParseAs(classGrammar([["a", "a"]], false, false));
560 expect('start = [b-a]').toFailToParse({
561 message: "Invalid character range: b-a."
562 });
563 });
564
565 /* Canonical ClassCharacter is "a". */
566 it("parses ClassCharacter", function() {
567 expect('start = [a]' ).toParseAs(classGrammar(["a"], false, false));
568 expect('start = [\\n]' ).toParseAs(classGrammar(["\n"], false, false));
569 expect('start = [\\\n]').toParseAs(classGrammar([], false, false));
570
571 expect('start = []]' ).toFailToParse();
572 expect('start = [\\]').toFailToParse();
573 expect('start = [\n]').toFailToParse();
574 });
575
576 /* Canonical LineContinuation is "\\\n". */
577 it("parses LineContinuation", function() {
578 expect('start = "\\\r\n"').toParseAs(literalGrammar("", false));
579 });
580
581 /* Canonical EscapeSequence is "n". */
582 it("parses EscapeSequence", function() {
583 expect('start = "\\n"' ).toParseAs(literalGrammar("\n", false));
584 expect('start = "\\0"' ).toParseAs(literalGrammar("\x00", false));
585 expect('start = "\\xFF"' ).toParseAs(literalGrammar("\xFF", false));
586 expect('start = "\\uFFFF"').toParseAs(literalGrammar("\uFFFF", false));
587
588 expect('start = "\\09"').toFailToParse();
589 });
590
591 /* Canonical CharacterEscapeSequence is "n". */
592 it("parses CharacterEscapeSequence", function() {
593 expect('start = "\\n"').toParseAs(literalGrammar("\n", false));
594 expect('start = "\\a"').toParseAs(literalGrammar("a", false));
595 });
596
597 /* Canonical SingleEscapeCharacter is "n". */
598 it("parses SingleEscapeCharacter", function() {
599 expect('start = "\\\'"').toParseAs(literalGrammar("'", false));
600 expect('start = "\\""' ).toParseAs(literalGrammar('"', false));
601 expect('start = "\\\\"').toParseAs(literalGrammar("\\", false));
602 expect('start = "\\b"' ).toParseAs(literalGrammar("\b", false));
603 expect('start = "\\f"' ).toParseAs(literalGrammar("\f", false));
604 expect('start = "\\n"' ).toParseAs(literalGrammar("\n", false));
605 expect('start = "\\r"' ).toParseAs(literalGrammar("\r", false));
606 expect('start = "\\t"' ).toParseAs(literalGrammar("\t", false));
607 expect('start = "\\v"' ).toParseAs(literalGrammar("\x0B", false)); // no "\v" in IE
608 });
609
610 /* Canonical NonEscapeCharacter is "a". */
611 it("parses NonEscapeCharacter", function() {
612 expect('start = "\\a"').toParseAs(literalGrammar("a", false));
613
614 /*
615 * The negative predicate is impossible to test with PEG.js grammar
616 * structure.
617 */
618 });
619
620 /*
621 * The EscapeCharacter rule is impossible to test with PEG.js grammar
622 * structure.
623 */
624
625 /* Canonical HexEscapeSequence is "xFF". */
626 it("parses HexEscapeSequence", function() {
627 expect('start = "\\xFF"').toParseAs(literalGrammar("\xFF", false));
628 });
629
630 /* Canonical UnicodeEscapeSequence is "uFFFF". */
631 it("parses UnicodeEscapeSequence", function() {
632 expect('start = "\\uFFFF"').toParseAs(literalGrammar("\uFFFF", false));
633 });
634
635 /* Digit rules are not tested. */
636
637 /* Canonical AnyMatcher is ".". */
638 it("parses AnyMatcher", function() {
639 expect('start = .').toParseAs(anyGrammar());
640 });
641
642 /* Canonical CodeBlock is "{ code }". */
643 it("parses CodeBlock", function() {
644 expect('start = "abcd" { code }').toParseAs(actionGrammar(" code "));
645 });
646
647 /* Canonical Code is " code ". */
648 it("parses Code", function() {
649 expect('start = "abcd" {a}' ).toParseAs(actionGrammar("a"));
650 expect('start = "abcd" {abc}' ).toParseAs(actionGrammar("abc"));
651 expect('start = "abcd" {{a}}' ).toParseAs(actionGrammar("{a}"));
652 expect('start = "abcd" {{a}{b}{c}}').toParseAs(actionGrammar("{a}{b}{c}"));
653
654 expect('start = "abcd" {{}').toFailToParse();
655 expect('start = "abcd" {}}').toFailToParse();
656 });
657
658 /* Unicode character category rules and token rules are not tested. */
659
660 /* Canonical __ is "\n". */
661 it("parses __", function() {
662 expect('start ="abcd"' ).toParseAs(trivialGrammar);
663 expect('start = "abcd"' ).toParseAs(trivialGrammar);
664 expect('start =\r\n"abcd"' ).toParseAs(trivialGrammar);
665 expect('start =/* comment */"abcd"').toParseAs(trivialGrammar);
666 expect('start = "abcd"' ).toParseAs(trivialGrammar);
667 });
668
669 /* Canonical _ is " ". */
670 it("parses _", function() {
671 expect('a = "abcd"\r\nb = "efgh"' ).toParseAs(twoRuleGrammar);
672 expect('a = "abcd" \r\nb = "efgh"' ).toParseAs(twoRuleGrammar);
673 expect('a = "abcd"/* comment */\r\nb = "efgh"').toParseAs(twoRuleGrammar);
674 expect('a = "abcd" \r\nb = "efgh"' ).toParseAs(twoRuleGrammar);
675 });
676
677 /* Canonical EOS is ";". */
678 it("parses EOS", function() {
679 expect('a = "abcd"\n;b = "efgh"' ).toParseAs(twoRuleGrammar);
680 expect('a = "abcd" \r\nb = "efgh"' ).toParseAs(twoRuleGrammar);
681 expect('a = "abcd" // comment\r\nb = "efgh"').toParseAs(twoRuleGrammar);
682 expect('a = "abcd"\nb = "efgh"' ).toParseAs(twoRuleGrammar);
683 });
684
685 /* Canonical EOF is the end of input. */
686 it("parses EOF", function() {
687 expect('start = "abcd"\n').toParseAs(trivialGrammar);
688 });
689 });
0 Copyright (c) 2008-2011 Pivotal Labs
1
2 Permission is hereby granted, free of charge, to any person obtaining
3 a copy of this software and associated documentation files (the
4 "Software"), to deal in the Software without restriction, including
5 without limitation the rights to use, copy, modify, merge, publish,
6 distribute, sublicense, and/or sell copies of the Software, and to
7 permit persons to whom the Software is furnished to do so, subject to
8 the following conditions:
9
10 The above copyright notice and this permission notice shall be
11 included in all copies or substantial portions of the Software.
12
13 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
15 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
17 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
18 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
19 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
0 jasmine.HtmlReporterHelpers = {};
1
2 jasmine.HtmlReporterHelpers.createDom = function(type, attrs, childrenVarArgs) {
3 var el = document.createElement(type);
4
5 for (var i = 2; i < arguments.length; i++) {
6 var child = arguments[i];
7
8 if (typeof child === 'string') {
9 el.appendChild(document.createTextNode(child));
10 } else {
11 if (child) {
12 el.appendChild(child);
13 }
14 }
15 }
16
17 for (var attr in attrs) {
18 if (attr == "className") {
19 el[attr] = attrs[attr];
20 } else {
21 el.setAttribute(attr, attrs[attr]);
22 }
23 }
24
25 return el;
26 };
27
28 jasmine.HtmlReporterHelpers.getSpecStatus = function(child) {
29 var results = child.results();
30 var status = results.passed() ? 'passed' : 'failed';
31 if (results.skipped) {
32 status = 'skipped';
33 }
34
35 return status;
36 };
37
38 jasmine.HtmlReporterHelpers.appendToSummary = function(child, childElement) {
39 var parentDiv = this.dom.summary;
40 var parentSuite = (typeof child.parentSuite == 'undefined') ? 'suite' : 'parentSuite';
41 var parent = child[parentSuite];
42
43 if (parent) {
44 if (typeof this.views.suites[parent.id] == 'undefined') {
45 this.views.suites[parent.id] = new jasmine.HtmlReporter.SuiteView(parent, this.dom, this.views);
46 }
47 parentDiv = this.views.suites[parent.id].element;
48 }
49
50 parentDiv.appendChild(childElement);
51 };
52
53
54 jasmine.HtmlReporterHelpers.addHelpers = function(ctor) {
55 for(var fn in jasmine.HtmlReporterHelpers) {
56 ctor.prototype[fn] = jasmine.HtmlReporterHelpers[fn];
57 }
58 };
59
60 jasmine.HtmlReporter = function(_doc) {
61 var self = this;
62 var doc = _doc || window.document;
63
64 var reporterView;
65
66 var dom = {};
67
68 // Jasmine Reporter Public Interface
69 self.logRunningSpecs = false;
70
71 self.reportRunnerStarting = function(runner) {
72 var specs = runner.specs() || [];
73
74 if (specs.length == 0) {
75 return;
76 }
77
78 createReporterDom(runner.env.versionString());
79 doc.body.appendChild(dom.reporter);
80 setExceptionHandling();
81
82 reporterView = new jasmine.HtmlReporter.ReporterView(dom);
83 reporterView.addSpecs(specs, self.specFilter);
84 };
85
86 self.reportRunnerResults = function(runner) {
87 reporterView && reporterView.complete();
88 };
89
90 self.reportSuiteResults = function(suite) {
91 reporterView.suiteComplete(suite);
92 };
93
94 self.reportSpecStarting = function(spec) {
95 if (self.logRunningSpecs) {
96 self.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
97 }
98 };
99
100 self.reportSpecResults = function(spec) {
101 reporterView.specComplete(spec);
102 };
103
104 self.log = function() {
105 var console = jasmine.getGlobal().console;
106 if (console && console.log) {
107 if (console.log.apply) {
108 console.log.apply(console, arguments);
109 } else {
110 console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
111 }
112 }
113 };
114
115 self.specFilter = function(spec) {
116 if (!focusedSpecName()) {
117 return true;
118 }
119
120 return spec.getFullName().indexOf(focusedSpecName()) === 0;
121 };
122
123 return self;
124
125 function focusedSpecName() {
126 var specName;
127
128 (function memoizeFocusedSpec() {
129 if (specName) {
130 return;
131 }
132
133 var paramMap = [];
134 var params = jasmine.HtmlReporter.parameters(doc);
135
136 for (var i = 0; i < params.length; i++) {
137 var p = params[i].split('=');
138 paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
139 }
140
141 specName = paramMap.spec;
142 })();
143
144 return specName;
145 }
146
147 function createReporterDom(version) {
148 dom.reporter = self.createDom('div', { id: 'HTMLReporter', className: 'jasmine_reporter' },
149 dom.banner = self.createDom('div', { className: 'banner' },
150 self.createDom('span', { className: 'title' }, "Jasmine "),
151 self.createDom('span', { className: 'version' }, version)),
152
153 dom.symbolSummary = self.createDom('ul', {className: 'symbolSummary'}),
154 dom.alert = self.createDom('div', {className: 'alert'},
155 self.createDom('span', { className: 'exceptions' },
156 self.createDom('label', { className: 'label', 'for': 'no_try_catch' }, 'No try/catch'),
157 self.createDom('input', { id: 'no_try_catch', type: 'checkbox' }))),
158 dom.results = self.createDom('div', {className: 'results'},
159 dom.summary = self.createDom('div', { className: 'summary' }),
160 dom.details = self.createDom('div', { id: 'details' }))
161 );
162 }
163
164 function noTryCatch() {
165 return window.location.search.match(/catch=false/);
166 }
167
168 function searchWithCatch() {
169 var params = jasmine.HtmlReporter.parameters(window.document);
170 var removed = false;
171 var i = 0;
172
173 while (!removed && i < params.length) {
174 if (params[i].match(/catch=/)) {
175 params.splice(i, 1);
176 removed = true;
177 }
178 i++;
179 }
180 if (jasmine.CATCH_EXCEPTIONS) {
181 params.push("catch=false");
182 }
183
184 return params.join("&");
185 }
186
187 function setExceptionHandling() {
188 var chxCatch = document.getElementById('no_try_catch');
189
190 if (noTryCatch()) {
191 chxCatch.setAttribute('checked', true);
192 jasmine.CATCH_EXCEPTIONS = false;
193 }
194 chxCatch.onclick = function() {
195 window.location.search = searchWithCatch();
196 };
197 }
198 };
199 jasmine.HtmlReporter.parameters = function(doc) {
200 var paramStr = doc.location.search.substring(1);
201 var params = [];
202
203 if (paramStr.length > 0) {
204 params = paramStr.split('&');
205 }
206 return params;
207 }
208 jasmine.HtmlReporter.sectionLink = function(sectionName) {
209 var link = '?';
210 var params = [];
211
212 if (sectionName) {
213 params.push('spec=' + encodeURIComponent(sectionName));
214 }
215 if (!jasmine.CATCH_EXCEPTIONS) {
216 params.push("catch=false");
217 }
218 if (params.length > 0) {
219 link += params.join("&");
220 }
221
222 return link;
223 };
224 jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter);
225 jasmine.HtmlReporter.ReporterView = function(dom) {
226 this.startedAt = new Date();
227 this.runningSpecCount = 0;
228 this.completeSpecCount = 0;
229 this.passedCount = 0;
230 this.failedCount = 0;
231 this.skippedCount = 0;
232
233 this.createResultsMenu = function() {
234 this.resultsMenu = this.createDom('span', {className: 'resultsMenu bar'},
235 this.summaryMenuItem = this.createDom('a', {className: 'summaryMenuItem', href: "#"}, '0 specs'),
236 ' | ',
237 this.detailsMenuItem = this.createDom('a', {className: 'detailsMenuItem', href: "#"}, '0 failing'));
238
239 this.summaryMenuItem.onclick = function() {
240 dom.reporter.className = dom.reporter.className.replace(/ showDetails/g, '');
241 };
242
243 this.detailsMenuItem.onclick = function() {
244 showDetails();
245 };
246 };
247
248 this.addSpecs = function(specs, specFilter) {
249 this.totalSpecCount = specs.length;
250
251 this.views = {
252 specs: {},
253 suites: {}
254 };
255
256 for (var i = 0; i < specs.length; i++) {
257 var spec = specs[i];
258 this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom, this.views);
259 if (specFilter(spec)) {
260 this.runningSpecCount++;
261 }
262 }
263 };
264
265 this.specComplete = function(spec) {
266 this.completeSpecCount++;
267
268 if (isUndefined(this.views.specs[spec.id])) {
269 this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom);
270 }
271
272 var specView = this.views.specs[spec.id];
273
274 switch (specView.status()) {
275 case 'passed':
276 this.passedCount++;
277 break;
278
279 case 'failed':
280 this.failedCount++;
281 break;
282
283 case 'skipped':
284 this.skippedCount++;
285 break;
286 }
287
288 specView.refresh();
289 this.refresh();
290 };
291
292 this.suiteComplete = function(suite) {
293 var suiteView = this.views.suites[suite.id];
294 if (isUndefined(suiteView)) {
295 return;
296 }
297 suiteView.refresh();
298 };
299
300 this.refresh = function() {
301
302 if (isUndefined(this.resultsMenu)) {
303 this.createResultsMenu();
304 }
305
306 // currently running UI
307 if (isUndefined(this.runningAlert)) {
308 this.runningAlert = this.createDom('a', { href: jasmine.HtmlReporter.sectionLink(), className: "runningAlert bar" });
309 dom.alert.appendChild(this.runningAlert);
310 }
311 this.runningAlert.innerHTML = "Running " + this.completeSpecCount + " of " + specPluralizedFor(this.totalSpecCount);
312
313 // skipped specs UI
314 if (isUndefined(this.skippedAlert)) {
315 this.skippedAlert = this.createDom('a', { href: jasmine.HtmlReporter.sectionLink(), className: "skippedAlert bar" });
316 }
317
318 this.skippedAlert.innerHTML = "Skipping " + this.skippedCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all";
319
320 if (this.skippedCount === 1 && isDefined(dom.alert)) {
321 dom.alert.appendChild(this.skippedAlert);
322 }
323
324 // passing specs UI
325 if (isUndefined(this.passedAlert)) {
326 this.passedAlert = this.createDom('span', { href: jasmine.HtmlReporter.sectionLink(), className: "passingAlert bar" });
327 }
328 this.passedAlert.innerHTML = "Passing " + specPluralizedFor(this.passedCount);
329
330 // failing specs UI
331 if (isUndefined(this.failedAlert)) {
332 this.failedAlert = this.createDom('span', {href: "?", className: "failingAlert bar"});
333 }
334 this.failedAlert.innerHTML = "Failing " + specPluralizedFor(this.failedCount);
335
336 if (this.failedCount === 1 && isDefined(dom.alert)) {
337 dom.alert.appendChild(this.failedAlert);
338 dom.alert.appendChild(this.resultsMenu);
339 }
340
341 // summary info
342 this.summaryMenuItem.innerHTML = "" + specPluralizedFor(this.runningSpecCount);
343 this.detailsMenuItem.innerHTML = "" + this.failedCount + " failing";
344 };
345
346 this.complete = function() {
347 dom.alert.removeChild(this.runningAlert);
348
349 this.skippedAlert.innerHTML = "Ran " + this.runningSpecCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all";
350
351 if (this.failedCount === 0) {
352 dom.alert.appendChild(this.createDom('span', {className: 'passingAlert bar'}, "Passing " + specPluralizedFor(this.passedCount)));
353 } else {
354 showDetails();
355 }
356
357 dom.banner.appendChild(this.createDom('span', {className: 'duration'}, "finished in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s"));
358 };
359
360 return this;
361
362 function showDetails() {
363 if (dom.reporter.className.search(/showDetails/) === -1) {
364 dom.reporter.className += " showDetails";
365 }
366 }
367
368 function isUndefined(obj) {
369 return typeof obj === 'undefined';
370 }
371
372 function isDefined(obj) {
373 return !isUndefined(obj);
374 }
375
376 function specPluralizedFor(count) {
377 var str = count + " spec";
378 if (count > 1) {
379 str += "s"
380 }
381 return str;
382 }
383
384 };
385
386 jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.ReporterView);
387
388
389 jasmine.HtmlReporter.SpecView = function(spec, dom, views) {
390 this.spec = spec;
391 this.dom = dom;
392 this.views = views;
393
394 this.symbol = this.createDom('li', { className: 'pending' });
395 this.dom.symbolSummary.appendChild(this.symbol);
396
397 this.summary = this.createDom('div', { className: 'specSummary' },
398 this.createDom('a', {
399 className: 'description',
400 href: jasmine.HtmlReporter.sectionLink(this.spec.getFullName()),
401 title: this.spec.getFullName()
402 }, this.spec.description)
403 );
404
405 this.detail = this.createDom('div', { className: 'specDetail' },
406 this.createDom('a', {
407 className: 'description',
408 href: '?spec=' + encodeURIComponent(this.spec.getFullName()),
409 title: this.spec.getFullName()
410 }, this.spec.getFullName())
411 );
412 };
413
414 jasmine.HtmlReporter.SpecView.prototype.status = function() {
415 return this.getSpecStatus(this.spec);
416 };
417
418 jasmine.HtmlReporter.SpecView.prototype.refresh = function() {
419 this.symbol.className = this.status();
420
421 switch (this.status()) {
422 case 'skipped':
423 break;
424
425 case 'passed':
426 this.appendSummaryToSuiteDiv();
427 break;
428
429 case 'failed':
430 this.appendSummaryToSuiteDiv();
431 this.appendFailureDetail();
432 break;
433 }
434 };
435
436 jasmine.HtmlReporter.SpecView.prototype.appendSummaryToSuiteDiv = function() {
437 this.summary.className += ' ' + this.status();
438 this.appendToSummary(this.spec, this.summary);
439 };
440
441 jasmine.HtmlReporter.SpecView.prototype.appendFailureDetail = function() {
442 this.detail.className += ' ' + this.status();
443
444 var resultItems = this.spec.results().getItems();
445 var messagesDiv = this.createDom('div', { className: 'messages' });
446
447 for (var i = 0; i < resultItems.length; i++) {
448 var result = resultItems[i];
449
450 if (result.type == 'log') {
451 messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
452 } else if (result.type == 'expect' && result.passed && !result.passed()) {
453 messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
454
455 if (result.trace.stack) {
456 messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
457 }
458 }
459 }
460
461 if (messagesDiv.childNodes.length > 0) {
462 this.detail.appendChild(messagesDiv);
463 this.dom.details.appendChild(this.detail);
464 }
465 };
466
467 jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SpecView);jasmine.HtmlReporter.SuiteView = function(suite, dom, views) {
468 this.suite = suite;
469 this.dom = dom;
470 this.views = views;
471
472 this.element = this.createDom('div', { className: 'suite' },
473 this.createDom('a', { className: 'description', href: jasmine.HtmlReporter.sectionLink(this.suite.getFullName()) }, this.suite.description)
474 );
475
476 this.appendToSummary(this.suite, this.element);
477 };
478
479 jasmine.HtmlReporter.SuiteView.prototype.status = function() {
480 return this.getSpecStatus(this.suite);
481 };
482
483 jasmine.HtmlReporter.SuiteView.prototype.refresh = function() {
484 this.element.className += " " + this.status();
485 };
486
487 jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SuiteView);
488
489 /* @deprecated Use jasmine.HtmlReporter instead
490 */
491 jasmine.TrivialReporter = function(doc) {
492 this.document = doc || document;
493 this.suiteDivs = {};
494 this.logRunningSpecs = false;
495 };
496
497 jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) {
498 var el = document.createElement(type);
499
500 for (var i = 2; i < arguments.length; i++) {
501 var child = arguments[i];
502
503 if (typeof child === 'string') {
504 el.appendChild(document.createTextNode(child));
505 } else {
506 if (child) { el.appendChild(child); }
507 }
508 }
509
510 for (var attr in attrs) {
511 if (attr == "className") {
512 el[attr] = attrs[attr];
513 } else {
514 el.setAttribute(attr, attrs[attr]);
515 }
516 }
517
518 return el;
519 };
520
521 jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {
522 var showPassed, showSkipped;
523
524 this.outerDiv = this.createDom('div', { id: 'TrivialReporter', className: 'jasmine_reporter' },
525 this.createDom('div', { className: 'banner' },
526 this.createDom('div', { className: 'logo' },
527 this.createDom('span', { className: 'title' }, "Jasmine"),
528 this.createDom('span', { className: 'version' }, runner.env.versionString())),
529 this.createDom('div', { className: 'options' },
530 "Show ",
531 showPassed = this.createDom('input', { id: "__jasmine_TrivialReporter_showPassed__", type: 'checkbox' }),
532 this.createDom('label', { "for": "__jasmine_TrivialReporter_showPassed__" }, " passed "),
533 showSkipped = this.createDom('input', { id: "__jasmine_TrivialReporter_showSkipped__", type: 'checkbox' }),
534 this.createDom('label', { "for": "__jasmine_TrivialReporter_showSkipped__" }, " skipped")
535 )
536 ),
537
538 this.runnerDiv = this.createDom('div', { className: 'runner running' },
539 this.createDom('a', { className: 'run_spec', href: '?' }, "run all"),
540 this.runnerMessageSpan = this.createDom('span', {}, "Running..."),
541 this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, ""))
542 );
543
544 this.document.body.appendChild(this.outerDiv);
545
546 var suites = runner.suites();
547 for (var i = 0; i < suites.length; i++) {
548 var suite = suites[i];
549 var suiteDiv = this.createDom('div', { className: 'suite' },
550 this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, "run"),
551 this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description));
552 this.suiteDivs[suite.id] = suiteDiv;
553 var parentDiv = this.outerDiv;
554 if (suite.parentSuite) {
555 parentDiv = this.suiteDivs[suite.parentSuite.id];
556 }
557 parentDiv.appendChild(suiteDiv);
558 }
559
560 this.startedAt = new Date();
561
562 var self = this;
563 showPassed.onclick = function(evt) {
564 if (showPassed.checked) {
565 self.outerDiv.className += ' show-passed';
566 } else {
567 self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, '');
568 }
569 };
570
571 showSkipped.onclick = function(evt) {
572 if (showSkipped.checked) {
573 self.outerDiv.className += ' show-skipped';
574 } else {
575 self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, '');
576 }
577 };
578 };
579
580 jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) {
581 var results = runner.results();
582 var className = (results.failedCount > 0) ? "runner failed" : "runner passed";
583 this.runnerDiv.setAttribute("class", className);
584 //do it twice for IE
585 this.runnerDiv.setAttribute("className", className);
586 var specs = runner.specs();
587 var specCount = 0;
588 for (var i = 0; i < specs.length; i++) {
589 if (this.specFilter(specs[i])) {
590 specCount++;
591 }
592 }
593 var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s");
594 message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s";
595 this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild);
596
597 this.finishedAtSpan.appendChild(document.createTextNode("Finished at " + new Date().toString()));
598 };
599
600 jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) {
601 var results = suite.results();
602 var status = results.passed() ? 'passed' : 'failed';
603 if (results.totalCount === 0) { // todo: change this to check results.skipped
604 status = 'skipped';
605 }
606 this.suiteDivs[suite.id].className += " " + status;
607 };
608
609 jasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) {
610 if (this.logRunningSpecs) {
611 this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
612 }
613 };
614
615 jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) {
616 var results = spec.results();
617 var status = results.passed() ? 'passed' : 'failed';
618 if (results.skipped) {
619 status = 'skipped';
620 }
621 var specDiv = this.createDom('div', { className: 'spec ' + status },
622 this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, "run"),
623 this.createDom('a', {
624 className: 'description',
625 href: '?spec=' + encodeURIComponent(spec.getFullName()),
626 title: spec.getFullName()
627 }, spec.description));
628
629
630 var resultItems = results.getItems();
631 var messagesDiv = this.createDom('div', { className: 'messages' });
632 for (var i = 0; i < resultItems.length; i++) {
633 var result = resultItems[i];
634
635 if (result.type == 'log') {
636 messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
637 } else if (result.type == 'expect' && result.passed && !result.passed()) {
638 messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
639
640 if (result.trace.stack) {
641 messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
642 }
643 }
644 }
645
646 if (messagesDiv.childNodes.length > 0) {
647 specDiv.appendChild(messagesDiv);
648 }
649
650 this.suiteDivs[spec.suite.id].appendChild(specDiv);
651 };
652
653 jasmine.TrivialReporter.prototype.log = function() {
654 var console = jasmine.getGlobal().console;
655 if (console && console.log) {
656 if (console.log.apply) {
657 console.log.apply(console, arguments);
658 } else {
659 console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
660 }
661 }
662 };
663
664 jasmine.TrivialReporter.prototype.getLocation = function() {
665 return this.document.location;
666 };
667
668 jasmine.TrivialReporter.prototype.specFilter = function(spec) {
669 var paramMap = {};
670 var params = this.getLocation().search.substring(1).split('&');
671 for (var i = 0; i < params.length; i++) {
672 var p = params[i].split('=');
673 paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
674 }
675
676 if (!paramMap.spec) {
677 return true;
678 }
679 return spec.getFullName().indexOf(paramMap.spec) === 0;
680 };
0 body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; }
1
2 #HTMLReporter { font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333333; }
3 #HTMLReporter a { text-decoration: none; }
4 #HTMLReporter a:hover { text-decoration: underline; }
5 #HTMLReporter p, #HTMLReporter h1, #HTMLReporter h2, #HTMLReporter h3, #HTMLReporter h4, #HTMLReporter h5, #HTMLReporter h6 { margin: 0; line-height: 14px; }
6 #HTMLReporter .banner, #HTMLReporter .symbolSummary, #HTMLReporter .summary, #HTMLReporter .resultMessage, #HTMLReporter .specDetail .description, #HTMLReporter .alert .bar, #HTMLReporter .stackTrace { padding-left: 9px; padding-right: 9px; }
7 #HTMLReporter #jasmine_content { position: fixed; right: 100%; }
8 #HTMLReporter .version { color: #aaaaaa; }
9 #HTMLReporter .banner { margin-top: 14px; }
10 #HTMLReporter .duration { color: #aaaaaa; float: right; }
11 #HTMLReporter .symbolSummary { overflow: hidden; *zoom: 1; margin: 14px 0; }
12 #HTMLReporter .symbolSummary li { display: block; float: left; height: 7px; width: 14px; margin-bottom: 7px; font-size: 16px; }
13 #HTMLReporter .symbolSummary li.passed { font-size: 14px; }
14 #HTMLReporter .symbolSummary li.passed:before { color: #5e7d00; content: "\02022"; }
15 #HTMLReporter .symbolSummary li.failed { line-height: 9px; }
16 #HTMLReporter .symbolSummary li.failed:before { color: #b03911; content: "x"; font-weight: bold; margin-left: -1px; }
17 #HTMLReporter .symbolSummary li.skipped { font-size: 14px; }
18 #HTMLReporter .symbolSummary li.skipped:before { color: #bababa; content: "\02022"; }
19 #HTMLReporter .symbolSummary li.pending { line-height: 11px; }
20 #HTMLReporter .symbolSummary li.pending:before { color: #aaaaaa; content: "-"; }
21 #HTMLReporter .exceptions { color: #fff; float: right; margin-top: 5px; margin-right: 5px; }
22 #HTMLReporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; }
23 #HTMLReporter .runningAlert { background-color: #666666; }
24 #HTMLReporter .skippedAlert { background-color: #aaaaaa; }
25 #HTMLReporter .skippedAlert:first-child { background-color: #333333; }
26 #HTMLReporter .skippedAlert:hover { text-decoration: none; color: white; text-decoration: underline; }
27 #HTMLReporter .passingAlert { background-color: #a6b779; }
28 #HTMLReporter .passingAlert:first-child { background-color: #5e7d00; }
29 #HTMLReporter .failingAlert { background-color: #cf867e; }
30 #HTMLReporter .failingAlert:first-child { background-color: #b03911; }
31 #HTMLReporter .results { margin-top: 14px; }
32 #HTMLReporter #details { display: none; }
33 #HTMLReporter .resultsMenu, #HTMLReporter .resultsMenu a { background-color: #fff; color: #333333; }
34 #HTMLReporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; }
35 #HTMLReporter.showDetails .summaryMenuItem:hover { text-decoration: underline; }
36 #HTMLReporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; }
37 #HTMLReporter.showDetails .summary { display: none; }
38 #HTMLReporter.showDetails #details { display: block; }
39 #HTMLReporter .summaryMenuItem { font-weight: bold; text-decoration: underline; }
40 #HTMLReporter .summary { margin-top: 14px; }
41 #HTMLReporter .summary .suite .suite, #HTMLReporter .summary .specSummary { margin-left: 14px; }
42 #HTMLReporter .summary .specSummary.passed a { color: #5e7d00; }
43 #HTMLReporter .summary .specSummary.failed a { color: #b03911; }
44 #HTMLReporter .description + .suite { margin-top: 0; }
45 #HTMLReporter .suite { margin-top: 14px; }
46 #HTMLReporter .suite a { color: #333333; }
47 #HTMLReporter #details .specDetail { margin-bottom: 28px; }
48 #HTMLReporter #details .specDetail .description { display: block; color: white; background-color: #b03911; }
49 #HTMLReporter .resultMessage { padding-top: 14px; color: #333333; }
50 #HTMLReporter .resultMessage span.result { display: block; }
51 #HTMLReporter .stackTrace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #ddd; background: white; white-space: pre; }
52
53 #TrivialReporter { padding: 8px 13px; position: absolute; top: 0; bottom: 0; left: 0; right: 0; overflow-y: scroll; background-color: white; font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif; /*.resultMessage {*/ /*white-space: pre;*/ /*}*/ }
54 #TrivialReporter a:visited, #TrivialReporter a { color: #303; }
55 #TrivialReporter a:hover, #TrivialReporter a:active { color: blue; }
56 #TrivialReporter .run_spec { float: right; padding-right: 5px; font-size: .8em; text-decoration: none; }
57 #TrivialReporter .banner { color: #303; background-color: #fef; padding: 5px; }
58 #TrivialReporter .logo { float: left; font-size: 1.1em; padding-left: 5px; }
59 #TrivialReporter .logo .version { font-size: .6em; padding-left: 1em; }
60 #TrivialReporter .runner.running { background-color: yellow; }
61 #TrivialReporter .options { text-align: right; font-size: .8em; }
62 #TrivialReporter .suite { border: 1px outset gray; margin: 5px 0; padding-left: 1em; }
63 #TrivialReporter .suite .suite { margin: 5px; }
64 #TrivialReporter .suite.passed { background-color: #dfd; }
65 #TrivialReporter .suite.failed { background-color: #fdd; }
66 #TrivialReporter .spec { margin: 5px; padding-left: 1em; clear: both; }
67 #TrivialReporter .spec.failed, #TrivialReporter .spec.passed, #TrivialReporter .spec.skipped { padding-bottom: 5px; border: 1px solid gray; }
68 #TrivialReporter .spec.failed { background-color: #fbb; border-color: red; }
69 #TrivialReporter .spec.passed { background-color: #bfb; border-color: green; }
70 #TrivialReporter .spec.skipped { background-color: #bbb; }
71 #TrivialReporter .messages { border-left: 1px dashed gray; padding-left: 1em; padding-right: 1em; }
72 #TrivialReporter .passed { background-color: #cfc; display: none; }
73 #TrivialReporter .failed { background-color: #fbb; }
74 #TrivialReporter .skipped { color: #777; background-color: #eee; display: none; }
75 #TrivialReporter .resultMessage span.result { display: block; line-height: 2em; color: black; }
76 #TrivialReporter .resultMessage .mismatch { color: black; }
77 #TrivialReporter .stackTrace { white-space: pre; font-size: .8em; margin-left: 10px; max-height: 5em; overflow: auto; border: 1px inset red; padding: 1em; background: #eef; }
78 #TrivialReporter .finished-at { padding-left: 1em; font-size: .6em; }
79 #TrivialReporter.show-passed .passed, #TrivialReporter.show-skipped .skipped { display: block; }
80 #TrivialReporter #jasmine_content { position: fixed; right: 100%; }
81 #TrivialReporter .runner { border: 1px solid gray; display: block; margin: 5px 0; padding: 2px 0 2px 10px; }
0 var isCommonJS = typeof window == "undefined" && typeof exports == "object";
1
2 /**
3 * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework.
4 *
5 * @namespace
6 */
7 var jasmine = {};
8 if (isCommonJS) exports.jasmine = jasmine;
9 /**
10 * @private
11 */
12 jasmine.unimplementedMethod_ = function() {
13 throw new Error("unimplemented method");
14 };
15
16 /**
17 * Use <code>jasmine.undefined</code> instead of <code>undefined</code>, since <code>undefined</code> is just
18 * a plain old variable and may be redefined by somebody else.
19 *
20 * @private
21 */
22 jasmine.undefined = jasmine.___undefined___;
23
24 /**
25 * Show diagnostic messages in the console if set to true
26 *
27 */
28 jasmine.VERBOSE = false;
29
30 /**
31 * Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed.
32 *
33 */
34 jasmine.DEFAULT_UPDATE_INTERVAL = 250;
35
36 /**
37 * Maximum levels of nesting that will be included when an object is pretty-printed
38 */
39 jasmine.MAX_PRETTY_PRINT_DEPTH = 40;
40
41 /**
42 * Default timeout interval in milliseconds for waitsFor() blocks.
43 */
44 jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000;
45
46 /**
47 * By default exceptions thrown in the context of a test are caught by jasmine so that it can run the remaining tests in the suite.
48 * Set to false to let the exception bubble up in the browser.
49 *
50 */
51 jasmine.CATCH_EXCEPTIONS = true;
52
53 jasmine.getGlobal = function() {
54 function getGlobal() {
55 return this;
56 }
57
58 return getGlobal();
59 };
60
61 /**
62 * Allows for bound functions to be compared. Internal use only.
63 *
64 * @ignore
65 * @private
66 * @param base {Object} bound 'this' for the function
67 * @param name {Function} function to find
68 */
69 jasmine.bindOriginal_ = function(base, name) {
70 var original = base[name];
71 if (original.apply) {
72 return function() {
73 return original.apply(base, arguments);
74 };
75 } else {
76 // IE support
77 return jasmine.getGlobal()[name];
78 }
79 };
80
81 jasmine.setTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'setTimeout');
82 jasmine.clearTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearTimeout');
83 jasmine.setInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'setInterval');
84 jasmine.clearInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearInterval');
85
86 jasmine.MessageResult = function(values) {
87 this.type = 'log';
88 this.values = values;
89 this.trace = new Error(); // todo: test better
90 };
91
92 jasmine.MessageResult.prototype.toString = function() {
93 var text = "";
94 for (var i = 0; i < this.values.length; i++) {
95 if (i > 0) text += " ";
96 if (jasmine.isString_(this.values[i])) {
97 text += this.values[i];
98 } else {
99 text += jasmine.pp(this.values[i]);
100 }
101 }
102 return text;
103 };
104
105 jasmine.ExpectationResult = function(params) {
106 this.type = 'expect';
107 this.matcherName = params.matcherName;
108 this.passed_ = params.passed;
109 this.expected = params.expected;
110 this.actual = params.actual;
111 this.message = this.passed_ ? 'Passed.' : params.message;
112
113 var trace = (params.trace || new Error(this.message));
114 this.trace = this.passed_ ? '' : trace;
115 };
116
117 jasmine.ExpectationResult.prototype.toString = function () {
118 return this.message;
119 };
120
121 jasmine.ExpectationResult.prototype.passed = function () {
122 return this.passed_;
123 };
124
125 /**
126 * Getter for the Jasmine environment. Ensures one gets created
127 */
128 jasmine.getEnv = function() {
129 var env = jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env();
130 return env;
131 };
132
133 /**
134 * @ignore
135 * @private
136 * @param value
137 * @returns {Boolean}
138 */
139 jasmine.isArray_ = function(value) {
140 return jasmine.isA_("Array", value);
141 };
142
143 /**
144 * @ignore
145 * @private
146 * @param value
147 * @returns {Boolean}
148 */
149 jasmine.isString_ = function(value) {
150 return jasmine.isA_("String", value);
151 };
152
153 /**
154 * @ignore
155 * @private
156 * @param value
157 * @returns {Boolean}
158 */
159 jasmine.isNumber_ = function(value) {
160 return jasmine.isA_("Number", value);
161 };
162
163 /**
164 * @ignore
165 * @private
166 * @param {String} typeName
167 * @param value
168 * @returns {Boolean}
169 */
170 jasmine.isA_ = function(typeName, value) {
171 return Object.prototype.toString.apply(value) === '[object ' + typeName + ']';
172 };
173
174 /**
175 * Pretty printer for expecations. Takes any object and turns it into a human-readable string.
176 *
177 * @param value {Object} an object to be outputted
178 * @returns {String}
179 */
180 jasmine.pp = function(value) {
181 var stringPrettyPrinter = new jasmine.StringPrettyPrinter();
182 stringPrettyPrinter.format(value);
183 return stringPrettyPrinter.string;
184 };
185
186 /**
187 * Returns true if the object is a DOM Node.
188 *
189 * @param {Object} obj object to check
190 * @returns {Boolean}
191 */
192 jasmine.isDomNode = function(obj) {
193 return obj.nodeType > 0;
194 };
195
196 /**
197 * Returns a matchable 'generic' object of the class type. For use in expecations of type when values don't matter.
198 *
199 * @example
200 * // don't care about which function is passed in, as long as it's a function
201 * expect(mySpy).toHaveBeenCalledWith(jasmine.any(Function));
202 *
203 * @param {Class} clazz
204 * @returns matchable object of the type clazz
205 */
206 jasmine.any = function(clazz) {
207 return new jasmine.Matchers.Any(clazz);
208 };
209
210 /**
211 * Returns a matchable subset of a JSON object. For use in expectations when you don't care about all of the
212 * attributes on the object.
213 *
214 * @example
215 * // don't care about any other attributes than foo.
216 * expect(mySpy).toHaveBeenCalledWith(jasmine.objectContaining({foo: "bar"});
217 *
218 * @param sample {Object} sample
219 * @returns matchable object for the sample
220 */
221 jasmine.objectContaining = function (sample) {
222 return new jasmine.Matchers.ObjectContaining(sample);
223 };
224
225 /**
226 * Jasmine Spies are test doubles that can act as stubs, spies, fakes or when used in an expecation, mocks.
227 *
228 * Spies should be created in test setup, before expectations. They can then be checked, using the standard Jasmine
229 * expectation syntax. Spies can be checked if they were called or not and what the calling params were.
230 *
231 * A Spy has the following fields: wasCalled, callCount, mostRecentCall, and argsForCall (see docs).
232 *
233 * Spies are torn down at the end of every spec.
234 *
235 * Note: Do <b>not</b> call new jasmine.Spy() directly - a spy must be created using spyOn, jasmine.createSpy or jasmine.createSpyObj.
236 *
237 * @example
238 * // a stub
239 * var myStub = jasmine.createSpy('myStub'); // can be used anywhere
240 *
241 * // spy example
242 * var foo = {
243 * not: function(bool) { return !bool; }
244 * }
245 *
246 * // actual foo.not will not be called, execution stops
247 * spyOn(foo, 'not');
248
249 // foo.not spied upon, execution will continue to implementation
250 * spyOn(foo, 'not').andCallThrough();
251 *
252 * // fake example
253 * var foo = {
254 * not: function(bool) { return !bool; }
255 * }
256 *
257 * // foo.not(val) will return val
258 * spyOn(foo, 'not').andCallFake(function(value) {return value;});
259 *
260 * // mock example
261 * foo.not(7 == 7);
262 * expect(foo.not).toHaveBeenCalled();
263 * expect(foo.not).toHaveBeenCalledWith(true);
264 *
265 * @constructor
266 * @see spyOn, jasmine.createSpy, jasmine.createSpyObj
267 * @param {String} name
268 */
269 jasmine.Spy = function(name) {
270 /**
271 * The name of the spy, if provided.
272 */
273 this.identity = name || 'unknown';
274 /**
275 * Is this Object a spy?
276 */
277 this.isSpy = true;
278 /**
279 * The actual function this spy stubs.
280 */
281 this.plan = function() {
282 };
283 /**
284 * Tracking of the most recent call to the spy.
285 * @example
286 * var mySpy = jasmine.createSpy('foo');
287 * mySpy(1, 2);
288 * mySpy.mostRecentCall.args = [1, 2];
289 */
290 this.mostRecentCall = {};
291
292 /**
293 * Holds arguments for each call to the spy, indexed by call count
294 * @example
295 * var mySpy = jasmine.createSpy('foo');
296 * mySpy(1, 2);
297 * mySpy(7, 8);
298 * mySpy.mostRecentCall.args = [7, 8];
299 * mySpy.argsForCall[0] = [1, 2];
300 * mySpy.argsForCall[1] = [7, 8];
301 */
302 this.argsForCall = [];
303 this.calls = [];
304 };
305
306 /**
307 * Tells a spy to call through to the actual implemenatation.
308 *
309 * @example
310 * var foo = {
311 * bar: function() { // do some stuff }
312 * }
313 *
314 * // defining a spy on an existing property: foo.bar
315 * spyOn(foo, 'bar').andCallThrough();
316 */
317 jasmine.Spy.prototype.andCallThrough = function() {
318 this.plan = this.originalValue;
319 return this;
320 };
321
322 /**
323 * For setting the return value of a spy.
324 *
325 * @example
326 * // defining a spy from scratch: foo() returns 'baz'
327 * var foo = jasmine.createSpy('spy on foo').andReturn('baz');
328 *
329 * // defining a spy on an existing property: foo.bar() returns 'baz'
330 * spyOn(foo, 'bar').andReturn('baz');
331 *
332 * @param {Object} value
333 */
334 jasmine.Spy.prototype.andReturn = function(value) {
335 this.plan = function() {
336 return value;
337 };
338 return this;
339 };
340
341 /**
342 * For throwing an exception when a spy is called.
343 *
344 * @example
345 * // defining a spy from scratch: foo() throws an exception w/ message 'ouch'
346 * var foo = jasmine.createSpy('spy on foo').andThrow('baz');
347 *
348 * // defining a spy on an existing property: foo.bar() throws an exception w/ message 'ouch'
349 * spyOn(foo, 'bar').andThrow('baz');
350 *
351 * @param {String} exceptionMsg
352 */
353 jasmine.Spy.prototype.andThrow = function(exceptionMsg) {
354 this.plan = function() {
355 throw exceptionMsg;
356 };
357 return this;
358 };
359
360 /**
361 * Calls an alternate implementation when a spy is called.
362 *
363 * @example
364 * var baz = function() {
365 * // do some stuff, return something
366 * }
367 * // defining a spy from scratch: foo() calls the function baz
368 * var foo = jasmine.createSpy('spy on foo').andCall(baz);
369 *
370 * // defining a spy on an existing property: foo.bar() calls an anonymnous function
371 * spyOn(foo, 'bar').andCall(function() { return 'baz';} );
372 *
373 * @param {Function} fakeFunc
374 */
375 jasmine.Spy.prototype.andCallFake = function(fakeFunc) {
376 this.plan = fakeFunc;
377 return this;
378 };
379
380 /**
381 * Resets all of a spy's the tracking variables so that it can be used again.
382 *
383 * @example
384 * spyOn(foo, 'bar');
385 *
386 * foo.bar();
387 *
388 * expect(foo.bar.callCount).toEqual(1);
389 *
390 * foo.bar.reset();
391 *
392 * expect(foo.bar.callCount).toEqual(0);
393 */
394 jasmine.Spy.prototype.reset = function() {
395 this.wasCalled = false;
396 this.callCount = 0;
397 this.argsForCall = [];
398 this.calls = [];
399 this.mostRecentCall = {};
400 };
401
402 jasmine.createSpy = function(name) {
403
404 var spyObj = function() {
405 spyObj.wasCalled = true;
406 spyObj.callCount++;
407 var args = jasmine.util.argsToArray(arguments);
408 spyObj.mostRecentCall.object = this;
409 spyObj.mostRecentCall.args = args;
410 spyObj.argsForCall.push(args);
411 spyObj.calls.push({object: this, args: args});
412 return spyObj.plan.apply(this, arguments);
413 };
414
415 var spy = new jasmine.Spy(name);
416
417 for (var prop in spy) {
418 spyObj[prop] = spy[prop];
419 }
420
421 spyObj.reset();
422
423 return spyObj;
424 };
425
426 /**
427 * Determines whether an object is a spy.
428 *
429 * @param {jasmine.Spy|Object} putativeSpy
430 * @returns {Boolean}
431 */
432 jasmine.isSpy = function(putativeSpy) {
433 return putativeSpy && putativeSpy.isSpy;
434 };
435
436 /**
437 * Creates a more complicated spy: an Object that has every property a function that is a spy. Used for stubbing something
438 * large in one call.
439 *
440 * @param {String} baseName name of spy class
441 * @param {Array} methodNames array of names of methods to make spies
442 */
443 jasmine.createSpyObj = function(baseName, methodNames) {
444 if (!jasmine.isArray_(methodNames) || methodNames.length === 0) {
445 throw new Error('createSpyObj requires a non-empty array of method names to create spies for');
446 }
447 var obj = {};
448 for (var i = 0; i < methodNames.length; i++) {
449 obj[methodNames[i]] = jasmine.createSpy(baseName + '.' + methodNames[i]);
450 }
451 return obj;
452 };
453
454 /**
455 * All parameters are pretty-printed and concatenated together, then written to the current spec's output.
456 *
457 * Be careful not to leave calls to <code>jasmine.log</code> in production code.
458 */
459 jasmine.log = function() {
460 var spec = jasmine.getEnv().currentSpec;
461 spec.log.apply(spec, arguments);
462 };
463
464 /**
465 * Function that installs a spy on an existing object's method name. Used within a Spec to create a spy.
466 *
467 * @example
468 * // spy example
469 * var foo = {
470 * not: function(bool) { return !bool; }
471 * }
472 * spyOn(foo, 'not'); // actual foo.not will not be called, execution stops
473 *
474 * @see jasmine.createSpy
475 * @param obj
476 * @param methodName
477 * @return {jasmine.Spy} a Jasmine spy that can be chained with all spy methods
478 */
479 var spyOn = function(obj, methodName) {
480 return jasmine.getEnv().currentSpec.spyOn(obj, methodName);
481 };
482 if (isCommonJS) exports.spyOn = spyOn;
483
484 /**
485 * Creates a Jasmine spec that will be added to the current suite.
486 *
487 * // TODO: pending tests
488 *
489 * @example
490 * it('should be true', function() {
491 * expect(true).toEqual(true);
492 * });
493 *
494 * @param {String} desc description of this specification
495 * @param {Function} func defines the preconditions and expectations of the spec
496 */
497 var it = function(desc, func) {
498 return jasmine.getEnv().it(desc, func);
499 };
500 if (isCommonJS) exports.it = it;
501
502 /**
503 * Creates a <em>disabled</em> Jasmine spec.
504 *
505 * A convenience method that allows existing specs to be disabled temporarily during development.
506 *
507 * @param {String} desc description of this specification
508 * @param {Function} func defines the preconditions and expectations of the spec
509 */
510 var xit = function(desc, func) {
511 return jasmine.getEnv().xit(desc, func);
512 };
513 if (isCommonJS) exports.xit = xit;
514
515 /**
516 * Starts a chain for a Jasmine expectation.
517 *
518 * It is passed an Object that is the actual value and should chain to one of the many
519 * jasmine.Matchers functions.
520 *
521 * @param {Object} actual Actual value to test against and expected value
522 * @return {jasmine.Matchers}
523 */
524 var expect = function(actual) {
525 return jasmine.getEnv().currentSpec.expect(actual);
526 };
527 if (isCommonJS) exports.expect = expect;
528
529 /**
530 * Defines part of a jasmine spec. Used in cominbination with waits or waitsFor in asynchrnous specs.
531 *
532 * @param {Function} func Function that defines part of a jasmine spec.
533 */
534 var runs = function(func) {
535 jasmine.getEnv().currentSpec.runs(func);
536 };
537 if (isCommonJS) exports.runs = runs;
538
539 /**
540 * Waits a fixed time period before moving to the next block.
541 *
542 * @deprecated Use waitsFor() instead
543 * @param {Number} timeout milliseconds to wait
544 */
545 var waits = function(timeout) {
546 jasmine.getEnv().currentSpec.waits(timeout);
547 };
548 if (isCommonJS) exports.waits = waits;
549
550 /**
551 * Waits for the latchFunction to return true before proceeding to the next block.
552 *
553 * @param {Function} latchFunction
554 * @param {String} optional_timeoutMessage
555 * @param {Number} optional_timeout
556 */
557 var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {
558 jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments);
559 };
560 if (isCommonJS) exports.waitsFor = waitsFor;
561
562 /**
563 * A function that is called before each spec in a suite.
564 *
565 * Used for spec setup, including validating assumptions.
566 *
567 * @param {Function} beforeEachFunction
568 */
569 var beforeEach = function(beforeEachFunction) {
570 jasmine.getEnv().beforeEach(beforeEachFunction);
571 };
572 if (isCommonJS) exports.beforeEach = beforeEach;
573
574 /**
575 * A function that is called after each spec in a suite.
576 *
577 * Used for restoring any state that is hijacked during spec execution.
578 *
579 * @param {Function} afterEachFunction
580 */
581 var afterEach = function(afterEachFunction) {
582 jasmine.getEnv().afterEach(afterEachFunction);
583 };
584 if (isCommonJS) exports.afterEach = afterEach;
585
586 /**
587 * Defines a suite of specifications.
588 *
589 * Stores the description and all defined specs in the Jasmine environment as one suite of specs. Variables declared
590 * are accessible by calls to beforeEach, it, and afterEach. Describe blocks can be nested, allowing for specialization
591 * of setup in some tests.
592 *
593 * @example
594 * // TODO: a simple suite
595 *
596 * // TODO: a simple suite with a nested describe block
597 *
598 * @param {String} description A string, usually the class under test.
599 * @param {Function} specDefinitions function that defines several specs.
600 */
601 var describe = function(description, specDefinitions) {
602 return jasmine.getEnv().describe(description, specDefinitions);
603 };
604 if (isCommonJS) exports.describe = describe;
605
606 /**
607 * Disables a suite of specifications. Used to disable some suites in a file, or files, temporarily during development.
608 *
609 * @param {String} description A string, usually the class under test.
610 * @param {Function} specDefinitions function that defines several specs.
611 */
612 var xdescribe = function(description, specDefinitions) {
613 return jasmine.getEnv().xdescribe(description, specDefinitions);
614 };
615 if (isCommonJS) exports.xdescribe = xdescribe;
616
617
618 // Provide the XMLHttpRequest class for IE 5.x-6.x:
619 jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() {
620 function tryIt(f) {
621 try {
622 return f();
623 } catch(e) {
624 }
625 return null;
626 }
627
628 var xhr = tryIt(function() {
629 return new ActiveXObject("Msxml2.XMLHTTP.6.0");
630 }) ||
631 tryIt(function() {
632 return new ActiveXObject("Msxml2.XMLHTTP.3.0");
633 }) ||
634 tryIt(function() {
635 return new ActiveXObject("Msxml2.XMLHTTP");
636 }) ||
637 tryIt(function() {
638 return new ActiveXObject("Microsoft.XMLHTTP");
639 });
640
641 if (!xhr) throw new Error("This browser does not support XMLHttpRequest.");
642
643 return xhr;
644 } : XMLHttpRequest;
645 /**
646 * @namespace
647 */
648 jasmine.util = {};
649
650 /**
651 * Declare that a child class inherit it's prototype from the parent class.
652 *
653 * @private
654 * @param {Function} childClass
655 * @param {Function} parentClass
656 */
657 jasmine.util.inherit = function(childClass, parentClass) {
658 /**
659 * @private
660 */
661 var subclass = function() {
662 };
663 subclass.prototype = parentClass.prototype;
664 childClass.prototype = new subclass();
665 };
666
667 jasmine.util.formatException = function(e) {
668 var lineNumber;
669 if (e.line) {
670 lineNumber = e.line;
671 }
672 else if (e.lineNumber) {
673 lineNumber = e.lineNumber;
674 }
675
676 var file;
677
678 if (e.sourceURL) {
679 file = e.sourceURL;
680 }
681 else if (e.fileName) {
682 file = e.fileName;
683 }
684
685 var message = (e.name && e.message) ? (e.name + ': ' + e.message) : e.toString();
686
687 if (file && lineNumber) {
688 message += ' in ' + file + ' (line ' + lineNumber + ')';
689 }
690
691 return message;
692 };
693
694 jasmine.util.htmlEscape = function(str) {
695 if (!str) return str;
696 return str.replace(/&/g, '&amp;')
697 .replace(/</g, '&lt;')
698 .replace(/>/g, '&gt;');
699 };
700
701 jasmine.util.argsToArray = function(args) {
702 var arrayOfArgs = [];
703 for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]);
704 return arrayOfArgs;
705 };
706
707 jasmine.util.extend = function(destination, source) {
708 for (var property in source) destination[property] = source[property];
709 return destination;
710 };
711
712 /**
713 * Environment for Jasmine
714 *
715 * @constructor
716 */
717 jasmine.Env = function() {
718 this.currentSpec = null;
719 this.currentSuite = null;
720 this.currentRunner_ = new jasmine.Runner(this);
721
722 this.reporter = new jasmine.MultiReporter();
723
724 this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL;
725 this.defaultTimeoutInterval = jasmine.DEFAULT_TIMEOUT_INTERVAL;
726 this.lastUpdate = 0;
727 this.specFilter = function() {
728 return true;
729 };
730
731 this.nextSpecId_ = 0;
732 this.nextSuiteId_ = 0;
733 this.equalityTesters_ = [];
734
735 // wrap matchers
736 this.matchersClass = function() {
737 jasmine.Matchers.apply(this, arguments);
738 };
739 jasmine.util.inherit(this.matchersClass, jasmine.Matchers);
740
741 jasmine.Matchers.wrapInto_(jasmine.Matchers.prototype, this.matchersClass);
742 };
743
744
745 jasmine.Env.prototype.setTimeout = jasmine.setTimeout;
746 jasmine.Env.prototype.clearTimeout = jasmine.clearTimeout;
747 jasmine.Env.prototype.setInterval = jasmine.setInterval;
748 jasmine.Env.prototype.clearInterval = jasmine.clearInterval;
749
750 /**
751 * @returns an object containing jasmine version build info, if set.
752 */
753 jasmine.Env.prototype.version = function () {
754 if (jasmine.version_) {
755 return jasmine.version_;
756 } else {
757 throw new Error('Version not set');
758 }
759 };
760
761 /**
762 * @returns string containing jasmine version build info, if set.
763 */
764 jasmine.Env.prototype.versionString = function() {
765 if (!jasmine.version_) {
766 return "version unknown";
767 }
768
769 var version = this.version();
770 var versionString = version.major + "." + version.minor + "." + version.build;
771 if (version.release_candidate) {
772 versionString += ".rc" + version.release_candidate;
773 }
774 versionString += " revision " + version.revision;
775 return versionString;
776 };
777
778 /**
779 * @returns a sequential integer starting at 0
780 */
781 jasmine.Env.prototype.nextSpecId = function () {
782 return this.nextSpecId_++;
783 };
784
785 /**
786 * @returns a sequential integer starting at 0
787 */
788 jasmine.Env.prototype.nextSuiteId = function () {
789 return this.nextSuiteId_++;
790 };
791
792 /**
793 * Register a reporter to receive status updates from Jasmine.
794 * @param {jasmine.Reporter} reporter An object which will receive status updates.
795 */
796 jasmine.Env.prototype.addReporter = function(reporter) {
797 this.reporter.addReporter(reporter);
798 };
799
800 jasmine.Env.prototype.execute = function() {
801 this.currentRunner_.execute();
802 };
803
804 jasmine.Env.prototype.describe = function(description, specDefinitions) {
805 var suite = new jasmine.Suite(this, description, specDefinitions, this.currentSuite);
806
807 var parentSuite = this.currentSuite;
808 if (parentSuite) {
809 parentSuite.add(suite);
810 } else {
811 this.currentRunner_.add(suite);
812 }
813
814 this.currentSuite = suite;
815
816 var declarationError = null;
817 try {
818 specDefinitions.call(suite);
819 } catch(e) {
820 declarationError = e;
821 }
822
823 if (declarationError) {
824 this.it("encountered a declaration exception", function() {
825 throw declarationError;
826 });
827 }
828
829 this.currentSuite = parentSuite;
830
831 return suite;
832 };
833
834 jasmine.Env.prototype.beforeEach = function(beforeEachFunction) {
835 if (this.currentSuite) {
836 this.currentSuite.beforeEach(beforeEachFunction);
837 } else {
838 this.currentRunner_.beforeEach(beforeEachFunction);
839 }
840 };
841
842 jasmine.Env.prototype.currentRunner = function () {
843 return this.currentRunner_;
844 };
845
846 jasmine.Env.prototype.afterEach = function(afterEachFunction) {
847 if (this.currentSuite) {
848 this.currentSuite.afterEach(afterEachFunction);
849 } else {
850 this.currentRunner_.afterEach(afterEachFunction);
851 }
852
853 };
854
855 jasmine.Env.prototype.xdescribe = function(desc, specDefinitions) {
856 return {
857 execute: function() {
858 }
859 };
860 };
861
862 jasmine.Env.prototype.it = function(description, func) {
863 var spec = new jasmine.Spec(this, this.currentSuite, description);
864 this.currentSuite.add(spec);
865 this.currentSpec = spec;
866
867 if (func) {
868 spec.runs(func);
869 }
870
871 return spec;
872 };
873
874 jasmine.Env.prototype.xit = function(desc, func) {
875 return {
876 id: this.nextSpecId(),
877 runs: function() {
878 }
879 };
880 };
881
882 jasmine.Env.prototype.compareRegExps_ = function(a, b, mismatchKeys, mismatchValues) {
883 if (a.source != b.source)
884 mismatchValues.push("expected pattern /" + b.source + "/ is not equal to the pattern /" + a.source + "/");
885
886 if (a.ignoreCase != b.ignoreCase)
887 mismatchValues.push("expected modifier i was" + (b.ignoreCase ? " " : " not ") + "set and does not equal the origin modifier");
888
889 if (a.global != b.global)
890 mismatchValues.push("expected modifier g was" + (b.global ? " " : " not ") + "set and does not equal the origin modifier");
891
892 if (a.multiline != b.multiline)
893 mismatchValues.push("expected modifier m was" + (b.multiline ? " " : " not ") + "set and does not equal the origin modifier");
894
895 if (a.sticky != b.sticky)
896 mismatchValues.push("expected modifier y was" + (b.sticky ? " " : " not ") + "set and does not equal the origin modifier");
897
898 return (mismatchValues.length === 0);
899 };
900
901 jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) {
902 if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) {
903 return true;
904 }
905
906 a.__Jasmine_been_here_before__ = b;
907 b.__Jasmine_been_here_before__ = a;
908
909 var hasKey = function(obj, keyName) {
910 return obj !== null && obj[keyName] !== jasmine.undefined;
911 };
912
913 for (var property in b) {
914 if (!hasKey(a, property) && hasKey(b, property)) {
915 mismatchKeys.push("expected has key '" + property + "', but missing from actual.");
916 }
917 }
918 for (property in a) {
919 if (!hasKey(b, property) && hasKey(a, property)) {
920 mismatchKeys.push("expected missing key '" + property + "', but present in actual.");
921 }
922 }
923 for (property in b) {
924 if (property == '__Jasmine_been_here_before__') continue;
925 if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) {
926 mismatchValues.push("'" + property + "' was '" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + "' in expected, but was '" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + "' in actual.");
927 }
928 }
929
930 if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) {
931 mismatchValues.push("arrays were not the same length");
932 }
933
934 delete a.__Jasmine_been_here_before__;
935 delete b.__Jasmine_been_here_before__;
936 return (mismatchKeys.length === 0 && mismatchValues.length === 0);
937 };
938
939 jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) {
940 mismatchKeys = mismatchKeys || [];
941 mismatchValues = mismatchValues || [];
942
943 for (var i = 0; i < this.equalityTesters_.length; i++) {
944 var equalityTester = this.equalityTesters_[i];
945 var result = equalityTester(a, b, this, mismatchKeys, mismatchValues);
946 if (result !== jasmine.undefined) return result;
947 }
948
949 if (a === b) return true;
950
951 if (a === jasmine.undefined || a === null || b === jasmine.undefined || b === null) {
952 return (a == jasmine.undefined && b == jasmine.undefined);
953 }
954
955 if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) {
956 return a === b;
957 }
958
959 if (a instanceof Date && b instanceof Date) {
960 return a.getTime() == b.getTime();
961 }
962
963 if (a.jasmineMatches) {
964 return a.jasmineMatches(b);
965 }
966
967 if (b.jasmineMatches) {
968 return b.jasmineMatches(a);
969 }
970
971 if (a instanceof jasmine.Matchers.ObjectContaining) {
972 return a.matches(b);
973 }
974
975 if (b instanceof jasmine.Matchers.ObjectContaining) {
976 return b.matches(a);
977 }
978
979 if (jasmine.isString_(a) && jasmine.isString_(b)) {
980 return (a == b);
981 }
982
983 if (jasmine.isNumber_(a) && jasmine.isNumber_(b)) {
984 return (a == b);
985 }
986
987 if (a instanceof RegExp && b instanceof RegExp) {
988 return this.compareRegExps_(a, b, mismatchKeys, mismatchValues);
989 }
990
991 if (typeof a === "object" && typeof b === "object") {
992 return this.compareObjects_(a, b, mismatchKeys, mismatchValues);
993 }
994
995 //Straight check
996 return (a === b);
997 };
998
999 jasmine.Env.prototype.contains_ = function(haystack, needle) {
1000 if (jasmine.isArray_(haystack)) {
1001 for (var i = 0; i < haystack.length; i++) {
1002 if (this.equals_(haystack[i], needle)) return true;
1003 }
1004 return false;
1005 }
1006 return haystack.indexOf(needle) >= 0;
1007 };
1008
1009 jasmine.Env.prototype.addEqualityTester = function(equalityTester) {
1010 this.equalityTesters_.push(equalityTester);
1011 };
1012 /** No-op base class for Jasmine reporters.
1013 *
1014 * @constructor
1015 */
1016 jasmine.Reporter = function() {
1017 };
1018
1019 //noinspection JSUnusedLocalSymbols
1020 jasmine.Reporter.prototype.reportRunnerStarting = function(runner) {
1021 };
1022
1023 //noinspection JSUnusedLocalSymbols
1024 jasmine.Reporter.prototype.reportRunnerResults = function(runner) {
1025 };
1026
1027 //noinspection JSUnusedLocalSymbols
1028 jasmine.Reporter.prototype.reportSuiteResults = function(suite) {
1029 };
1030
1031 //noinspection JSUnusedLocalSymbols
1032 jasmine.Reporter.prototype.reportSpecStarting = function(spec) {
1033 };
1034
1035 //noinspection JSUnusedLocalSymbols
1036 jasmine.Reporter.prototype.reportSpecResults = function(spec) {
1037 };
1038
1039 //noinspection JSUnusedLocalSymbols
1040 jasmine.Reporter.prototype.log = function(str) {
1041 };
1042
1043 /**
1044 * Blocks are functions with executable code that make up a spec.
1045 *
1046 * @constructor
1047 * @param {jasmine.Env} env
1048 * @param {Function} func
1049 * @param {jasmine.Spec} spec
1050 */
1051 jasmine.Block = function(env, func, spec) {
1052 this.env = env;
1053 this.func = func;
1054 this.spec = spec;
1055 };
1056
1057 jasmine.Block.prototype.execute = function(onComplete) {
1058 if (!jasmine.CATCH_EXCEPTIONS) {
1059 this.func.apply(this.spec);
1060 }
1061 else {
1062 try {
1063 this.func.apply(this.spec);
1064 } catch (e) {
1065 this.spec.fail(e);
1066 }
1067 }
1068 onComplete();
1069 };
1070 /** JavaScript API reporter.
1071 *
1072 * @constructor
1073 */
1074 jasmine.JsApiReporter = function() {
1075 this.started = false;
1076 this.finished = false;
1077 this.suites_ = [];
1078 this.results_ = {};
1079 };
1080
1081 jasmine.JsApiReporter.prototype.reportRunnerStarting = function(runner) {
1082 this.started = true;
1083 var suites = runner.topLevelSuites();
1084 for (var i = 0; i < suites.length; i++) {
1085 var suite = suites[i];
1086 this.suites_.push(this.summarize_(suite));
1087 }
1088 };
1089
1090 jasmine.JsApiReporter.prototype.suites = function() {
1091 return this.suites_;
1092 };
1093
1094 jasmine.JsApiReporter.prototype.summarize_ = function(suiteOrSpec) {
1095 var isSuite = suiteOrSpec instanceof jasmine.Suite;
1096 var summary = {
1097 id: suiteOrSpec.id,
1098 name: suiteOrSpec.description,
1099 type: isSuite ? 'suite' : 'spec',
1100 children: []
1101 };
1102
1103 if (isSuite) {
1104 var children = suiteOrSpec.children();
1105 for (var i = 0; i < children.length; i++) {
1106 summary.children.push(this.summarize_(children[i]));
1107 }
1108 }
1109 return summary;
1110 };
1111
1112 jasmine.JsApiReporter.prototype.results = function() {
1113 return this.results_;
1114 };
1115
1116 jasmine.JsApiReporter.prototype.resultsForSpec = function(specId) {
1117 return this.results_[specId];
1118 };
1119
1120 //noinspection JSUnusedLocalSymbols
1121 jasmine.JsApiReporter.prototype.reportRunnerResults = function(runner) {
1122 this.finished = true;
1123 };
1124
1125 //noinspection JSUnusedLocalSymbols
1126 jasmine.JsApiReporter.prototype.reportSuiteResults = function(suite) {
1127 };
1128
1129 //noinspection JSUnusedLocalSymbols
1130 jasmine.JsApiReporter.prototype.reportSpecResults = function(spec) {
1131 this.results_[spec.id] = {
1132 messages: spec.results().getItems(),
1133 result: spec.results().failedCount > 0 ? "failed" : "passed"
1134 };
1135 };
1136
1137 //noinspection JSUnusedLocalSymbols
1138 jasmine.JsApiReporter.prototype.log = function(str) {
1139 };
1140
1141 jasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){
1142 var results = {};
1143 for (var i = 0; i < specIds.length; i++) {
1144 var specId = specIds[i];
1145 results[specId] = this.summarizeResult_(this.results_[specId]);
1146 }
1147 return results;
1148 };
1149
1150 jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){
1151 var summaryMessages = [];
1152 var messagesLength = result.messages.length;
1153 for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) {
1154 var resultMessage = result.messages[messageIndex];
1155 summaryMessages.push({
1156 text: resultMessage.type == 'log' ? resultMessage.toString() : jasmine.undefined,
1157 passed: resultMessage.passed ? resultMessage.passed() : true,
1158 type: resultMessage.type,
1159 message: resultMessage.message,
1160 trace: {
1161 stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined
1162 }
1163 });
1164 }
1165
1166 return {
1167 result : result.result,
1168 messages : summaryMessages
1169 };
1170 };
1171
1172 /**
1173 * @constructor
1174 * @param {jasmine.Env} env
1175 * @param actual
1176 * @param {jasmine.Spec} spec
1177 */
1178 jasmine.Matchers = function(env, actual, spec, opt_isNot) {
1179 this.env = env;
1180 this.actual = actual;
1181 this.spec = spec;
1182 this.isNot = opt_isNot || false;
1183 this.reportWasCalled_ = false;
1184 };
1185
1186 // todo: @deprecated as of Jasmine 0.11, remove soon [xw]
1187 jasmine.Matchers.pp = function(str) {
1188 throw new Error("jasmine.Matchers.pp() is no longer supported, please use jasmine.pp() instead!");
1189 };
1190
1191 // todo: @deprecated Deprecated as of Jasmine 0.10. Rewrite your custom matchers to return true or false. [xw]
1192 jasmine.Matchers.prototype.report = function(result, failing_message, details) {
1193 throw new Error("As of jasmine 0.11, custom matchers must be implemented differently -- please see jasmine docs");
1194 };
1195
1196 jasmine.Matchers.wrapInto_ = function(prototype, matchersClass) {
1197 for (var methodName in prototype) {
1198 if (methodName == 'report') continue;
1199 var orig = prototype[methodName];
1200 matchersClass.prototype[methodName] = jasmine.Matchers.matcherFn_(methodName, orig);
1201 }
1202 };
1203
1204 jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) {
1205 return function() {
1206 var matcherArgs = jasmine.util.argsToArray(arguments);
1207 var result = matcherFunction.apply(this, arguments);
1208
1209 if (this.isNot) {
1210 result = !result;
1211 }
1212
1213 if (this.reportWasCalled_) return result;
1214
1215 var message;
1216 if (!result) {
1217 if (this.message) {
1218 message = this.message.apply(this, arguments);
1219 if (jasmine.isArray_(message)) {
1220 message = message[this.isNot ? 1 : 0];
1221 }
1222 } else {
1223 var englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); });
1224 message = "Expected " + jasmine.pp(this.actual) + (this.isNot ? " not " : " ") + englishyPredicate;
1225 if (matcherArgs.length > 0) {
1226 for (var i = 0; i < matcherArgs.length; i++) {
1227 if (i > 0) message += ",";
1228 message += " " + jasmine.pp(matcherArgs[i]);
1229 }
1230 }
1231 message += ".";
1232 }
1233 }
1234 var expectationResult = new jasmine.ExpectationResult({
1235 matcherName: matcherName,
1236 passed: result,
1237 expected: matcherArgs.length > 1 ? matcherArgs : matcherArgs[0],
1238 actual: this.actual,
1239 message: message
1240 });
1241 this.spec.addMatcherResult(expectationResult);
1242 return jasmine.undefined;
1243 };
1244 };
1245
1246
1247
1248
1249 /**
1250 * toBe: compares the actual to the expected using ===
1251 * @param expected
1252 */
1253 jasmine.Matchers.prototype.toBe = function(expected) {
1254 return this.actual === expected;
1255 };
1256
1257 /**
1258 * toNotBe: compares the actual to the expected using !==
1259 * @param expected
1260 * @deprecated as of 1.0. Use not.toBe() instead.
1261 */
1262 jasmine.Matchers.prototype.toNotBe = function(expected) {
1263 return this.actual !== expected;
1264 };
1265
1266 /**
1267 * toEqual: compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc.
1268 *
1269 * @param expected
1270 */
1271 jasmine.Matchers.prototype.toEqual = function(expected) {
1272 return this.env.equals_(this.actual, expected);
1273 };
1274
1275 /**
1276 * toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual
1277 * @param expected
1278 * @deprecated as of 1.0. Use not.toEqual() instead.
1279 */
1280 jasmine.Matchers.prototype.toNotEqual = function(expected) {
1281 return !this.env.equals_(this.actual, expected);
1282 };
1283
1284 /**
1285 * Matcher that compares the actual to the expected using a regular expression. Constructs a RegExp, so takes
1286 * a pattern or a String.
1287 *
1288 * @param expected
1289 */
1290 jasmine.Matchers.prototype.toMatch = function(expected) {
1291 return new RegExp(expected).test(this.actual);
1292 };
1293
1294 /**
1295 * Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch
1296 * @param expected
1297 * @deprecated as of 1.0. Use not.toMatch() instead.
1298 */
1299 jasmine.Matchers.prototype.toNotMatch = function(expected) {
1300 return !(new RegExp(expected).test(this.actual));
1301 };
1302
1303 /**
1304 * Matcher that compares the actual to jasmine.undefined.
1305 */
1306 jasmine.Matchers.prototype.toBeDefined = function() {
1307 return (this.actual !== jasmine.undefined);
1308 };
1309
1310 /**
1311 * Matcher that compares the actual to jasmine.undefined.
1312 */
1313 jasmine.Matchers.prototype.toBeUndefined = function() {
1314 return (this.actual === jasmine.undefined);
1315 };
1316
1317 /**
1318 * Matcher that compares the actual to null.
1319 */
1320 jasmine.Matchers.prototype.toBeNull = function() {
1321 return (this.actual === null);
1322 };
1323
1324 /**
1325 * Matcher that compares the actual to NaN.
1326 */
1327 jasmine.Matchers.prototype.toBeNaN = function() {
1328 this.message = function() {
1329 return [ "Expected " + jasmine.pp(this.actual) + " to be NaN." ];
1330 };
1331
1332 return (this.actual !== this.actual);
1333 };
1334
1335 /**
1336 * Matcher that boolean not-nots the actual.
1337 */
1338 jasmine.Matchers.prototype.toBeTruthy = function() {
1339 return !!this.actual;
1340 };
1341
1342
1343 /**
1344 * Matcher that boolean nots the actual.
1345 */
1346 jasmine.Matchers.prototype.toBeFalsy = function() {
1347 return !this.actual;
1348 };
1349
1350
1351 /**
1352 * Matcher that checks to see if the actual, a Jasmine spy, was called.
1353 */
1354 jasmine.Matchers.prototype.toHaveBeenCalled = function() {
1355 if (arguments.length > 0) {
1356 throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith');
1357 }
1358
1359 if (!jasmine.isSpy(this.actual)) {
1360 throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
1361 }
1362
1363 this.message = function() {
1364 return [
1365 "Expected spy " + this.actual.identity + " to have been called.",
1366 "Expected spy " + this.actual.identity + " not to have been called."
1367 ];
1368 };
1369
1370 return this.actual.wasCalled;
1371 };
1372
1373 /** @deprecated Use expect(xxx).toHaveBeenCalled() instead */
1374 jasmine.Matchers.prototype.wasCalled = jasmine.Matchers.prototype.toHaveBeenCalled;
1375
1376 /**
1377 * Matcher that checks to see if the actual, a Jasmine spy, was not called.
1378 *
1379 * @deprecated Use expect(xxx).not.toHaveBeenCalled() instead
1380 */
1381 jasmine.Matchers.prototype.wasNotCalled = function() {
1382 if (arguments.length > 0) {
1383 throw new Error('wasNotCalled does not take arguments');
1384 }
1385
1386 if (!jasmine.isSpy(this.actual)) {
1387 throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
1388 }
1389
1390 this.message = function() {
1391 return [
1392 "Expected spy " + this.actual.identity + " to not have been called.",
1393 "Expected spy " + this.actual.identity + " to have been called."
1394 ];
1395 };
1396
1397 return !this.actual.wasCalled;
1398 };
1399
1400 /**
1401 * Matcher that checks to see if the actual, a Jasmine spy, was called with a set of parameters.
1402 *
1403 * @example
1404 *
1405 */
1406 jasmine.Matchers.prototype.toHaveBeenCalledWith = function() {
1407 var expectedArgs = jasmine.util.argsToArray(arguments);
1408 if (!jasmine.isSpy(this.actual)) {
1409 throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
1410 }
1411 this.message = function() {
1412 var invertedMessage = "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but it was.";
1413 var positiveMessage = "";
1414 if (this.actual.callCount === 0) {
1415 positiveMessage = "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.";
1416 } else {
1417 positiveMessage = "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but actual calls were " + jasmine.pp(this.actual.argsForCall).replace(/^\[ | \]$/g, '')
1418 }
1419 return [positiveMessage, invertedMessage];
1420 };
1421
1422 return this.env.contains_(this.actual.argsForCall, expectedArgs);
1423 };
1424
1425 /** @deprecated Use expect(xxx).toHaveBeenCalledWith() instead */
1426 jasmine.Matchers.prototype.wasCalledWith = jasmine.Matchers.prototype.toHaveBeenCalledWith;
1427
1428 /** @deprecated Use expect(xxx).not.toHaveBeenCalledWith() instead */
1429 jasmine.Matchers.prototype.wasNotCalledWith = function() {
1430 var expectedArgs = jasmine.util.argsToArray(arguments);
1431 if (!jasmine.isSpy(this.actual)) {
1432 throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
1433 }
1434
1435 this.message = function() {
1436 return [
1437 "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was",
1438 "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was"
1439 ];
1440 };
1441
1442 return !this.env.contains_(this.actual.argsForCall, expectedArgs);
1443 };
1444
1445 /**
1446 * Matcher that checks that the expected item is an element in the actual Array.
1447 *
1448 * @param {Object} expected
1449 */
1450 jasmine.Matchers.prototype.toContain = function(expected) {
1451 return this.env.contains_(this.actual, expected);
1452 };
1453
1454 /**
1455 * Matcher that checks that the expected item is NOT an element in the actual Array.
1456 *
1457 * @param {Object} expected
1458 * @deprecated as of 1.0. Use not.toContain() instead.
1459 */
1460 jasmine.Matchers.prototype.toNotContain = function(expected) {
1461 return !this.env.contains_(this.actual, expected);
1462 };
1463
1464 jasmine.Matchers.prototype.toBeLessThan = function(expected) {
1465 return this.actual < expected;
1466 };
1467
1468 jasmine.Matchers.prototype.toBeGreaterThan = function(expected) {
1469 return this.actual > expected;
1470 };
1471
1472 /**
1473 * Matcher that checks that the expected item is equal to the actual item
1474 * up to a given level of decimal precision (default 2).
1475 *
1476 * @param {Number} expected
1477 * @param {Number} precision, as number of decimal places
1478 */
1479 jasmine.Matchers.prototype.toBeCloseTo = function(expected, precision) {
1480 if (!(precision === 0)) {
1481 precision = precision || 2;
1482 }
1483 return Math.abs(expected - this.actual) < (Math.pow(10, -precision) / 2);
1484 };
1485
1486 /**
1487 * Matcher that checks that the expected exception was thrown by the actual.
1488 *
1489 * @param {String} [expected]
1490 */
1491 jasmine.Matchers.prototype.toThrow = function(expected) {
1492 var result = false;
1493 var exception;
1494 if (typeof this.actual != 'function') {
1495 throw new Error('Actual is not a function');
1496 }
1497 try {
1498 this.actual();
1499 } catch (e) {
1500 exception = e;
1501 }
1502 if (exception) {
1503 result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected));
1504 }
1505
1506 var not = this.isNot ? "not " : "";
1507
1508 this.message = function() {
1509 if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) {
1510 return ["Expected function " + not + "to throw", expected ? expected.message || expected : "an exception", ", but it threw", exception.message || exception].join(' ');
1511 } else {
1512 return "Expected function to throw an exception.";
1513 }
1514 };
1515
1516 return result;
1517 };
1518
1519 jasmine.Matchers.Any = function(expectedClass) {
1520 this.expectedClass = expectedClass;
1521 };
1522
1523 jasmine.Matchers.Any.prototype.jasmineMatches = function(other) {
1524 if (this.expectedClass == String) {
1525 return typeof other == 'string' || other instanceof String;
1526 }
1527
1528 if (this.expectedClass == Number) {
1529 return typeof other == 'number' || other instanceof Number;
1530 }
1531
1532 if (this.expectedClass == Function) {
1533 return typeof other == 'function' || other instanceof Function;
1534 }
1535
1536 if (this.expectedClass == Object) {
1537 return typeof other == 'object';
1538 }
1539
1540 return other instanceof this.expectedClass;
1541 };
1542
1543 jasmine.Matchers.Any.prototype.jasmineToString = function() {
1544 return '<jasmine.any(' + this.expectedClass + ')>';
1545 };
1546
1547 jasmine.Matchers.ObjectContaining = function (sample) {
1548 this.sample = sample;
1549 };
1550
1551 jasmine.Matchers.ObjectContaining.prototype.jasmineMatches = function(other, mismatchKeys, mismatchValues) {
1552 mismatchKeys = mismatchKeys || [];
1553 mismatchValues = mismatchValues || [];
1554
1555 var env = jasmine.getEnv();
1556
1557 var hasKey = function(obj, keyName) {
1558 return obj != null && obj[keyName] !== jasmine.undefined;
1559 };
1560
1561 for (var property in this.sample) {
1562 if (!hasKey(other, property) && hasKey(this.sample, property)) {
1563 mismatchKeys.push("expected has key '" + property + "', but missing from actual.");
1564 }
1565 else if (!env.equals_(this.sample[property], other[property], mismatchKeys, mismatchValues)) {
1566 mismatchValues.push("'" + property + "' was '" + (other[property] ? jasmine.util.htmlEscape(other[property].toString()) : other[property]) + "' in expected, but was '" + (this.sample[property] ? jasmine.util.htmlEscape(this.sample[property].toString()) : this.sample[property]) + "' in actual.");
1567 }
1568 }
1569
1570 return (mismatchKeys.length === 0 && mismatchValues.length === 0);
1571 };
1572
1573 jasmine.Matchers.ObjectContaining.prototype.jasmineToString = function () {
1574 return "<jasmine.objectContaining(" + jasmine.pp(this.sample) + ")>";
1575 };
1576 // Mock setTimeout, clearTimeout
1577 // Contributed by Pivotal Computer Systems, www.pivotalsf.com
1578
1579 jasmine.FakeTimer = function() {
1580 this.reset();
1581
1582 var self = this;
1583 self.setTimeout = function(funcToCall, millis) {
1584 self.timeoutsMade++;
1585 self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false);
1586 return self.timeoutsMade;
1587 };
1588
1589 self.setInterval = function(funcToCall, millis) {
1590 self.timeoutsMade++;
1591 self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true);
1592 return self.timeoutsMade;
1593 };
1594
1595 self.clearTimeout = function(timeoutKey) {
1596 self.scheduledFunctions[timeoutKey] = jasmine.undefined;
1597 };
1598
1599 self.clearInterval = function(timeoutKey) {
1600 self.scheduledFunctions[timeoutKey] = jasmine.undefined;
1601 };
1602
1603 };
1604
1605 jasmine.FakeTimer.prototype.reset = function() {
1606 this.timeoutsMade = 0;
1607 this.scheduledFunctions = {};
1608 this.nowMillis = 0;
1609 };
1610
1611 jasmine.FakeTimer.prototype.tick = function(millis) {
1612 var oldMillis = this.nowMillis;
1613 var newMillis = oldMillis + millis;
1614 this.runFunctionsWithinRange(oldMillis, newMillis);
1615 this.nowMillis = newMillis;
1616 };
1617
1618 jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) {
1619 var scheduledFunc;
1620 var funcsToRun = [];
1621 for (var timeoutKey in this.scheduledFunctions) {
1622 scheduledFunc = this.scheduledFunctions[timeoutKey];
1623 if (scheduledFunc != jasmine.undefined &&
1624 scheduledFunc.runAtMillis >= oldMillis &&
1625 scheduledFunc.runAtMillis <= nowMillis) {
1626 funcsToRun.push(scheduledFunc);
1627 this.scheduledFunctions[timeoutKey] = jasmine.undefined;
1628 }
1629 }
1630
1631 if (funcsToRun.length > 0) {
1632 funcsToRun.sort(function(a, b) {
1633 return a.runAtMillis - b.runAtMillis;
1634 });
1635 for (var i = 0; i < funcsToRun.length; ++i) {
1636 try {
1637 var funcToRun = funcsToRun[i];
1638 this.nowMillis = funcToRun.runAtMillis;
1639 funcToRun.funcToCall();
1640 if (funcToRun.recurring) {
1641 this.scheduleFunction(funcToRun.timeoutKey,
1642 funcToRun.funcToCall,
1643 funcToRun.millis,
1644 true);
1645 }
1646 } catch(e) {
1647 }
1648 }
1649 this.runFunctionsWithinRange(oldMillis, nowMillis);
1650 }
1651 };
1652
1653 jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) {
1654 this.scheduledFunctions[timeoutKey] = {
1655 runAtMillis: this.nowMillis + millis,
1656 funcToCall: funcToCall,
1657 recurring: recurring,
1658 timeoutKey: timeoutKey,
1659 millis: millis
1660 };
1661 };
1662
1663 /**
1664 * @namespace
1665 */
1666 jasmine.Clock = {
1667 defaultFakeTimer: new jasmine.FakeTimer(),
1668
1669 reset: function() {
1670 jasmine.Clock.assertInstalled();
1671 jasmine.Clock.defaultFakeTimer.reset();
1672 },
1673
1674 tick: function(millis) {
1675 jasmine.Clock.assertInstalled();
1676 jasmine.Clock.defaultFakeTimer.tick(millis);
1677 },
1678
1679 runFunctionsWithinRange: function(oldMillis, nowMillis) {
1680 jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis);
1681 },
1682
1683 scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) {
1684 jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring);
1685 },
1686
1687 useMock: function() {
1688 if (!jasmine.Clock.isInstalled()) {
1689 var spec = jasmine.getEnv().currentSpec;
1690 spec.after(jasmine.Clock.uninstallMock);
1691
1692 jasmine.Clock.installMock();
1693 }
1694 },
1695
1696 installMock: function() {
1697 jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer;
1698 },
1699
1700 uninstallMock: function() {
1701 jasmine.Clock.assertInstalled();
1702 jasmine.Clock.installed = jasmine.Clock.real;
1703 },
1704
1705 real: {
1706 setTimeout: jasmine.getGlobal().setTimeout,
1707 clearTimeout: jasmine.getGlobal().clearTimeout,
1708 setInterval: jasmine.getGlobal().setInterval,
1709 clearInterval: jasmine.getGlobal().clearInterval
1710 },
1711
1712 assertInstalled: function() {
1713 if (!jasmine.Clock.isInstalled()) {
1714 throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()");
1715 }
1716 },
1717
1718 isInstalled: function() {
1719 return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer;
1720 },
1721
1722 installed: null
1723 };
1724 jasmine.Clock.installed = jasmine.Clock.real;
1725
1726 //else for IE support
1727 jasmine.getGlobal().setTimeout = function(funcToCall, millis) {
1728 if (jasmine.Clock.installed.setTimeout.apply) {
1729 return jasmine.Clock.installed.setTimeout.apply(this, arguments);
1730 } else {
1731 return jasmine.Clock.installed.setTimeout(funcToCall, millis);
1732 }
1733 };
1734
1735 jasmine.getGlobal().setInterval = function(funcToCall, millis) {
1736 if (jasmine.Clock.installed.setInterval.apply) {
1737 return jasmine.Clock.installed.setInterval.apply(this, arguments);
1738 } else {
1739 return jasmine.Clock.installed.setInterval(funcToCall, millis);
1740 }
1741 };
1742
1743 jasmine.getGlobal().clearTimeout = function(timeoutKey) {
1744 if (jasmine.Clock.installed.clearTimeout.apply) {
1745 return jasmine.Clock.installed.clearTimeout.apply(this, arguments);
1746 } else {
1747 return jasmine.Clock.installed.clearTimeout(timeoutKey);
1748 }
1749 };
1750
1751 jasmine.getGlobal().clearInterval = function(timeoutKey) {
1752 if (jasmine.Clock.installed.clearTimeout.apply) {
1753 return jasmine.Clock.installed.clearInterval.apply(this, arguments);
1754 } else {
1755 return jasmine.Clock.installed.clearInterval(timeoutKey);
1756 }
1757 };
1758
1759 /**
1760 * @constructor
1761 */
1762 jasmine.MultiReporter = function() {
1763 this.subReporters_ = [];
1764 };
1765 jasmine.util.inherit(jasmine.MultiReporter, jasmine.Reporter);
1766
1767 jasmine.MultiReporter.prototype.addReporter = function(reporter) {
1768 this.subReporters_.push(reporter);
1769 };
1770
1771 (function() {
1772 var functionNames = [
1773 "reportRunnerStarting",
1774 "reportRunnerResults",
1775 "reportSuiteResults",
1776 "reportSpecStarting",
1777 "reportSpecResults",
1778 "log"
1779 ];
1780 for (var i = 0; i < functionNames.length; i++) {
1781 var functionName = functionNames[i];
1782 jasmine.MultiReporter.prototype[functionName] = (function(functionName) {
1783 return function() {
1784 for (var j = 0; j < this.subReporters_.length; j++) {
1785 var subReporter = this.subReporters_[j];
1786 if (subReporter[functionName]) {
1787 subReporter[functionName].apply(subReporter, arguments);
1788 }
1789 }
1790 };
1791 })(functionName);
1792 }
1793 })();
1794 /**
1795 * Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults
1796 *
1797 * @constructor
1798 */
1799 jasmine.NestedResults = function() {
1800 /**
1801 * The total count of results
1802 */
1803 this.totalCount = 0;
1804 /**
1805 * Number of passed results
1806 */
1807 this.passedCount = 0;
1808 /**
1809 * Number of failed results
1810 */
1811 this.failedCount = 0;
1812 /**
1813 * Was this suite/spec skipped?
1814 */
1815 this.skipped = false;
1816 /**
1817 * @ignore
1818 */
1819 this.items_ = [];
1820 };
1821
1822 /**
1823 * Roll up the result counts.
1824 *
1825 * @param result
1826 */
1827 jasmine.NestedResults.prototype.rollupCounts = function(result) {
1828 this.totalCount += result.totalCount;
1829 this.passedCount += result.passedCount;
1830 this.failedCount += result.failedCount;
1831 };
1832
1833 /**
1834 * Adds a log message.
1835 * @param values Array of message parts which will be concatenated later.
1836 */
1837 jasmine.NestedResults.prototype.log = function(values) {
1838 this.items_.push(new jasmine.MessageResult(values));
1839 };
1840
1841 /**
1842 * Getter for the results: message & results.
1843 */
1844 jasmine.NestedResults.prototype.getItems = function() {
1845 return this.items_;
1846 };
1847
1848 /**
1849 * Adds a result, tracking counts (total, passed, & failed)
1850 * @param {jasmine.ExpectationResult|jasmine.NestedResults} result
1851 */
1852 jasmine.NestedResults.prototype.addResult = function(result) {
1853 if (result.type != 'log') {
1854 if (result.items_) {
1855 this.rollupCounts(result);
1856 } else {
1857 this.totalCount++;
1858 if (result.passed()) {
1859 this.passedCount++;
1860 } else {
1861 this.failedCount++;
1862 }
1863 }
1864 }
1865 this.items_.push(result);
1866 };
1867
1868 /**
1869 * @returns {Boolean} True if <b>everything</b> below passed
1870 */
1871 jasmine.NestedResults.prototype.passed = function() {
1872 return this.passedCount === this.totalCount;
1873 };
1874 /**
1875 * Base class for pretty printing for expectation results.
1876 */
1877 jasmine.PrettyPrinter = function() {
1878 this.ppNestLevel_ = 0;
1879 };
1880
1881 /**
1882 * Formats a value in a nice, human-readable string.
1883 *
1884 * @param value
1885 */
1886 jasmine.PrettyPrinter.prototype.format = function(value) {
1887 this.ppNestLevel_++;
1888 try {
1889 if (value === jasmine.undefined) {
1890 this.emitScalar('undefined');
1891 } else if (value === null) {
1892 this.emitScalar('null');
1893 } else if (value === jasmine.getGlobal()) {
1894 this.emitScalar('<global>');
1895 } else if (value.jasmineToString) {
1896 this.emitScalar(value.jasmineToString());
1897 } else if (typeof value === 'string') {
1898 this.emitString(value);
1899 } else if (jasmine.isSpy(value)) {
1900 this.emitScalar("spy on " + value.identity);
1901 } else if (value instanceof RegExp) {
1902 this.emitScalar(value.toString());
1903 } else if (typeof value === 'function') {
1904 this.emitScalar('Function');
1905 } else if (typeof value.nodeType === 'number') {
1906 this.emitScalar('HTMLNode');
1907 } else if (value instanceof Date) {
1908 this.emitScalar('Date(' + value + ')');
1909 } else if (value.__Jasmine_been_here_before__) {
1910 this.emitScalar('<circular reference: ' + (jasmine.isArray_(value) ? 'Array' : 'Object') + '>');
1911 } else if (jasmine.isArray_(value) || typeof value == 'object') {
1912 value.__Jasmine_been_here_before__ = true;
1913 if (jasmine.isArray_(value)) {
1914 this.emitArray(value);
1915 } else {
1916 this.emitObject(value);
1917 }
1918 delete value.__Jasmine_been_here_before__;
1919 } else {
1920 this.emitScalar(value.toString());
1921 }
1922 } finally {
1923 this.ppNestLevel_--;
1924 }
1925 };
1926
1927 jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) {
1928 for (var property in obj) {
1929 if (!obj.hasOwnProperty(property)) continue;
1930 if (property == '__Jasmine_been_here_before__') continue;
1931 fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) !== jasmine.undefined &&
1932 obj.__lookupGetter__(property) !== null) : false);
1933 }
1934 };
1935
1936 jasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_;
1937 jasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_;
1938 jasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_;
1939 jasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_;
1940
1941 jasmine.StringPrettyPrinter = function() {
1942 jasmine.PrettyPrinter.call(this);
1943
1944 this.string = '';
1945 };
1946 jasmine.util.inherit(jasmine.StringPrettyPrinter, jasmine.PrettyPrinter);
1947
1948 jasmine.StringPrettyPrinter.prototype.emitScalar = function(value) {
1949 this.append(value);
1950 };
1951
1952 jasmine.StringPrettyPrinter.prototype.emitString = function(value) {
1953 this.append("'" + value + "'");
1954 };
1955
1956 jasmine.StringPrettyPrinter.prototype.emitArray = function(array) {
1957 if (this.ppNestLevel_ > jasmine.MAX_PRETTY_PRINT_DEPTH) {
1958 this.append("Array");
1959 return;
1960 }
1961
1962 this.append('[ ');
1963 for (var i = 0; i < array.length; i++) {
1964 if (i > 0) {
1965 this.append(', ');
1966 }
1967 this.format(array[i]);
1968 }
1969 this.append(' ]');
1970 };
1971
1972 jasmine.StringPrettyPrinter.prototype.emitObject = function(obj) {
1973 if (this.ppNestLevel_ > jasmine.MAX_PRETTY_PRINT_DEPTH) {
1974 this.append("Object");
1975 return;
1976 }
1977
1978 var self = this;
1979 this.append('{ ');
1980 var first = true;
1981
1982 this.iterateObject(obj, function(property, isGetter) {
1983 if (first) {
1984 first = false;
1985 } else {
1986 self.append(', ');
1987 }
1988
1989 self.append(property);
1990 self.append(' : ');
1991 if (isGetter) {
1992 self.append('<getter>');
1993 } else {
1994 self.format(obj[property]);
1995 }
1996 });
1997
1998 this.append(' }');
1999 };
2000
2001 jasmine.StringPrettyPrinter.prototype.append = function(value) {
2002 this.string += value;
2003 };
2004 jasmine.Queue = function(env) {
2005 this.env = env;
2006
2007 // parallel to blocks. each true value in this array means the block will
2008 // get executed even if we abort
2009 this.ensured = [];
2010 this.blocks = [];
2011 this.running = false;
2012 this.index = 0;
2013 this.offset = 0;
2014 this.abort = false;
2015 };
2016
2017 jasmine.Queue.prototype.addBefore = function(block, ensure) {
2018 if (ensure === jasmine.undefined) {
2019 ensure = false;
2020 }
2021
2022 this.blocks.unshift(block);
2023 this.ensured.unshift(ensure);
2024 };
2025
2026 jasmine.Queue.prototype.add = function(block, ensure) {
2027 if (ensure === jasmine.undefined) {
2028 ensure = false;
2029 }
2030
2031 this.blocks.push(block);
2032 this.ensured.push(ensure);
2033 };
2034
2035 jasmine.Queue.prototype.insertNext = function(block, ensure) {
2036 if (ensure === jasmine.undefined) {
2037 ensure = false;
2038 }
2039
2040 this.ensured.splice((this.index + this.offset + 1), 0, ensure);
2041 this.blocks.splice((this.index + this.offset + 1), 0, block);
2042 this.offset++;
2043 };
2044
2045 jasmine.Queue.prototype.start = function(onComplete) {
2046 this.running = true;
2047 this.onComplete = onComplete;
2048 this.next_();
2049 };
2050
2051 jasmine.Queue.prototype.isRunning = function() {
2052 return this.running;
2053 };
2054
2055 jasmine.Queue.LOOP_DONT_RECURSE = true;
2056
2057 jasmine.Queue.prototype.next_ = function() {
2058 var self = this;
2059 var goAgain = true;
2060
2061 while (goAgain) {
2062 goAgain = false;
2063
2064 if (self.index < self.blocks.length && !(this.abort && !this.ensured[self.index])) {
2065 var calledSynchronously = true;
2066 var completedSynchronously = false;
2067
2068 var onComplete = function () {
2069 if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) {
2070 completedSynchronously = true;
2071 return;
2072 }
2073
2074 if (self.blocks[self.index].abort) {
2075 self.abort = true;
2076 }
2077
2078 self.offset = 0;
2079 self.index++;
2080
2081 var now = new Date().getTime();
2082 if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) {
2083 self.env.lastUpdate = now;
2084 self.env.setTimeout(function() {
2085 self.next_();
2086 }, 0);
2087 } else {
2088 if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) {
2089 goAgain = true;
2090 } else {
2091 self.next_();
2092 }
2093 }
2094 };
2095 self.blocks[self.index].execute(onComplete);
2096
2097 calledSynchronously = false;
2098 if (completedSynchronously) {
2099 onComplete();
2100 }
2101
2102 } else {
2103 self.running = false;
2104 if (self.onComplete) {
2105 self.onComplete();
2106 }
2107 }
2108 }
2109 };
2110
2111 jasmine.Queue.prototype.results = function() {
2112 var results = new jasmine.NestedResults();
2113 for (var i = 0; i < this.blocks.length; i++) {
2114 if (this.blocks[i].results) {
2115 results.addResult(this.blocks[i].results());
2116 }
2117 }
2118 return results;
2119 };
2120
2121
2122 /**
2123 * Runner
2124 *
2125 * @constructor
2126 * @param {jasmine.Env} env
2127 */
2128 jasmine.Runner = function(env) {
2129 var self = this;
2130 self.env = env;
2131 self.queue = new jasmine.Queue(env);
2132 self.before_ = [];
2133 self.after_ = [];
2134 self.suites_ = [];
2135 };
2136
2137 jasmine.Runner.prototype.execute = function() {
2138 var self = this;
2139 if (self.env.reporter.reportRunnerStarting) {
2140 self.env.reporter.reportRunnerStarting(this);
2141 }
2142 self.queue.start(function () {
2143 self.finishCallback();
2144 });
2145 };
2146
2147 jasmine.Runner.prototype.beforeEach = function(beforeEachFunction) {
2148 beforeEachFunction.typeName = 'beforeEach';
2149 this.before_.splice(0,0,beforeEachFunction);
2150 };
2151
2152 jasmine.Runner.prototype.afterEach = function(afterEachFunction) {
2153 afterEachFunction.typeName = 'afterEach';
2154 this.after_.splice(0,0,afterEachFunction);
2155 };
2156
2157
2158 jasmine.Runner.prototype.finishCallback = function() {
2159 this.env.reporter.reportRunnerResults(this);
2160 };
2161
2162 jasmine.Runner.prototype.addSuite = function(suite) {
2163 this.suites_.push(suite);
2164 };
2165
2166 jasmine.Runner.prototype.add = function(block) {
2167 if (block instanceof jasmine.Suite) {
2168 this.addSuite(block);
2169 }
2170 this.queue.add(block);
2171 };
2172
2173 jasmine.Runner.prototype.specs = function () {
2174 var suites = this.suites();
2175 var specs = [];
2176 for (var i = 0; i < suites.length; i++) {
2177 specs = specs.concat(suites[i].specs());
2178 }
2179 return specs;
2180 };
2181
2182 jasmine.Runner.prototype.suites = function() {
2183 return this.suites_;
2184 };
2185
2186 jasmine.Runner.prototype.topLevelSuites = function() {
2187 var topLevelSuites = [];
2188 for (var i = 0; i < this.suites_.length; i++) {
2189 if (!this.suites_[i].parentSuite) {
2190 topLevelSuites.push(this.suites_[i]);
2191 }
2192 }
2193 return topLevelSuites;
2194 };
2195
2196 jasmine.Runner.prototype.results = function() {
2197 return this.queue.results();
2198 };
2199 /**
2200 * Internal representation of a Jasmine specification, or test.
2201 *
2202 * @constructor
2203 * @param {jasmine.Env} env
2204 * @param {jasmine.Suite} suite
2205 * @param {String} description
2206 */
2207 jasmine.Spec = function(env, suite, description) {
2208 if (!env) {
2209 throw new Error('jasmine.Env() required');
2210 }
2211 if (!suite) {
2212 throw new Error('jasmine.Suite() required');
2213 }
2214 var spec = this;
2215 spec.id = env.nextSpecId ? env.nextSpecId() : null;
2216 spec.env = env;
2217 spec.suite = suite;
2218 spec.description = description;
2219 spec.queue = new jasmine.Queue(env);
2220
2221 spec.afterCallbacks = [];
2222 spec.spies_ = [];
2223
2224 spec.results_ = new jasmine.NestedResults();
2225 spec.results_.description = description;
2226 spec.matchersClass = null;
2227 };
2228
2229 jasmine.Spec.prototype.getFullName = function() {
2230 return this.suite.getFullName() + ' ' + this.description + '.';
2231 };
2232
2233
2234 jasmine.Spec.prototype.results = function() {
2235 return this.results_;
2236 };
2237
2238 /**
2239 * All parameters are pretty-printed and concatenated together, then written to the spec's output.
2240 *
2241 * Be careful not to leave calls to <code>jasmine.log</code> in production code.
2242 */
2243 jasmine.Spec.prototype.log = function() {
2244 return this.results_.log(arguments);
2245 };
2246
2247 jasmine.Spec.prototype.runs = function (func) {
2248 var block = new jasmine.Block(this.env, func, this);
2249 this.addToQueue(block);
2250 return this;
2251 };
2252
2253 jasmine.Spec.prototype.addToQueue = function (block) {
2254 if (this.queue.isRunning()) {
2255 this.queue.insertNext(block);
2256 } else {
2257 this.queue.add(block);
2258 }
2259 };
2260
2261 /**
2262 * @param {jasmine.ExpectationResult} result
2263 */
2264 jasmine.Spec.prototype.addMatcherResult = function(result) {
2265 this.results_.addResult(result);
2266 };
2267
2268 jasmine.Spec.prototype.expect = function(actual) {
2269 var positive = new (this.getMatchersClass_())(this.env, actual, this);
2270 positive.not = new (this.getMatchersClass_())(this.env, actual, this, true);
2271 return positive;
2272 };
2273
2274 /**
2275 * Waits a fixed time period before moving to the next block.
2276 *
2277 * @deprecated Use waitsFor() instead
2278 * @param {Number} timeout milliseconds to wait
2279 */
2280 jasmine.Spec.prototype.waits = function(timeout) {
2281 var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this);
2282 this.addToQueue(waitsFunc);
2283 return this;
2284 };
2285
2286 /**
2287 * Waits for the latchFunction to return true before proceeding to the next block.
2288 *
2289 * @param {Function} latchFunction
2290 * @param {String} optional_timeoutMessage
2291 * @param {Number} optional_timeout
2292 */
2293 jasmine.Spec.prototype.waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {
2294 var latchFunction_ = null;
2295 var optional_timeoutMessage_ = null;
2296 var optional_timeout_ = null;
2297
2298 for (var i = 0; i < arguments.length; i++) {
2299 var arg = arguments[i];
2300 switch (typeof arg) {
2301 case 'function':
2302 latchFunction_ = arg;
2303 break;
2304 case 'string':
2305 optional_timeoutMessage_ = arg;
2306 break;
2307 case 'number':
2308 optional_timeout_ = arg;
2309 break;
2310 }
2311 }
2312
2313 var waitsForFunc = new jasmine.WaitsForBlock(this.env, optional_timeout_, latchFunction_, optional_timeoutMessage_, this);
2314 this.addToQueue(waitsForFunc);
2315 return this;
2316 };
2317
2318 jasmine.Spec.prototype.fail = function (e) {
2319 var expectationResult = new jasmine.ExpectationResult({
2320 passed: false,
2321 message: e ? jasmine.util.formatException(e) : 'Exception',
2322 trace: { stack: e.stack }
2323 });
2324 this.results_.addResult(expectationResult);
2325 };
2326
2327 jasmine.Spec.prototype.getMatchersClass_ = function() {
2328 return this.matchersClass || this.env.matchersClass;
2329 };
2330
2331 jasmine.Spec.prototype.addMatchers = function(matchersPrototype) {
2332 var parent = this.getMatchersClass_();
2333 var newMatchersClass = function() {
2334 parent.apply(this, arguments);
2335 };
2336 jasmine.util.inherit(newMatchersClass, parent);
2337 jasmine.Matchers.wrapInto_(matchersPrototype, newMatchersClass);
2338 this.matchersClass = newMatchersClass;
2339 };
2340
2341 jasmine.Spec.prototype.finishCallback = function() {
2342 this.env.reporter.reportSpecResults(this);
2343 };
2344
2345 jasmine.Spec.prototype.finish = function(onComplete) {
2346 this.removeAllSpies();
2347 this.finishCallback();
2348 if (onComplete) {
2349 onComplete();
2350 }
2351 };
2352
2353 jasmine.Spec.prototype.after = function(doAfter) {
2354 if (this.queue.isRunning()) {
2355 this.queue.add(new jasmine.Block(this.env, doAfter, this), true);
2356 } else {
2357 this.afterCallbacks.unshift(doAfter);
2358 }
2359 };
2360
2361 jasmine.Spec.prototype.execute = function(onComplete) {
2362 var spec = this;
2363 if (!spec.env.specFilter(spec)) {
2364 spec.results_.skipped = true;
2365 spec.finish(onComplete);
2366 return;
2367 }
2368
2369 this.env.reporter.reportSpecStarting(this);
2370
2371 spec.env.currentSpec = spec;
2372
2373 spec.addBeforesAndAftersToQueue();
2374
2375 spec.queue.start(function () {
2376 spec.finish(onComplete);
2377 });
2378 };
2379
2380 jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() {
2381 var runner = this.env.currentRunner();
2382 var i;
2383
2384 for (var suite = this.suite; suite; suite = suite.parentSuite) {
2385 for (i = 0; i < suite.before_.length; i++) {
2386 this.queue.addBefore(new jasmine.Block(this.env, suite.before_[i], this));
2387 }
2388 }
2389 for (i = 0; i < runner.before_.length; i++) {
2390 this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this));
2391 }
2392 for (i = 0; i < this.afterCallbacks.length; i++) {
2393 this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this), true);
2394 }
2395 for (suite = this.suite; suite; suite = suite.parentSuite) {
2396 for (i = 0; i < suite.after_.length; i++) {
2397 this.queue.add(new jasmine.Block(this.env, suite.after_[i], this), true);
2398 }
2399 }
2400 for (i = 0; i < runner.after_.length; i++) {
2401 this.queue.add(new jasmine.Block(this.env, runner.after_[i], this), true);
2402 }
2403 };
2404
2405 jasmine.Spec.prototype.explodes = function() {
2406 throw 'explodes function should not have been called';
2407 };
2408
2409 jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) {
2410 if (obj == jasmine.undefined) {
2411 throw "spyOn could not find an object to spy upon for " + methodName + "()";
2412 }
2413
2414 if (!ignoreMethodDoesntExist && obj[methodName] === jasmine.undefined) {
2415 throw methodName + '() method does not exist';
2416 }
2417
2418 if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) {
2419 throw new Error(methodName + ' has already been spied upon');
2420 }
2421
2422 var spyObj = jasmine.createSpy(methodName);
2423
2424 this.spies_.push(spyObj);
2425 spyObj.baseObj = obj;
2426 spyObj.methodName = methodName;
2427 spyObj.originalValue = obj[methodName];
2428
2429 obj[methodName] = spyObj;
2430
2431 return spyObj;
2432 };
2433
2434 jasmine.Spec.prototype.removeAllSpies = function() {
2435 for (var i = 0; i < this.spies_.length; i++) {
2436 var spy = this.spies_[i];
2437 spy.baseObj[spy.methodName] = spy.originalValue;
2438 }
2439 this.spies_ = [];
2440 };
2441
2442 /**
2443 * Internal representation of a Jasmine suite.
2444 *
2445 * @constructor
2446 * @param {jasmine.Env} env
2447 * @param {String} description
2448 * @param {Function} specDefinitions
2449 * @param {jasmine.Suite} parentSuite
2450 */
2451 jasmine.Suite = function(env, description, specDefinitions, parentSuite) {
2452 var self = this;
2453 self.id = env.nextSuiteId ? env.nextSuiteId() : null;
2454 self.description = description;
2455 self.queue = new jasmine.Queue(env);
2456 self.parentSuite = parentSuite;
2457 self.env = env;
2458 self.before_ = [];
2459 self.after_ = [];
2460 self.children_ = [];
2461 self.suites_ = [];
2462 self.specs_ = [];
2463 };
2464
2465 jasmine.Suite.prototype.getFullName = function() {
2466 var fullName = this.description;
2467 for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) {
2468 fullName = parentSuite.description + ' ' + fullName;
2469 }
2470 return fullName;
2471 };
2472
2473 jasmine.Suite.prototype.finish = function(onComplete) {
2474 this.env.reporter.reportSuiteResults(this);
2475 this.finished = true;
2476 if (typeof(onComplete) == 'function') {
2477 onComplete();
2478 }
2479 };
2480
2481 jasmine.Suite.prototype.beforeEach = function(beforeEachFunction) {
2482 beforeEachFunction.typeName = 'beforeEach';
2483 this.before_.unshift(beforeEachFunction);
2484 };
2485
2486 jasmine.Suite.prototype.afterEach = function(afterEachFunction) {
2487 afterEachFunction.typeName = 'afterEach';
2488 this.after_.unshift(afterEachFunction);
2489 };
2490
2491 jasmine.Suite.prototype.results = function() {
2492 return this.queue.results();
2493 };
2494
2495 jasmine.Suite.prototype.add = function(suiteOrSpec) {
2496 this.children_.push(suiteOrSpec);
2497 if (suiteOrSpec instanceof jasmine.Suite) {
2498 this.suites_.push(suiteOrSpec);
2499 this.env.currentRunner().addSuite(suiteOrSpec);
2500 } else {
2501 this.specs_.push(suiteOrSpec);
2502 }
2503 this.queue.add(suiteOrSpec);
2504 };
2505
2506 jasmine.Suite.prototype.specs = function() {
2507 return this.specs_;
2508 };
2509
2510 jasmine.Suite.prototype.suites = function() {
2511 return this.suites_;
2512 };
2513
2514 jasmine.Suite.prototype.children = function() {
2515 return this.children_;
2516 };
2517
2518 jasmine.Suite.prototype.execute = function(onComplete) {
2519 var self = this;
2520 this.queue.start(function () {
2521 self.finish(onComplete);
2522 });
2523 };
2524 jasmine.WaitsBlock = function(env, timeout, spec) {
2525 this.timeout = timeout;
2526 jasmine.Block.call(this, env, null, spec);
2527 };
2528
2529 jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block);
2530
2531 jasmine.WaitsBlock.prototype.execute = function (onComplete) {
2532 if (jasmine.VERBOSE) {
2533 this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...');
2534 }
2535 this.env.setTimeout(function () {
2536 onComplete();
2537 }, this.timeout);
2538 };
2539 /**
2540 * A block which waits for some condition to become true, with timeout.
2541 *
2542 * @constructor
2543 * @extends jasmine.Block
2544 * @param {jasmine.Env} env The Jasmine environment.
2545 * @param {Number} timeout The maximum time in milliseconds to wait for the condition to become true.
2546 * @param {Function} latchFunction A function which returns true when the desired condition has been met.
2547 * @param {String} message The message to display if the desired condition hasn't been met within the given time period.
2548 * @param {jasmine.Spec} spec The Jasmine spec.
2549 */
2550 jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) {
2551 this.timeout = timeout || env.defaultTimeoutInterval;
2552 this.latchFunction = latchFunction;
2553 this.message = message;
2554 this.totalTimeSpentWaitingForLatch = 0;
2555 jasmine.Block.call(this, env, null, spec);
2556 };
2557 jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block);
2558
2559 jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10;
2560
2561 jasmine.WaitsForBlock.prototype.execute = function(onComplete) {
2562 if (jasmine.VERBOSE) {
2563 this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen'));
2564 }
2565 var latchFunctionResult;
2566 try {
2567 latchFunctionResult = this.latchFunction.apply(this.spec);
2568 } catch (e) {
2569 this.spec.fail(e);
2570 onComplete();
2571 return;
2572 }
2573
2574 if (latchFunctionResult) {
2575 onComplete();
2576 } else if (this.totalTimeSpentWaitingForLatch >= this.timeout) {
2577 var message = 'timed out after ' + this.timeout + ' msec waiting for ' + (this.message || 'something to happen');
2578 this.spec.fail({
2579 name: 'timeout',
2580 message: message
2581 });
2582
2583 this.abort = true;
2584 onComplete();
2585 } else {
2586 this.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT;
2587 var self = this;
2588 this.env.setTimeout(function() {
2589 self.execute(onComplete);
2590 }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT);
2591 }
2592 };
2593
2594 jasmine.version_= {
2595 "major": 1,
2596 "minor": 3,
2597 "build": 1,
2598 "revision": 1354556913
2599 };
+0
-36
src/compiler.js less more
0 PEG.compiler = {
1 /*
2 * Names of passes that will get run during the compilation (in the specified
3 * order).
4 */
5 appliedPassNames: [
6 "reportMissingRules",
7 "reportLeftRecursion",
8 "removeProxyRules",
9 "computeVarNames",
10 "computeParams"
11 ],
12
13 /*
14 * Generates a parser from a specified grammar AST. Throws |PEG.GrammarError|
15 * if the AST contains a semantic error. Note that not all errors are detected
16 * during the generation and some may protrude to the generated parser and
17 * cause its malfunction.
18 */
19 compile: function(ast, options) {
20 var that = this;
21
22 each(this.appliedPassNames, function(passName) {
23 that.passes[passName](ast);
24 });
25
26 var source = this.emitter(ast, options);
27 var result = eval(source);
28 result._source = source;
29
30 return result;
31 }
32 };
33
34 // @include "passes.js"
35 // @include "emitter.js"
+0
-889
src/emitter.js less more
0 /* Emits the generated code for the AST. */
1 PEG.compiler.emitter = function(ast, options) {
2 options = options || {};
3 if (options.cache === undefined) {
4 options.cache = false;
5 }
6 if (options.trackLineAndColumn === undefined) {
7 options.trackLineAndColumn = false;
8 }
9
10 /*
11 * Codie 1.1.0
12 *
13 * https://github.com/dmajda/codie
14 *
15 * Copyright (c) 2011-2012 David Majda
16 * Licensend under the MIT license.
17 */
18 var Codie = (function(undefined) {
19
20 function stringEscape(s) {
21 function hex(ch) { return ch.charCodeAt(0).toString(16).toUpperCase(); }
22
23 /*
24 * ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a
25 * string literal except for the closing quote character, backslash,
26 * carriage return, line separator, paragraph separator, and line feed.
27 * Any character may appear in the form of an escape sequence.
28 *
29 * For portability, we also escape escape all control and non-ASCII
30 * characters. Note that "\0" and "\v" escape sequences are not used
31 * because JSHint does not like the first and IE the second.
32 */
33 return s
34 .replace(/\\/g, '\\\\') // backslash
35 .replace(/"/g, '\\"') // closing double quote
36 .replace(/\x08/g, '\\b') // backspace
37 .replace(/\t/g, '\\t') // horizontal tab
38 .replace(/\n/g, '\\n') // line feed
39 .replace(/\f/g, '\\f') // form feed
40 .replace(/\r/g, '\\r') // carriage return
41 .replace(/[\x00-\x07\x0B\x0E\x0F]/g, function(ch) { return '\\x0' + hex(ch); })
42 .replace(/[\x10-\x1F\x80-\xFF]/g, function(ch) { return '\\x' + hex(ch); })
43 .replace(/[\u0180-\u0FFF]/g, function(ch) { return '\\u0' + hex(ch); })
44 .replace(/[\u1080-\uFFFF]/g, function(ch) { return '\\u' + hex(ch); });
45 }
46
47 function push(s) { return '__p.push(' + s + ');'; }
48
49 function pushRaw(template, length, state) {
50 function unindent(code, level, unindentFirst) {
51 return code.replace(
52 new RegExp('^.{' + level +'}', "gm"),
53 function(str, offset) {
54 if (offset === 0) {
55 return unindentFirst ? '' : str;
56 } else {
57 return "";
58 }
59 }
60 );
61 }
62
63 var escaped = stringEscape(unindent(
64 template.substring(0, length),
65 state.indentLevel(),
66 state.atBOL
67 ));
68
69 return escaped.length > 0 ? push('"' + escaped + '"') : '';
70 }
71
72
73 var Codie = {
74 /* Codie version (uses semantic versioning). */
75 VERSION: "1.1.0",
76
77 /*
78 * Specifies by how many characters do #if/#else and #for unindent their
79 * content in the generated code.
80 */
81 indentStep: 2,
82
83 /* Description of #-commands. Extend to define your own commands. */
84 commands: {
85 "if": {
86 params: /^(.*)$/,
87 compile: function(state, prefix, params) {
88 return ['if(' + params[0] + '){', []];
89 },
90 stackOp: "push"
91 },
92 "else": {
93 params: /^$/,
94 compile: function(state) {
95 var stack = state.commandStack,
96 insideElse = stack[stack.length - 1] === "else",
97 insideIf = stack[stack.length - 1] === "if";
98
99 if (insideElse) { throw new Error("Multiple #elses."); }
100 if (!insideIf) { throw new Error("Using #else outside of #if."); }
101
102 return ['}else{', []];
103 },
104 stackOp: "replace"
105 },
106 "for": {
107 params: /^([a-zA-Z_][a-zA-Z0-9_]*)[ \t]+in[ \t]+(.*)$/,
108 init: function(state) {
109 state.forCurrLevel = 0; // current level of #for loop nesting
110 state.forMaxLevel = 0; // maximum level of #for loop nesting
111 },
112 compile: function(state, prefix, params) {
113 var c = '__c' + state.forCurrLevel, // __c for "collection"
114 l = '__l' + state.forCurrLevel, // __l for "length"
115 i = '__i' + state.forCurrLevel; // __i for "index"
116
117 state.forCurrLevel++;
118 if (state.forMaxLevel < state.forCurrLevel) {
119 state.forMaxLevel = state.forCurrLevel;
120 }
121
122 return [
123 c + '=' + params[1] + ';'
124 + l + '=' + c + '.length;'
125 + 'for(' + i + '=0;' + i + '<' + l + ';' + i + '++){'
126 + params[0] + '=' + c + '[' + i + '];',
127 [params[0], c, l, i]
128 ];
129 },
130 exit: function(state) { state.forCurrLevel--; },
131 stackOp: "push"
132 },
133 "end": {
134 params: /^$/,
135 compile: function(state) {
136 var stack = state.commandStack, exit;
137
138 if (stack.length === 0) { throw new Error("Too many #ends."); }
139
140 exit = Codie.commands[stack[stack.length - 1]].exit;
141 if (exit) { exit(state); }
142
143 return ['}', []];
144 },
145 stackOp: "pop"
146 },
147 "block": {
148 params: /^(.*)$/,
149 compile: function(state, prefix, params) {
150 var x = '__x', // __x for "prefix",
151 n = '__n', // __n for "lines"
152 l = '__l', // __l for "length"
153 i = '__i'; // __i for "index"
154
155 /*
156 * Originally, the generated code used |String.prototype.replace|, but
157 * it is buggy in certain versions of V8 so it was rewritten. See the
158 * tests for details.
159 */
160 return [
161 x + '="' + stringEscape(prefix.substring(state.indentLevel())) + '";'
162 + n + '=(' + params[0] + ').toString().split("\\n");'
163 + l + '=' + n + '.length;'
164 + 'for(' + i + '=0;' + i + '<' + l + ';' + i + '++){'
165 + n + '[' + i +']=' + x + '+' + n + '[' + i + ']+"\\n";'
166 + '}'
167 + push(n + '.join("")'),
168 [x, n, l, i]
169 ];
170 },
171 stackOp: "nop"
172 }
173 },
174
175 /*
176 * Compiles a template into a function. When called, this function will
177 * execute the template in the context of an object passed in a parameter and
178 * return the result.
179 */
180 template: function(template) {
181 var stackOps = {
182 push: function(stack, name) { stack.push(name); },
183 replace: function(stack, name) { stack[stack.length - 1] = name; },
184 pop: function(stack) { stack.pop(); },
185 nop: function() { }
186 };
187
188 function compileExpr(state, expr) {
189 state.atBOL = false;
190 return [push(expr), []];
191 }
192
193 function compileCommand(state, prefix, name, params) {
194 var command, match, result;
195
196 command = Codie.commands[name];
197 if (!command) { throw new Error("Unknown command: #" + name + "."); }
198
199 match = command.params.exec(params);
200 if (match === null) {
201 throw new Error(
202 "Invalid params for command #" + name + ": " + params + "."
203 );
204 }
205
206 result = command.compile(state, prefix, match.slice(1));
207 stackOps[command.stackOp](state.commandStack, name);
208 state.atBOL = true;
209 return result;
210 }
211
212 var state = { // compilation state
213 commandStack: [], // stack of commands as they were nested
214 atBOL: true, // is the next character to process at BOL?
215 indentLevel: function() {
216 return Codie.indentStep * this.commandStack.length;
217 }
218 },
219 code = '', // generated template function code
220 vars = ['__p=[]'], // variables used by generated code
221 name, match, result, i;
222
223 /* Initialize state. */
224 for (name in Codie.commands) {
225 if (Codie.commands[name].init) { Codie.commands[name].init(state); }
226 }
227
228 /* Compile the template. */
229 while ((match = /^([ \t]*)#([a-zA-Z_][a-zA-Z0-9_]*)(?:[ \t]+([^ \t\n][^\n]*))?[ \t]*(?:\n|$)|#\{([^}]*)\}/m.exec(template)) !== null) {
230 code += pushRaw(template, match.index, state);
231 result = match[2] !== undefined && match[2] !== ""
232 ? compileCommand(state, match[1], match[2], match[3] || "") // #-command
233 : compileExpr(state, match[4]); // #{...}
234 code += result[0];
235 vars = vars.concat(result[1]);
236 template = template.substring(match.index + match[0].length);
237 }
238 code += pushRaw(template, template.length, state);
239
240 /* Check the final state. */
241 if (state.commandStack.length > 0) { throw new Error("Missing #end."); }
242
243 /* Sanitize the list of variables used by commands. */
244 vars.sort();
245 for (i = 0; i < vars.length; i++) {
246 if (vars[i] === vars[i - 1]) { vars.splice(i--, 1); }
247 }
248
249 /* Create the resulting function. */
250 return new Function("__v", [
251 '__v=__v||{};',
252 'var ' + vars.join(',') + ';',
253 'with(__v){',
254 code,
255 'return __p.join("").replace(/^\\n+|\\n+$/g,"");};'
256 ].join(''));
257 }
258 };
259
260 return Codie;
261
262 })();
263
264 var templates = (function() {
265 var name,
266 templates = {},
267 sources = {
268 grammar: [
269 '(function(){',
270 ' /*',
271 ' * Generated by PEG.js @VERSION.',
272 ' *',
273 ' * http://pegjs.majda.cz/',
274 ' */',
275 ' ',
276 /* This needs to be in sync with |quote| in utils.js. */
277 ' function quote(s) {',
278 ' /*',
279 ' * ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a',
280 ' * string literal except for the closing quote character, backslash,',
281 ' * carriage return, line separator, paragraph separator, and line feed.',
282 ' * Any character may appear in the form of an escape sequence.',
283 ' *',
284 ' * For portability, we also escape escape all control and non-ASCII',
285 ' * characters. Note that "\\0" and "\\v" escape sequences are not used',
286 ' * because JSHint does not like the first and IE the second.',
287 ' */',
288 ' return \'"\' + s',
289 ' .replace(/\\\\/g, \'\\\\\\\\\') // backslash',
290 ' .replace(/"/g, \'\\\\"\') // closing quote character',
291 ' .replace(/\\x08/g, \'\\\\b\') // backspace',
292 ' .replace(/\\t/g, \'\\\\t\') // horizontal tab',
293 ' .replace(/\\n/g, \'\\\\n\') // line feed',
294 ' .replace(/\\f/g, \'\\\\f\') // form feed',
295 ' .replace(/\\r/g, \'\\\\r\') // carriage return',
296 ' .replace(/[\\x00-\\x07\\x0B\\x0E-\\x1F\\x80-\\uFFFF]/g, escape)',
297 ' + \'"\';',
298 ' }',
299 ' ',
300 ' var result = {',
301 ' /*',
302 ' * Parses the input with a generated parser. If the parsing is successfull,',
303 ' * returns a value explicitly or implicitly specified by the grammar from',
304 ' * which the parser was generated (see |PEG.buildParser|). If the parsing is',
305 ' * unsuccessful, throws |PEG.parser.SyntaxError| describing the error.',
306 ' */',
307 ' parse: function(input, startRule) {',
308 ' var parseFunctions = {',
309 ' #for rule in node.rules',
310 ' #{string(rule.name) + ": parse_" + rule.name + (rule !== node.rules[node.rules.length - 1] ? "," : "")}',
311 ' #end',
312 ' };',
313 ' ',
314 ' if (startRule !== undefined) {',
315 ' if (parseFunctions[startRule] === undefined) {',
316 ' throw new Error("Invalid rule name: " + quote(startRule) + ".");',
317 ' }',
318 ' } else {',
319 ' startRule = #{string(node.startRule)};',
320 ' }',
321 ' ',
322 ' #{posInit("pos")};',
323 ' var reportFailures = 0;', // 0 = report, anything > 0 = do not report
324 ' #{posInit("rightmostFailuresPos")};',
325 ' var rightmostFailuresExpected = [];',
326 ' #if options.cache',
327 ' var cache = {};',
328 ' #end',
329 ' ',
330 /* This needs to be in sync with |padLeft| in utils.js. */
331 ' function padLeft(input, padding, length) {',
332 ' var result = input;',
333 ' ',
334 ' var padLength = length - input.length;',
335 ' for (var i = 0; i < padLength; i++) {',
336 ' result = padding + result;',
337 ' }',
338 ' ',
339 ' return result;',
340 ' }',
341 ' ',
342 /* This needs to be in sync with |escape| in utils.js. */
343 ' function escape(ch) {',
344 ' var charCode = ch.charCodeAt(0);',
345 ' var escapeChar;',
346 ' var length;',
347 ' ',
348 ' if (charCode <= 0xFF) {',
349 ' escapeChar = \'x\';',
350 ' length = 2;',
351 ' } else {',
352 ' escapeChar = \'u\';',
353 ' length = 4;',
354 ' }',
355 ' ',
356 ' return \'\\\\\' + escapeChar + padLeft(charCode.toString(16).toUpperCase(), \'0\', length);',
357 ' }',
358 ' ',
359 ' #if options.trackLineAndColumn',
360 ' function clone(object) {',
361 ' var result = {};',
362 ' for (var key in object) {',
363 ' result[key] = object[key];',
364 ' }',
365 ' return result;',
366 ' }',
367 ' ',
368 ' function advance(pos, n) {',
369 ' var endOffset = pos.offset + n;',
370 ' ',
371 ' for (var offset = pos.offset; offset < endOffset; offset++) {',
372 ' var ch = input.charAt(offset);',
373 ' if (ch === "\\n") {',
374 ' if (!pos.seenCR) { pos.line++; }',
375 ' pos.column = 1;',
376 ' pos.seenCR = false;',
377 ' } else if (ch === "\\r" || ch === "\\u2028" || ch === "\\u2029") {',
378 ' pos.line++;',
379 ' pos.column = 1;',
380 ' pos.seenCR = true;',
381 ' } else {',
382 ' pos.column++;',
383 ' pos.seenCR = false;',
384 ' }',
385 ' }',
386 ' ',
387 ' pos.offset += n;',
388 ' }',
389 ' ',
390 ' #end',
391 ' function matchFailed(failure) {',
392 ' if (#{posOffset("pos")} < #{posOffset("rightmostFailuresPos")}) {',
393 ' return;',
394 ' }',
395 ' ',
396 ' if (#{posOffset("pos")} > #{posOffset("rightmostFailuresPos")}) {',
397 ' rightmostFailuresPos = #{posClone("pos")};',
398 ' rightmostFailuresExpected = [];',
399 ' }',
400 ' ',
401 ' rightmostFailuresExpected.push(failure);',
402 ' }',
403 ' ',
404 ' #for rule in node.rules',
405 ' #block emit(rule)',
406 ' ',
407 ' #end',
408 ' ',
409 ' function cleanupExpected(expected) {',
410 ' expected.sort();',
411 ' ',
412 ' var lastExpected = null;',
413 ' var cleanExpected = [];',
414 ' for (var i = 0; i < expected.length; i++) {',
415 ' if (expected[i] !== lastExpected) {',
416 ' cleanExpected.push(expected[i]);',
417 ' lastExpected = expected[i];',
418 ' }',
419 ' }',
420 ' return cleanExpected;',
421 ' }',
422 ' ',
423 ' #if !options.trackLineAndColumn',
424 ' function computeErrorPosition() {',
425 ' /*',
426 ' * The first idea was to use |String.split| to break the input up to the',
427 ' * error position along newlines and derive the line and column from',
428 ' * there. However IE\'s |split| implementation is so broken that it was',
429 ' * enough to prevent it.',
430 ' */',
431 ' ',
432 ' var line = 1;',
433 ' var column = 1;',
434 ' var seenCR = false;',
435 ' ',
436 ' for (var i = 0; i < Math.max(pos, rightmostFailuresPos); i++) {',
437 ' var ch = input.charAt(i);',
438 ' if (ch === "\\n") {',
439 ' if (!seenCR) { line++; }',
440 ' column = 1;',
441 ' seenCR = false;',
442 ' } else if (ch === "\\r" || ch === "\\u2028" || ch === "\\u2029") {',
443 ' line++;',
444 ' column = 1;',
445 ' seenCR = true;',
446 ' } else {',
447 ' column++;',
448 ' seenCR = false;',
449 ' }',
450 ' }',
451 ' ',
452 ' return { line: line, column: column };',
453 ' }',
454 ' #end',
455 ' ',
456 ' #if node.initializer',
457 ' #block emit(node.initializer)',
458 ' #end',
459 ' ',
460 ' var result = parseFunctions[startRule]();',
461 ' ',
462 ' /*',
463 ' * The parser is now in one of the following three states:',
464 ' *',
465 ' * 1. The parser successfully parsed the whole input.',
466 ' *',
467 ' * - |result !== null|',
468 ' * - |#{posOffset("pos")} === input.length|',
469 ' * - |rightmostFailuresExpected| may or may not contain something',
470 ' *',
471 ' * 2. The parser successfully parsed only a part of the input.',
472 ' *',
473 ' * - |result !== null|',
474 ' * - |#{posOffset("pos")} < input.length|',
475 ' * - |rightmostFailuresExpected| may or may not contain something',
476 ' *',
477 ' * 3. The parser did not successfully parse any part of the input.',
478 ' *',
479 ' * - |result === null|',
480 ' * - |#{posOffset("pos")} === 0|',
481 ' * - |rightmostFailuresExpected| contains at least one failure',
482 ' *',
483 ' * All code following this comment (including called functions) must',
484 ' * handle these states.',
485 ' */',
486 ' if (result === null || #{posOffset("pos")} !== input.length) {',
487 ' var offset = Math.max(#{posOffset("pos")}, #{posOffset("rightmostFailuresPos")});',
488 ' var found = offset < input.length ? input.charAt(offset) : null;',
489 ' #if options.trackLineAndColumn',
490 ' var errorPosition = #{posOffset("pos")} > #{posOffset("rightmostFailuresPos")} ? pos : rightmostFailuresPos;',
491 ' #else',
492 ' var errorPosition = computeErrorPosition();',
493 ' #end',
494 ' ',
495 ' throw new this.SyntaxError(',
496 ' cleanupExpected(rightmostFailuresExpected),',
497 ' found,',
498 ' offset,',
499 ' errorPosition.line,',
500 ' errorPosition.column',
501 ' );',
502 ' }',
503 ' ',
504 ' return result;',
505 ' },',
506 ' ',
507 ' /* Returns the parser source code. */',
508 ' toSource: function() { return this._source; }',
509 ' };',
510 ' ',
511 ' /* Thrown when a parser encounters a syntax error. */',
512 ' ',
513 ' result.SyntaxError = function(expected, found, offset, line, column) {',
514 ' function buildMessage(expected, found) {',
515 ' var expectedHumanized, foundHumanized;',
516 ' ',
517 ' switch (expected.length) {',
518 ' case 0:',
519 ' expectedHumanized = "end of input";',
520 ' break;',
521 ' case 1:',
522 ' expectedHumanized = expected[0];',
523 ' break;',
524 ' default:',
525 ' expectedHumanized = expected.slice(0, expected.length - 1).join(", ")',
526 ' + " or "',
527 ' + expected[expected.length - 1];',
528 ' }',
529 ' ',
530 ' foundHumanized = found ? quote(found) : "end of input";',
531 ' ',
532 ' return "Expected " + expectedHumanized + " but " + foundHumanized + " found.";',
533 ' }',
534 ' ',
535 ' this.name = "SyntaxError";',
536 ' this.expected = expected;',
537 ' this.found = found;',
538 ' this.message = buildMessage(expected, found);',
539 ' this.offset = offset;',
540 ' this.line = line;',
541 ' this.column = column;',
542 ' };',
543 ' ',
544 ' result.SyntaxError.prototype = Error.prototype;',
545 ' ',
546 ' return result;',
547 '})()'
548 ],
549 rule: [
550 'function parse_#{node.name}() {',
551 ' #if options.cache',
552 ' var cacheKey = "#{node.name}@" + #{posOffset("pos")};',
553 ' var cachedResult = cache[cacheKey];',
554 ' if (cachedResult) {',
555 ' pos = #{posClone("cachedResult.nextPos")};',
556 ' return cachedResult.result;',
557 ' }',
558 ' ',
559 ' #end',
560 ' #if node.resultVars.length > 0',
561 ' var #{node.resultVars.join(", ")};',
562 ' #end',
563 ' #if node.posVars.length > 0',
564 ' var #{node.posVars.join(", ")};',
565 ' #end',
566 ' ',
567 ' #if node.displayName !== null',
568 ' reportFailures++;',
569 ' #end',
570 ' #block emit(node.expression)',
571 ' #if node.displayName !== null',
572 ' reportFailures--;',
573 ' if (reportFailures === 0 && #{node.resultVar} === null) {',
574 ' matchFailed(#{string(node.displayName)});',
575 ' }',
576 ' #end',
577 ' #if options.cache',
578 ' ',
579 ' cache[cacheKey] = {',
580 ' nextPos: #{posClone("pos")},',
581 ' result: #{node.resultVar}',
582 ' };',
583 ' #end',
584 ' return #{node.resultVar};',
585 '}'
586 ],
587 choice: [
588 '#block emit(alternative)',
589 '#block nextAlternativesCode'
590 ],
591 "choice.next": [
592 'if (#{node.resultVar} === null) {',
593 ' #block code',
594 '}'
595 ],
596 sequence: [
597 '#{posSave(node)};',
598 '#block code'
599 ],
600 "sequence.iteration": [
601 '#block emit(element)',
602 'if (#{element.resultVar} !== null) {',
603 ' #block code',
604 '} else {',
605 ' #{node.resultVar} = null;',
606 ' #{posRestore(node)};',
607 '}'
608 ],
609 "sequence.inner": [
610 '#{node.resultVar} = [#{pluck(node.elements, "resultVar").join(", ")}];'
611 ],
612 simple_and: [
613 '#{posSave(node)};',
614 'reportFailures++;',
615 '#block emit(node.expression)',
616 'reportFailures--;',
617 'if (#{node.resultVar} !== null) {',
618 ' #{node.resultVar} = "";',
619 ' #{posRestore(node)};',
620 '} else {',
621 ' #{node.resultVar} = null;',
622 '}'
623 ],
624 simple_not: [
625 '#{posSave(node)};',
626 'reportFailures++;',
627 '#block emit(node.expression)',
628 'reportFailures--;',
629 'if (#{node.resultVar} === null) {',
630 ' #{node.resultVar} = "";',
631 '} else {',
632 ' #{node.resultVar} = null;',
633 ' #{posRestore(node)};',
634 '}'
635 ],
636 semantic_and: [
637 '#{node.resultVar} = (function(#{(options.trackLineAndColumn ? ["offset", "line", "column"] : ["offset"]).concat(keys(node.params)).join(", ")}) {#{node.code}})(#{(options.trackLineAndColumn ? ["pos.offset", "pos.line", "pos.column"] : ["pos"]).concat(values(node.params)).join(", ")}) ? "" : null;'
638 ],
639 semantic_not: [
640 '#{node.resultVar} = (function(#{(options.trackLineAndColumn ? ["offset", "line", "column"] : ["offset"]).concat(keys(node.params)).join(", ")}) {#{node.code}})(#{(options.trackLineAndColumn ? ["pos.offset", "pos.line", "pos.column"] : ["pos"]).concat(values(node.params)).join(", ")}) ? null : "";'
641 ],
642 optional: [
643 '#block emit(node.expression)',
644 '#{node.resultVar} = #{node.resultVar} !== null ? #{node.resultVar} : "";'
645 ],
646 zero_or_more: [
647 '#{node.resultVar} = [];',
648 '#block emit(node.expression)',
649 'while (#{node.expression.resultVar} !== null) {',
650 ' #{node.resultVar}.push(#{node.expression.resultVar});',
651 ' #block emit(node.expression)',
652 '}'
653 ],
654 one_or_more: [
655 '#block emit(node.expression)',
656 'if (#{node.expression.resultVar} !== null) {',
657 ' #{node.resultVar} = [];',
658 ' while (#{node.expression.resultVar} !== null) {',
659 ' #{node.resultVar}.push(#{node.expression.resultVar});',
660 ' #block emit(node.expression)',
661 ' }',
662 '} else {',
663 ' #{node.resultVar} = null;',
664 '}'
665 ],
666 action: [
667 '#{posSave(node)};',
668 '#block emit(node.expression)',
669 'if (#{node.resultVar} !== null) {',
670 ' #{node.resultVar} = (function(#{(options.trackLineAndColumn ? ["offset", "line", "column"] : ["offset"]).concat(keys(node.params)).join(", ")}) {#{node.code}})(#{(options.trackLineAndColumn ? [node.posVar + ".offset", node.posVar + ".line", node.posVar + ".column"] : [node.posVar]).concat(values(node.params)).join(", ")});',
671 '}',
672 'if (#{node.resultVar} === null) {',
673 ' #{posRestore(node)};',
674 '}'
675 ],
676 rule_ref: [
677 '#{node.resultVar} = parse_#{node.name}();'
678 ],
679 literal: [
680 '#if node.value.length === 0',
681 ' #{node.resultVar} = "";',
682 '#else',
683 ' #if !node.ignoreCase',
684 ' #if node.value.length === 1',
685 ' if (input.charCodeAt(#{posOffset("pos")}) === #{node.value.charCodeAt(0)}) {',
686 ' #else',
687 ' if (input.substr(#{posOffset("pos")}, #{node.value.length}) === #{string(node.value)}) {',
688 ' #end',
689 ' #else',
690 /*
691 * One-char literals are not optimized when case-insensitive
692 * matching is enabled. This is because there is no simple way to
693 * lowercase a character code that works for character outside ASCII
694 * letters. Moreover, |toLowerCase| can change string length,
695 * meaning the result of lowercasing a character can be more
696 * characters.
697 */
698 ' if (input.substr(#{posOffset("pos")}, #{node.value.length}).toLowerCase() === #{string(node.value.toLowerCase())}) {',
699 ' #end',
700 ' #if !node.ignoreCase',
701 ' #{node.resultVar} = #{string(node.value)};',
702 ' #else',
703 ' #{node.resultVar} = input.substr(#{posOffset("pos")}, #{node.value.length});',
704 ' #end',
705 ' #{posAdvance(node.value.length)};',
706 ' } else {',
707 ' #{node.resultVar} = null;',
708 ' if (reportFailures === 0) {',
709 ' matchFailed(#{string(string(node.value))});',
710 ' }',
711 ' }',
712 '#end'
713 ],
714 any: [
715 'if (input.length > #{posOffset("pos")}) {',
716 ' #{node.resultVar} = input.charAt(#{posOffset("pos")});',
717 ' #{posAdvance(1)};',
718 '} else {',
719 ' #{node.resultVar} = null;',
720 ' if (reportFailures === 0) {',
721 ' matchFailed("any character");',
722 ' }',
723 '}'
724 ],
725 "class": [
726 'if (#{regexp}.test(input.charAt(#{posOffset("pos")}))) {',
727 ' #{node.resultVar} = input.charAt(#{posOffset("pos")});',
728 ' #{posAdvance(1)};',
729 '} else {',
730 ' #{node.resultVar} = null;',
731 ' if (reportFailures === 0) {',
732 ' matchFailed(#{string(node.rawText)});',
733 ' }',
734 '}'
735 ]
736 };
737
738 for (name in sources) {
739 templates[name] = Codie.template(sources[name].join('\n'));
740 }
741
742 return templates;
743 })();
744
745 function fill(name, vars) {
746 vars.string = quote;
747 vars.pluck = pluck;
748 vars.keys = keys;
749 vars.values = values;
750 vars.emit = emit;
751 vars.options = options;
752
753 /* Position-handling macros */
754 if (options.trackLineAndColumn) {
755 vars.posInit = function(name) {
756 return "var "
757 + name
758 + " = "
759 + "{ offset: 0, line: 1, column: 1, seenCR: false }";
760 };
761 vars.posClone = function(name) { return "clone(" + name + ")"; };
762 vars.posOffset = function(name) { return name + ".offset"; };
763
764 vars.posAdvance = function(n) { return "advance(pos, " + n + ")"; };
765 } else {
766 vars.posInit = function(name) { return "var " + name + " = 0"; };
767 vars.posClone = function(name) { return name; };
768 vars.posOffset = function(name) { return name; };
769
770 vars.posAdvance = function(n) {
771 return n === 1 ? "pos++" : "pos += " + n;
772 };
773 }
774 vars.posSave = function(node) {
775 return node.posVar + " = " + vars.posClone("pos");
776 };
777 vars.posRestore = function(node) {
778 return "pos" + " = " + vars.posClone(node.posVar);
779 };
780
781 return templates[name](vars);
782 }
783
784 function emitSimple(name) {
785 return function(node) { return fill(name, { node: node }); };
786 }
787
788 var emit = buildNodeVisitor({
789 grammar: emitSimple("grammar"),
790
791 initializer: function(node) { return node.code; },
792
793 rule: emitSimple("rule"),
794
795 /*
796 * The contract for all code fragments generated by the following functions
797 * is as follows.
798 *
799 * The code fragment tries to match a part of the input starting with the
800 * position indicated in |pos|. That position may point past the end of the
801 * input.
802 *
803 * * If the code fragment matches the input, it advances |pos| to point to
804 * the first chracter following the matched part of the input and sets
805 * variable with a name stored in |node.resultVar| to an appropriate
806 * value. This value is always non-|null|.
807 *
808 * * If the code fragment does not match the input, it returns with |pos|
809 * set to the original value and it sets a variable with a name stored in
810 * |node.resultVar| to |null|.
811 *
812 * The code can use variables with names stored in |resultVar| and |posVar|
813 * properties of the current node's subnodes. It can't use any other
814 * variables.
815 */
816
817 choice: function(node) {
818 var code, nextAlternativesCode;
819
820 for (var i = node.alternatives.length - 1; i >= 0; i--) {
821 nextAlternativesCode = i !== node.alternatives.length - 1
822 ? fill("choice.next", { node: node, code: code })
823 : '';
824 code = fill("choice", {
825 alternative: node.alternatives[i],
826 nextAlternativesCode: nextAlternativesCode
827 });
828 }
829
830 return code;
831 },
832
833 sequence: function(node) {
834 var code = fill("sequence.inner", { node: node });
835
836 for (var i = node.elements.length - 1; i >= 0; i--) {
837 code = fill("sequence.iteration", {
838 node: node,
839 element: node.elements[i],
840 code: code
841 });
842 }
843
844 return fill("sequence", { node: node, code: code });
845 },
846
847 labeled: function(node) { return emit(node.expression); },
848
849 simple_and: emitSimple("simple_and"),
850 simple_not: emitSimple("simple_not"),
851 semantic_and: emitSimple("semantic_and"),
852 semantic_not: emitSimple("semantic_not"),
853 optional: emitSimple("optional"),
854 zero_or_more: emitSimple("zero_or_more"),
855 one_or_more: emitSimple("one_or_more"),
856 action: emitSimple("action"),
857 rule_ref: emitSimple("rule_ref"),
858 literal: emitSimple("literal"),
859 any: emitSimple("any"),
860
861 "class": function(node) {
862 var regexp;
863
864 if (node.parts.length > 0) {
865 regexp = '/^['
866 + (node.inverted ? '^' : '')
867 + map(node.parts, function(part) {
868 return part instanceof Array
869 ? quoteForRegexpClass(part[0])
870 + '-'
871 + quoteForRegexpClass(part[1])
872 : quoteForRegexpClass(part);
873 }).join('')
874 + ']/' + (node.ignoreCase ? 'i' : '');
875 } else {
876 /*
877 * Stupid IE considers regexps /[]/ and /[^]/ syntactically invalid, so
878 * we translate them into euqivalents it can handle.
879 */
880 regexp = node.inverted ? '/^[\\S\\s]/' : '/^(?!)/';
881 }
882
883 return fill("class", { node: node, regexp: regexp });
884 }
885 });
886
887 return emit(ast);
888 };
+0
-2963
src/parser.js less more
0 PEG.parser = (function(){
1 /*
2 * Generated by PEG.js 0.7.0.
3 *
4 * http://pegjs.majda.cz/
5 */
6
7 function quote(s) {
8 /*
9 * ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a
10 * string literal except for the closing quote character, backslash,
11 * carriage return, line separator, paragraph separator, and line feed.
12 * Any character may appear in the form of an escape sequence.
13 *
14 * For portability, we also escape escape all control and non-ASCII
15 * characters. Note that "\0" and "\v" escape sequences are not used
16 * because JSHint does not like the first and IE the second.
17 */
18 return '"' + s
19 .replace(/\\/g, '\\\\') // backslash
20 .replace(/"/g, '\\"') // closing quote character
21 .replace(/\x08/g, '\\b') // backspace
22 .replace(/\t/g, '\\t') // horizontal tab
23 .replace(/\n/g, '\\n') // line feed
24 .replace(/\f/g, '\\f') // form feed
25 .replace(/\r/g, '\\r') // carriage return
26 .replace(/[\x00-\x07\x0B\x0E-\x1F\x80-\uFFFF]/g, escape)
27 + '"';
28 }
29
30 var result = {
31 /*
32 * Parses the input with a generated parser. If the parsing is successfull,
33 * returns a value explicitly or implicitly specified by the grammar from
34 * which the parser was generated (see |PEG.buildParser|). If the parsing is
35 * unsuccessful, throws |PEG.parser.SyntaxError| describing the error.
36 */
37 parse: function(input, startRule) {
38 var parseFunctions = {
39 "grammar": parse_grammar,
40 "initializer": parse_initializer,
41 "rule": parse_rule,
42 "choice": parse_choice,
43 "sequence": parse_sequence,
44 "labeled": parse_labeled,
45 "prefixed": parse_prefixed,
46 "suffixed": parse_suffixed,
47 "primary": parse_primary,
48 "action": parse_action,
49 "braced": parse_braced,
50 "nonBraceCharacters": parse_nonBraceCharacters,
51 "nonBraceCharacter": parse_nonBraceCharacter,
52 "equals": parse_equals,
53 "colon": parse_colon,
54 "semicolon": parse_semicolon,
55 "slash": parse_slash,
56 "and": parse_and,
57 "not": parse_not,
58 "question": parse_question,
59 "star": parse_star,
60 "plus": parse_plus,
61 "lparen": parse_lparen,
62 "rparen": parse_rparen,
63 "dot": parse_dot,
64 "identifier": parse_identifier,
65 "literal": parse_literal,
66 "string": parse_string,
67 "doubleQuotedString": parse_doubleQuotedString,
68 "doubleQuotedCharacter": parse_doubleQuotedCharacter,
69 "simpleDoubleQuotedCharacter": parse_simpleDoubleQuotedCharacter,
70 "singleQuotedString": parse_singleQuotedString,
71 "singleQuotedCharacter": parse_singleQuotedCharacter,
72 "simpleSingleQuotedCharacter": parse_simpleSingleQuotedCharacter,
73 "class": parse_class,
74 "classCharacterRange": parse_classCharacterRange,
75 "classCharacter": parse_classCharacter,
76 "bracketDelimitedCharacter": parse_bracketDelimitedCharacter,
77 "simpleBracketDelimitedCharacter": parse_simpleBracketDelimitedCharacter,
78 "simpleEscapeSequence": parse_simpleEscapeSequence,
79 "zeroEscapeSequence": parse_zeroEscapeSequence,
80 "hexEscapeSequence": parse_hexEscapeSequence,
81 "unicodeEscapeSequence": parse_unicodeEscapeSequence,
82 "eolEscapeSequence": parse_eolEscapeSequence,
83 "digit": parse_digit,
84 "hexDigit": parse_hexDigit,
85 "letter": parse_letter,
86 "lowerCaseLetter": parse_lowerCaseLetter,
87 "upperCaseLetter": parse_upperCaseLetter,
88 "__": parse___,
89 "comment": parse_comment,
90 "singleLineComment": parse_singleLineComment,
91 "multiLineComment": parse_multiLineComment,
92 "eol": parse_eol,
93 "eolChar": parse_eolChar,
94 "whitespace": parse_whitespace
95 };
96
97 if (startRule !== undefined) {
98 if (parseFunctions[startRule] === undefined) {
99 throw new Error("Invalid rule name: " + quote(startRule) + ".");
100 }
101 } else {
102 startRule = "grammar";
103 }
104
105 var pos = 0;
106 var reportFailures = 0;
107 var rightmostFailuresPos = 0;
108 var rightmostFailuresExpected = [];
109
110 function padLeft(input, padding, length) {
111 var result = input;
112
113 var padLength = length - input.length;
114 for (var i = 0; i < padLength; i++) {
115 result = padding + result;
116 }
117
118 return result;
119 }
120
121 function escape(ch) {
122 var charCode = ch.charCodeAt(0);
123 var escapeChar;
124 var length;
125
126 if (charCode <= 0xFF) {
127 escapeChar = 'x';
128 length = 2;
129 } else {
130 escapeChar = 'u';
131 length = 4;
132 }
133
134 return '\\' + escapeChar + padLeft(charCode.toString(16).toUpperCase(), '0', length);
135 }
136
137 function matchFailed(failure) {
138 if (pos < rightmostFailuresPos) {
139 return;
140 }
141
142 if (pos > rightmostFailuresPos) {
143 rightmostFailuresPos = pos;
144 rightmostFailuresExpected = [];
145 }
146
147 rightmostFailuresExpected.push(failure);
148 }
149
150 function parse_grammar() {
151 var result0, result1, result2, result3;
152 var pos0, pos1;
153
154 pos0 = pos;
155 pos1 = pos;
156 result0 = parse___();
157 if (result0 !== null) {
158 result1 = parse_initializer();
159 result1 = result1 !== null ? result1 : "";
160 if (result1 !== null) {
161 result3 = parse_rule();
162 if (result3 !== null) {
163 result2 = [];
164 while (result3 !== null) {
165 result2.push(result3);
166 result3 = parse_rule();
167 }
168 } else {
169 result2 = null;
170 }
171 if (result2 !== null) {
172 result0 = [result0, result1, result2];
173 } else {
174 result0 = null;
175 pos = pos1;
176 }
177 } else {
178 result0 = null;
179 pos = pos1;
180 }
181 } else {
182 result0 = null;
183 pos = pos1;
184 }
185 if (result0 !== null) {
186 result0 = (function(offset, initializer, rules) {
187 return {
188 type: "grammar",
189 initializer: initializer !== "" ? initializer : null,
190 rules: rules,
191 startRule: rules[0].name
192 };
193 })(pos0, result0[1], result0[2]);
194 }
195 if (result0 === null) {
196 pos = pos0;
197 }
198 return result0;
199 }
200
201 function parse_initializer() {
202 var result0, result1;
203 var pos0, pos1;
204
205 pos0 = pos;
206 pos1 = pos;
207 result0 = parse_action();
208 if (result0 !== null) {
209 result1 = parse_semicolon();
210 result1 = result1 !== null ? result1 : "";
211 if (result1 !== null) {
212 result0 = [result0, result1];
213 } else {
214 result0 = null;
215 pos = pos1;
216 }
217 } else {
218 result0 = null;
219 pos = pos1;
220 }
221 if (result0 !== null) {
222 result0 = (function(offset, code) {
223 return {
224 type: "initializer",
225 code: code
226 };
227 })(pos0, result0[0]);
228 }
229 if (result0 === null) {
230 pos = pos0;
231 }
232 return result0;
233 }
234
235 function parse_rule() {
236 var result0, result1, result2, result3, result4;
237 var pos0, pos1;
238
239 pos0 = pos;
240 pos1 = pos;
241 result0 = parse_identifier();
242 if (result0 !== null) {
243 result1 = parse_string();
244 result1 = result1 !== null ? result1 : "";
245 if (result1 !== null) {
246 result2 = parse_equals();
247 if (result2 !== null) {
248 result3 = parse_choice();
249 if (result3 !== null) {
250 result4 = parse_semicolon();
251 result4 = result4 !== null ? result4 : "";
252 if (result4 !== null) {
253 result0 = [result0, result1, result2, result3, result4];
254 } else {
255 result0 = null;
256 pos = pos1;
257 }
258 } else {
259 result0 = null;
260 pos = pos1;
261 }
262 } else {
263 result0 = null;
264 pos = pos1;
265 }
266 } else {
267 result0 = null;
268 pos = pos1;
269 }
270 } else {
271 result0 = null;
272 pos = pos1;
273 }
274 if (result0 !== null) {
275 result0 = (function(offset, name, displayName, expression) {
276 return {
277 type: "rule",
278 name: name,
279 displayName: displayName !== "" ? displayName : null,
280 expression: expression
281 };
282 })(pos0, result0[0], result0[1], result0[3]);
283 }
284 if (result0 === null) {
285 pos = pos0;
286 }
287 return result0;
288 }
289
290 function parse_choice() {
291 var result0, result1, result2, result3;
292 var pos0, pos1, pos2;
293
294 pos0 = pos;
295 pos1 = pos;
296 result0 = parse_sequence();
297 if (result0 !== null) {
298 result1 = [];
299 pos2 = pos;
300 result2 = parse_slash();
301 if (result2 !== null) {
302 result3 = parse_sequence();
303 if (result3 !== null) {
304 result2 = [result2, result3];
305 } else {
306 result2 = null;
307 pos = pos2;
308 }
309 } else {
310 result2 = null;
311 pos = pos2;
312 }
313 while (result2 !== null) {
314 result1.push(result2);
315 pos2 = pos;
316 result2 = parse_slash();
317 if (result2 !== null) {
318 result3 = parse_sequence();
319 if (result3 !== null) {
320 result2 = [result2, result3];
321 } else {
322 result2 = null;
323 pos = pos2;
324 }
325 } else {
326 result2 = null;
327 pos = pos2;
328 }
329 }
330 if (result1 !== null) {
331 result0 = [result0, result1];
332 } else {
333 result0 = null;
334 pos = pos1;
335 }
336 } else {
337 result0 = null;
338 pos = pos1;
339 }
340 if (result0 !== null) {
341 result0 = (function(offset, head, tail) {
342 if (tail.length > 0) {
343 var alternatives = [head].concat(map(
344 tail,
345 function(element) { return element[1]; }
346 ));
347 return {
348 type: "choice",
349 alternatives: alternatives
350 };
351 } else {
352 return head;
353 }
354 })(pos0, result0[0], result0[1]);
355 }
356 if (result0 === null) {
357 pos = pos0;
358 }
359 return result0;
360 }
361
362 function parse_sequence() {
363 var result0, result1;
364 var pos0, pos1;
365
366 pos0 = pos;
367 pos1 = pos;
368 result0 = [];
369 result1 = parse_labeled();
370 while (result1 !== null) {
371 result0.push(result1);
372 result1 = parse_labeled();
373 }
374 if (result0 !== null) {
375 result1 = parse_action();
376 if (result1 !== null) {
377 result0 = [result0, result1];
378 } else {
379 result0 = null;
380 pos = pos1;
381 }
382 } else {
383 result0 = null;
384 pos = pos1;
385 }
386 if (result0 !== null) {
387 result0 = (function(offset, elements, code) {
388 var expression = elements.length !== 1
389 ? {
390 type: "sequence",
391 elements: elements
392 }
393 : elements[0];
394 return {
395 type: "action",
396 expression: expression,
397 code: code
398 };
399 })(pos0, result0[0], result0[1]);
400 }
401 if (result0 === null) {
402 pos = pos0;
403 }
404 if (result0 === null) {
405 pos0 = pos;
406 result0 = [];
407 result1 = parse_labeled();
408 while (result1 !== null) {
409 result0.push(result1);
410 result1 = parse_labeled();
411 }
412 if (result0 !== null) {
413 result0 = (function(offset, elements) {
414 return elements.length !== 1
415 ? {
416 type: "sequence",
417 elements: elements
418 }
419 : elements[0];
420 })(pos0, result0);
421 }
422 if (result0 === null) {
423 pos = pos0;
424 }
425 }
426 return result0;
427 }
428
429 function parse_labeled() {
430 var result0, result1, result2;
431 var pos0, pos1;
432
433 pos0 = pos;
434 pos1 = pos;
435 result0 = parse_identifier();
436 if (result0 !== null) {
437 result1 = parse_colon();
438 if (result1 !== null) {
439 result2 = parse_prefixed();
440 if (result2 !== null) {
441 result0 = [result0, result1, result2];
442 } else {
443 result0 = null;
444 pos = pos1;
445 }
446 } else {
447 result0 = null;
448 pos = pos1;
449 }
450 } else {
451 result0 = null;
452 pos = pos1;
453 }
454 if (result0 !== null) {
455 result0 = (function(offset, label, expression) {
456 return {
457 type: "labeled",
458 label: label,
459 expression: expression
460 };
461 })(pos0, result0[0], result0[2]);
462 }
463 if (result0 === null) {
464 pos = pos0;
465 }
466 if (result0 === null) {
467 result0 = parse_prefixed();
468 }
469 return result0;
470 }
471
472 function parse_prefixed() {
473 var result0, result1;
474 var pos0, pos1;
475
476 pos0 = pos;
477 pos1 = pos;
478 result0 = parse_and();
479 if (result0 !== null) {
480 result1 = parse_action();
481 if (result1 !== null) {
482 result0 = [result0, result1];
483 } else {
484 result0 = null;
485 pos = pos1;
486 }
487 } else {
488 result0 = null;
489 pos = pos1;
490 }
491 if (result0 !== null) {
492 result0 = (function(offset, code) {
493 return {
494 type: "semantic_and",
495 code: code
496 };
497 })(pos0, result0[1]);
498 }
499 if (result0 === null) {
500 pos = pos0;
501 }
502 if (result0 === null) {
503 pos0 = pos;
504 pos1 = pos;
505 result0 = parse_and();
506 if (result0 !== null) {
507 result1 = parse_suffixed();
508 if (result1 !== null) {
509 result0 = [result0, result1];
510 } else {
511 result0 = null;
512 pos = pos1;
513 }
514 } else {
515 result0 = null;
516 pos = pos1;
517 }
518 if (result0 !== null) {
519 result0 = (function(offset, expression) {
520 return {
521 type: "simple_and",
522 expression: expression
523 };
524 })(pos0, result0[1]);
525 }
526 if (result0 === null) {
527 pos = pos0;
528 }
529 if (result0 === null) {
530 pos0 = pos;
531 pos1 = pos;
532 result0 = parse_not();
533 if (result0 !== null) {
534 result1 = parse_action();
535 if (result1 !== null) {
536 result0 = [result0, result1];
537 } else {
538 result0 = null;
539 pos = pos1;
540 }
541 } else {
542 result0 = null;
543 pos = pos1;
544 }
545 if (result0 !== null) {
546 result0 = (function(offset, code) {
547 return {
548 type: "semantic_not",
549 code: code
550 };
551 })(pos0, result0[1]);
552 }
553 if (result0 === null) {
554 pos = pos0;
555 }
556 if (result0 === null) {
557 pos0 = pos;
558 pos1 = pos;
559 result0 = parse_not();
560 if (result0 !== null) {
561 result1 = parse_suffixed();
562 if (result1 !== null) {
563 result0 = [result0, result1];
564 } else {
565 result0 = null;
566 pos = pos1;
567 }
568 } else {
569 result0 = null;
570 pos = pos1;
571 }
572 if (result0 !== null) {
573 result0 = (function(offset, expression) {
574 return {
575 type: "simple_not",
576 expression: expression
577 };
578 })(pos0, result0[1]);
579 }
580 if (result0 === null) {
581 pos = pos0;
582 }
583 if (result0 === null) {
584 result0 = parse_suffixed();
585 }
586 }
587 }
588 }
589 return result0;
590 }
591
592 function parse_suffixed() {
593 var result0, result1;
594 var pos0, pos1;
595
596 pos0 = pos;
597 pos1 = pos;
598 result0 = parse_primary();
599 if (result0 !== null) {
600 result1 = parse_question();
601 if (result1 !== null) {
602 result0 = [result0, result1];
603 } else {
604 result0 = null;
605 pos = pos1;
606 }
607 } else {
608 result0 = null;
609 pos = pos1;
610 }
611 if (result0 !== null) {
612 result0 = (function(offset, expression) {
613 return {
614 type: "optional",
615 expression: expression
616 };
617 })(pos0, result0[0]);
618 }
619 if (result0 === null) {
620 pos = pos0;
621 }
622 if (result0 === null) {
623 pos0 = pos;
624 pos1 = pos;
625 result0 = parse_primary();
626 if (result0 !== null) {
627 result1 = parse_star();
628 if (result1 !== null) {
629 result0 = [result0, result1];
630 } else {
631 result0 = null;
632 pos = pos1;
633 }
634 } else {
635 result0 = null;
636 pos = pos1;
637 }
638 if (result0 !== null) {
639 result0 = (function(offset, expression) {
640 return {
641 type: "zero_or_more",
642 expression: expression
643 };
644 })(pos0, result0[0]);
645 }
646 if (result0 === null) {
647 pos = pos0;
648 }
649 if (result0 === null) {
650 pos0 = pos;
651 pos1 = pos;
652 result0 = parse_primary();
653 if (result0 !== null) {
654 result1 = parse_plus();
655 if (result1 !== null) {
656 result0 = [result0, result1];
657 } else {
658 result0 = null;
659 pos = pos1;
660 }
661 } else {
662 result0 = null;
663 pos = pos1;
664 }
665 if (result0 !== null) {
666 result0 = (function(offset, expression) {
667 return {
668 type: "one_or_more",
669 expression: expression
670 };
671 })(pos0, result0[0]);
672 }
673 if (result0 === null) {
674 pos = pos0;
675 }
676 if (result0 === null) {
677 result0 = parse_primary();
678 }
679 }
680 }
681 return result0;
682 }
683
684 function parse_primary() {
685 var result0, result1, result2;
686 var pos0, pos1, pos2, pos3;
687
688 pos0 = pos;
689 pos1 = pos;
690 result0 = parse_identifier();
691 if (result0 !== null) {
692 pos2 = pos;
693 reportFailures++;
694 pos3 = pos;
695 result1 = parse_string();
696 result1 = result1 !== null ? result1 : "";
697 if (result1 !== null) {
698 result2 = parse_equals();
699 if (result2 !== null) {
700 result1 = [result1, result2];
701 } else {
702 result1 = null;
703 pos = pos3;
704 }
705 } else {
706 result1 = null;
707 pos = pos3;
708 }
709 reportFailures--;
710 if (result1 === null) {
711 result1 = "";
712 } else {
713 result1 = null;
714 pos = pos2;
715 }
716 if (result1 !== null) {
717 result0 = [result0, result1];
718 } else {
719 result0 = null;
720 pos = pos1;
721 }
722 } else {
723 result0 = null;
724 pos = pos1;
725 }
726 if (result0 !== null) {
727 result0 = (function(offset, name) {
728 return {
729 type: "rule_ref",
730 name: name
731 };
732 })(pos0, result0[0]);
733 }
734 if (result0 === null) {
735 pos = pos0;
736 }
737 if (result0 === null) {
738 result0 = parse_literal();
739 if (result0 === null) {
740 pos0 = pos;
741 result0 = parse_dot();
742 if (result0 !== null) {
743 result0 = (function(offset) { return { type: "any" }; })(pos0);
744 }
745 if (result0 === null) {
746 pos = pos0;
747 }
748 if (result0 === null) {
749 result0 = parse_class();
750 if (result0 === null) {
751 pos0 = pos;
752 pos1 = pos;
753 result0 = parse_lparen();
754 if (result0 !== null) {
755 result1 = parse_choice();
756 if (result1 !== null) {
757 result2 = parse_rparen();
758 if (result2 !== null) {
759 result0 = [result0, result1, result2];
760 } else {
761 result0 = null;
762 pos = pos1;
763 }
764 } else {
765 result0 = null;
766 pos = pos1;
767 }
768 } else {
769 result0 = null;
770 pos = pos1;
771 }
772 if (result0 !== null) {
773 result0 = (function(offset, expression) { return expression; })(pos0, result0[1]);
774 }
775 if (result0 === null) {
776 pos = pos0;
777 }
778 }
779 }
780 }
781 }
782 return result0;
783 }
784
785 function parse_action() {
786 var result0, result1;
787 var pos0, pos1;
788
789 reportFailures++;
790 pos0 = pos;
791 pos1 = pos;
792 result0 = parse_braced();
793 if (result0 !== null) {
794 result1 = parse___();
795 if (result1 !== null) {
796 result0 = [result0, result1];
797 } else {
798 result0 = null;
799 pos = pos1;
800 }
801 } else {
802 result0 = null;
803 pos = pos1;
804 }
805 if (result0 !== null) {
806 result0 = (function(offset, braced) { return braced.substr(1, braced.length - 2); })(pos0, result0[0]);
807 }
808 if (result0 === null) {
809 pos = pos0;
810 }
811 reportFailures--;
812 if (reportFailures === 0 && result0 === null) {
813 matchFailed("action");
814 }
815 return result0;
816 }
817
818 function parse_braced() {
819 var result0, result1, result2;
820 var pos0, pos1;
821
822 pos0 = pos;
823 pos1 = pos;
824 if (input.charCodeAt(pos) === 123) {
825 result0 = "{";
826 pos++;
827 } else {
828 result0 = null;
829 if (reportFailures === 0) {
830 matchFailed("\"{\"");
831 }
832 }
833 if (result0 !== null) {
834 result1 = [];
835 result2 = parse_braced();
836 if (result2 === null) {
837 result2 = parse_nonBraceCharacter();
838 }
839 while (result2 !== null) {
840 result1.push(result2);
841 result2 = parse_braced();
842 if (result2 === null) {
843 result2 = parse_nonBraceCharacter();
844 }
845 }
846 if (result1 !== null) {
847 if (input.charCodeAt(pos) === 125) {
848 result2 = "}";
849 pos++;
850 } else {
851 result2 = null;
852 if (reportFailures === 0) {
853 matchFailed("\"}\"");
854 }
855 }
856 if (result2 !== null) {
857 result0 = [result0, result1, result2];
858 } else {
859 result0 = null;
860 pos = pos1;
861 }
862 } else {
863 result0 = null;
864 pos = pos1;
865 }
866 } else {
867 result0 = null;
868 pos = pos1;
869 }
870 if (result0 !== null) {
871 result0 = (function(offset, parts) {
872 return "{" + parts.join("") + "}";
873 })(pos0, result0[1]);
874 }
875 if (result0 === null) {
876 pos = pos0;
877 }
878 return result0;
879 }
880
881 function parse_nonBraceCharacters() {
882 var result0, result1;
883 var pos0;
884
885 pos0 = pos;
886 result1 = parse_nonBraceCharacter();
887 if (result1 !== null) {
888 result0 = [];
889 while (result1 !== null) {
890 result0.push(result1);
891 result1 = parse_nonBraceCharacter();
892 }
893 } else {
894 result0 = null;
895 }
896 if (result0 !== null) {
897 result0 = (function(offset, chars) { return chars.join(""); })(pos0, result0);
898 }
899 if (result0 === null) {
900 pos = pos0;
901 }
902 return result0;
903 }
904
905 function parse_nonBraceCharacter() {
906 var result0;
907
908 if (/^[^{}]/.test(input.charAt(pos))) {
909 result0 = input.charAt(pos);
910 pos++;
911 } else {
912 result0 = null;
913 if (reportFailures === 0) {
914 matchFailed("[^{}]");
915 }
916 }
917 return result0;
918 }
919
920 function parse_equals() {
921 var result0, result1;
922 var pos0, pos1;
923
924 pos0 = pos;
925 pos1 = pos;
926 if (input.charCodeAt(pos) === 61) {
927 result0 = "=";
928 pos++;
929 } else {
930 result0 = null;
931 if (reportFailures === 0) {
932 matchFailed("\"=\"");
933 }
934 }
935 if (result0 !== null) {
936 result1 = parse___();
937 if (result1 !== null) {
938 result0 = [result0, result1];
939 } else {
940 result0 = null;
941 pos = pos1;
942 }
943 } else {
944 result0 = null;
945 pos = pos1;
946 }
947 if (result0 !== null) {
948 result0 = (function(offset) { return "="; })(pos0);
949 }
950 if (result0 === null) {
951 pos = pos0;
952 }
953 return result0;
954 }
955
956 function parse_colon() {
957 var result0, result1;
958 var pos0, pos1;
959
960 pos0 = pos;
961 pos1 = pos;
962 if (input.charCodeAt(pos) === 58) {
963 result0 = ":";
964 pos++;
965 } else {
966 result0 = null;
967 if (reportFailures === 0) {
968 matchFailed("\":\"");
969 }
970 }
971 if (result0 !== null) {
972 result1 = parse___();
973 if (result1 !== null) {
974 result0 = [result0, result1];
975 } else {
976 result0 = null;
977 pos = pos1;
978 }
979 } else {
980 result0 = null;
981 pos = pos1;
982 }
983 if (result0 !== null) {
984 result0 = (function(offset) { return ":"; })(pos0);
985 }
986 if (result0 === null) {
987 pos = pos0;
988 }
989 return result0;
990 }
991
992 function parse_semicolon() {
993 var result0, result1;
994 var pos0, pos1;
995
996 pos0 = pos;
997 pos1 = pos;
998 if (input.charCodeAt(pos) === 59) {
999 result0 = ";";
1000 pos++;
1001 } else {
1002 result0 = null;
1003 if (reportFailures === 0) {
1004 matchFailed("\";\"");
1005 }
1006 }
1007 if (result0 !== null) {
1008 result1 = parse___();
1009 if (result1 !== null) {
1010 result0 = [result0, result1];
1011 } else {
1012 result0 = null;
1013 pos = pos1;
1014 }
1015 } else {
1016 result0 = null;
1017 pos = pos1;
1018 }
1019 if (result0 !== null) {
1020 result0 = (function(offset) { return ";"; })(pos0);
1021 }
1022 if (result0 === null) {
1023 pos = pos0;
1024 }
1025 return result0;
1026 }
1027
1028 function parse_slash() {
1029 var result0, result1;
1030 var pos0, pos1;
1031
1032 pos0 = pos;
1033 pos1 = pos;
1034 if (input.charCodeAt(pos) === 47) {
1035 result0 = "/";
1036 pos++;
1037 } else {
1038 result0 = null;
1039 if (reportFailures === 0) {
1040 matchFailed("\"/\"");
1041 }
1042 }
1043 if (result0 !== null) {
1044 result1 = parse___();
1045 if (result1 !== null) {
1046 result0 = [result0, result1];
1047 } else {
1048 result0 = null;
1049 pos = pos1;
1050 }
1051 } else {
1052 result0 = null;
1053 pos = pos1;
1054 }
1055 if (result0 !== null) {
1056 result0 = (function(offset) { return "/"; })(pos0);
1057 }
1058 if (result0 === null) {
1059 pos = pos0;
1060 }
1061 return result0;
1062 }
1063
1064 function parse_and() {
1065 var result0, result1;
1066 var pos0, pos1;
1067
1068 pos0 = pos;
1069 pos1 = pos;
1070 if (input.charCodeAt(pos) === 38) {
1071 result0 = "&";
1072 pos++;
1073 } else {
1074 result0 = null;
1075 if (reportFailures === 0) {
1076 matchFailed("\"&\"");
1077 }
1078 }
1079 if (result0 !== null) {
1080 result1 = parse___();
1081 if (result1 !== null) {
1082 result0 = [result0, result1];
1083 } else {
1084 result0 = null;
1085 pos = pos1;
1086 }
1087 } else {
1088 result0 = null;
1089 pos = pos1;
1090 }
1091 if (result0 !== null) {
1092 result0 = (function(offset) { return "&"; })(pos0);
1093 }
1094 if (result0 === null) {
1095 pos = pos0;
1096 }
1097 return result0;
1098 }
1099
1100 function parse_not() {
1101 var result0, result1;
1102 var pos0, pos1;
1103
1104 pos0 = pos;
1105 pos1 = pos;
1106 if (input.charCodeAt(pos) === 33) {
1107 result0 = "!";
1108 pos++;
1109 } else {
1110 result0 = null;
1111 if (reportFailures === 0) {
1112 matchFailed("\"!\"");
1113 }
1114 }
1115 if (result0 !== null) {
1116 result1 = parse___();
1117 if (result1 !== null) {
1118 result0 = [result0, result1];
1119 } else {
1120 result0 = null;
1121 pos = pos1;
1122 }
1123 } else {
1124 result0 = null;
1125 pos = pos1;
1126 }
1127 if (result0 !== null) {
1128 result0 = (function(offset) { return "!"; })(pos0);
1129 }
1130 if (result0 === null) {
1131 pos = pos0;
1132 }
1133 return result0;
1134 }
1135
1136 function parse_question() {
1137 var result0, result1;
1138 var pos0, pos1;
1139
1140 pos0 = pos;
1141 pos1 = pos;
1142 if (input.charCodeAt(pos) === 63) {
1143 result0 = "?";
1144 pos++;
1145 } else {
1146 result0 = null;
1147 if (reportFailures === 0) {
1148 matchFailed("\"?\"");
1149 }
1150 }
1151 if (result0 !== null) {
1152 result1 = parse___();
1153 if (result1 !== null) {
1154 result0 = [result0, result1];
1155 } else {
1156 result0 = null;
1157 pos = pos1;
1158 }
1159 } else {
1160 result0 = null;
1161 pos = pos1;
1162 }
1163 if (result0 !== null) {
1164 result0 = (function(offset) { return "?"; })(pos0);
1165 }
1166 if (result0 === null) {
1167 pos = pos0;
1168 }
1169 return result0;
1170 }
1171
1172 function parse_star() {
1173 var result0, result1;
1174 var pos0, pos1;
1175
1176 pos0 = pos;
1177 pos1 = pos;
1178 if (input.charCodeAt(pos) === 42) {
1179 result0 = "*";
1180 pos++;
1181 } else {
1182 result0 = null;
1183 if (reportFailures === 0) {
1184 matchFailed("\"*\"");
1185 }
1186 }
1187 if (result0 !== null) {
1188 result1 = parse___();
1189 if (result1 !== null) {
1190 result0 = [result0, result1];
1191 } else {
1192 result0 = null;
1193 pos = pos1;
1194 }
1195 } else {
1196 result0 = null;
1197 pos = pos1;
1198 }
1199 if (result0 !== null) {
1200 result0 = (function(offset) { return "*"; })(pos0);
1201 }
1202 if (result0 === null) {
1203 pos = pos0;
1204 }
1205 return result0;
1206 }
1207
1208 function parse_plus() {
1209 var result0, result1;
1210 var pos0, pos1;
1211
1212 pos0 = pos;
1213 pos1 = pos;
1214 if (input.charCodeAt(pos) === 43) {
1215 result0 = "+";
1216 pos++;
1217 } else {
1218 result0 = null;
1219 if (reportFailures === 0) {
1220 matchFailed("\"+\"");
1221 }
1222 }
1223 if (result0 !== null) {
1224 result1 = parse___();
1225 if (result1 !== null) {
1226 result0 = [result0, result1];
1227 } else {
1228 result0 = null;
1229 pos = pos1;
1230 }
1231 } else {
1232 result0 = null;
1233 pos = pos1;
1234 }
1235 if (result0 !== null) {
1236 result0 = (function(offset) { return "+"; })(pos0);
1237 }
1238 if (result0 === null) {
1239 pos = pos0;
1240 }
1241 return result0;
1242 }
1243
1244 function parse_lparen() {
1245 var result0, result1;
1246 var pos0, pos1;
1247
1248 pos0 = pos;
1249 pos1 = pos;
1250 if (input.charCodeAt(pos) === 40) {
1251 result0 = "(";
1252 pos++;
1253 } else {
1254 result0 = null;
1255 if (reportFailures === 0) {
1256 matchFailed("\"(\"");
1257 }
1258 }
1259 if (result0 !== null) {
1260 result1 = parse___();
1261 if (result1 !== null) {
1262 result0 = [result0, result1];
1263 } else {
1264 result0 = null;
1265 pos = pos1;
1266 }
1267 } else {
1268 result0 = null;
1269 pos = pos1;
1270 }
1271 if (result0 !== null) {
1272 result0 = (function(offset) { return "("; })(pos0);
1273 }
1274 if (result0 === null) {
1275 pos = pos0;
1276 }
1277 return result0;
1278 }
1279
1280 function parse_rparen() {
1281 var result0, result1;
1282 var pos0, pos1;
1283
1284 pos0 = pos;
1285 pos1 = pos;
1286 if (input.charCodeAt(pos) === 41) {
1287 result0 = ")";
1288 pos++;
1289 } else {
1290 result0 = null;
1291 if (reportFailures === 0) {
1292 matchFailed("\")\"");
1293 }
1294 }
1295 if (result0 !== null) {
1296 result1 = parse___();
1297 if (result1 !== null) {
1298 result0 = [result0, result1];
1299 } else {
1300 result0 = null;
1301 pos = pos1;
1302 }
1303 } else {
1304 result0 = null;
1305 pos = pos1;
1306 }
1307 if (result0 !== null) {
1308 result0 = (function(offset) { return ")"; })(pos0);
1309 }
1310 if (result0 === null) {
1311 pos = pos0;
1312 }
1313 return result0;
1314 }
1315
1316 function parse_dot() {
1317 var result0, result1;
1318 var pos0, pos1;
1319
1320 pos0 = pos;
1321 pos1 = pos;
1322 if (input.charCodeAt(pos) === 46) {
1323 result0 = ".";
1324 pos++;
1325 } else {
1326 result0 = null;
1327 if (reportFailures === 0) {
1328 matchFailed("\".\"");
1329 }
1330 }
1331 if (result0 !== null) {
1332 result1 = parse___();
1333 if (result1 !== null) {
1334 result0 = [result0, result1];
1335 } else {
1336 result0 = null;
1337 pos = pos1;
1338 }
1339 } else {
1340 result0 = null;
1341 pos = pos1;
1342 }
1343 if (result0 !== null) {
1344 result0 = (function(offset) { return "."; })(pos0);
1345 }
1346 if (result0 === null) {
1347 pos = pos0;
1348 }
1349 return result0;
1350 }
1351
1352 function parse_identifier() {
1353 var result0, result1, result2;
1354 var pos0, pos1;
1355
1356 reportFailures++;
1357 pos0 = pos;
1358 pos1 = pos;
1359 result0 = parse_letter();
1360 if (result0 === null) {
1361 if (input.charCodeAt(pos) === 95) {
1362 result0 = "_";
1363 pos++;
1364 } else {
1365 result0 = null;
1366 if (reportFailures === 0) {
1367 matchFailed("\"_\"");
1368 }
1369 }
1370 if (result0 === null) {
1371 if (input.charCodeAt(pos) === 36) {
1372 result0 = "$";
1373 pos++;
1374 } else {
1375 result0 = null;
1376 if (reportFailures === 0) {
1377 matchFailed("\"$\"");
1378 }
1379 }
1380 }
1381 }
1382 if (result0 !== null) {
1383 result1 = [];
1384 result2 = parse_letter();
1385 if (result2 === null) {
1386 result2 = parse_digit();
1387 if (result2 === null) {
1388 if (input.charCodeAt(pos) === 95) {
1389 result2 = "_";
1390 pos++;
1391 } else {
1392 result2 = null;
1393 if (reportFailures === 0) {
1394 matchFailed("\"_\"");
1395 }
1396 }
1397 if (result2 === null) {
1398 if (input.charCodeAt(pos) === 36) {
1399 result2 = "$";
1400 pos++;
1401 } else {
1402 result2 = null;
1403 if (reportFailures === 0) {
1404 matchFailed("\"$\"");
1405 }
1406 }
1407 }
1408 }
1409 }
1410 while (result2 !== null) {
1411 result1.push(result2);
1412 result2 = parse_letter();
1413 if (result2 === null) {
1414 result2 = parse_digit();
1415 if (result2 === null) {
1416 if (input.charCodeAt(pos) === 95) {
1417 result2 = "_";
1418 pos++;
1419 } else {
1420 result2 = null;
1421 if (reportFailures === 0) {
1422 matchFailed("\"_\"");
1423 }
1424 }
1425 if (result2 === null) {
1426 if (input.charCodeAt(pos) === 36) {
1427 result2 = "$";
1428 pos++;
1429 } else {
1430 result2 = null;
1431 if (reportFailures === 0) {
1432 matchFailed("\"$\"");
1433 }
1434 }
1435 }
1436 }
1437 }
1438 }
1439 if (result1 !== null) {
1440 result2 = parse___();
1441 if (result2 !== null) {
1442 result0 = [result0, result1, result2];
1443 } else {
1444 result0 = null;
1445 pos = pos1;
1446 }
1447 } else {
1448 result0 = null;
1449 pos = pos1;
1450 }
1451 } else {
1452 result0 = null;
1453 pos = pos1;
1454 }
1455 if (result0 !== null) {
1456 result0 = (function(offset, head, tail) {
1457 return head + tail.join("");
1458 })(pos0, result0[0], result0[1]);
1459 }
1460 if (result0 === null) {
1461 pos = pos0;
1462 }
1463 reportFailures--;
1464 if (reportFailures === 0 && result0 === null) {
1465 matchFailed("identifier");
1466 }
1467 return result0;
1468 }
1469
1470 function parse_literal() {
1471 var result0, result1, result2;
1472 var pos0, pos1;
1473
1474 reportFailures++;
1475 pos0 = pos;
1476 pos1 = pos;
1477 result0 = parse_doubleQuotedString();
1478 if (result0 === null) {
1479 result0 = parse_singleQuotedString();
1480 }
1481 if (result0 !== null) {
1482 if (input.charCodeAt(pos) === 105) {
1483 result1 = "i";
1484 pos++;
1485 } else {
1486 result1 = null;
1487 if (reportFailures === 0) {
1488 matchFailed("\"i\"");
1489 }
1490 }
1491 result1 = result1 !== null ? result1 : "";
1492 if (result1 !== null) {
1493 result2 = parse___();
1494 if (result2 !== null) {
1495 result0 = [result0, result1, result2];
1496 } else {
1497 result0 = null;
1498 pos = pos1;
1499 }
1500 } else {
1501 result0 = null;
1502 pos = pos1;
1503 }
1504 } else {
1505 result0 = null;
1506 pos = pos1;
1507 }
1508 if (result0 !== null) {
1509 result0 = (function(offset, value, flags) {
1510 return {
1511 type: "literal",
1512 value: value,
1513 ignoreCase: flags === "i"
1514 };
1515 })(pos0, result0[0], result0[1]);
1516 }
1517 if (result0 === null) {
1518 pos = pos0;
1519 }
1520 reportFailures--;
1521 if (reportFailures === 0 && result0 === null) {
1522 matchFailed("literal");
1523 }
1524 return result0;
1525 }
1526
1527 function parse_string() {
1528 var result0, result1;
1529 var pos0, pos1;
1530
1531 reportFailures++;
1532 pos0 = pos;
1533 pos1 = pos;
1534 result0 = parse_doubleQuotedString();
1535 if (result0 === null) {
1536 result0 = parse_singleQuotedString();
1537 }
1538 if (result0 !== null) {
1539 result1 = parse___();
1540 if (result1 !== null) {
1541 result0 = [result0, result1];
1542 } else {
1543 result0 = null;
1544 pos = pos1;
1545 }
1546 } else {
1547 result0 = null;
1548 pos = pos1;
1549 }
1550 if (result0 !== null) {
1551 result0 = (function(offset, string) { return string; })(pos0, result0[0]);
1552 }
1553 if (result0 === null) {
1554 pos = pos0;
1555 }
1556 reportFailures--;
1557 if (reportFailures === 0 && result0 === null) {
1558 matchFailed("string");
1559 }
1560 return result0;
1561 }
1562
1563 function parse_doubleQuotedString() {
1564 var result0, result1, result2;
1565 var pos0, pos1;
1566
1567 pos0 = pos;
1568 pos1 = pos;
1569 if (input.charCodeAt(pos) === 34) {
1570 result0 = "\"";
1571 pos++;
1572 } else {
1573 result0 = null;
1574 if (reportFailures === 0) {
1575 matchFailed("\"\\\"\"");
1576 }
1577 }
1578 if (result0 !== null) {
1579 result1 = [];
1580 result2 = parse_doubleQuotedCharacter();
1581 while (result2 !== null) {
1582 result1.push(result2);
1583 result2 = parse_doubleQuotedCharacter();
1584 }
1585 if (result1 !== null) {
1586 if (input.charCodeAt(pos) === 34) {
1587 result2 = "\"";
1588 pos++;
1589 } else {
1590 result2 = null;
1591 if (reportFailures === 0) {
1592 matchFailed("\"\\\"\"");
1593 }
1594 }
1595 if (result2 !== null) {
1596 result0 = [result0, result1, result2];
1597 } else {
1598 result0 = null;
1599 pos = pos1;
1600 }
1601 } else {
1602 result0 = null;
1603 pos = pos1;
1604 }
1605 } else {
1606 result0 = null;
1607 pos = pos1;
1608 }
1609 if (result0 !== null) {
1610 result0 = (function(offset, chars) { return chars.join(""); })(pos0, result0[1]);
1611 }
1612 if (result0 === null) {
1613 pos = pos0;
1614 }
1615 return result0;
1616 }
1617
1618 function parse_doubleQuotedCharacter() {
1619 var result0;
1620
1621 result0 = parse_simpleDoubleQuotedCharacter();
1622 if (result0 === null) {
1623 result0 = parse_simpleEscapeSequence();
1624 if (result0 === null) {
1625 result0 = parse_zeroEscapeSequence();
1626 if (result0 === null) {
1627 result0 = parse_hexEscapeSequence();
1628 if (result0 === null) {
1629 result0 = parse_unicodeEscapeSequence();
1630 if (result0 === null) {
1631 result0 = parse_eolEscapeSequence();
1632 }
1633 }
1634 }
1635 }
1636 }
1637 return result0;
1638 }
1639
1640 function parse_simpleDoubleQuotedCharacter() {
1641 var result0, result1;
1642 var pos0, pos1, pos2;
1643
1644 pos0 = pos;
1645 pos1 = pos;
1646 pos2 = pos;
1647 reportFailures++;
1648 if (input.charCodeAt(pos) === 34) {
1649 result0 = "\"";
1650 pos++;
1651 } else {
1652 result0 = null;
1653 if (reportFailures === 0) {
1654 matchFailed("\"\\\"\"");
1655 }
1656 }
1657 if (result0 === null) {
1658 if (input.charCodeAt(pos) === 92) {
1659 result0 = "\\";
1660 pos++;
1661 } else {
1662 result0 = null;
1663 if (reportFailures === 0) {
1664 matchFailed("\"\\\\\"");
1665 }
1666 }
1667 if (result0 === null) {
1668 result0 = parse_eolChar();
1669 }
1670 }
1671 reportFailures--;
1672 if (result0 === null) {
1673 result0 = "";
1674 } else {
1675 result0 = null;
1676 pos = pos2;
1677 }
1678 if (result0 !== null) {
1679 if (input.length > pos) {
1680 result1 = input.charAt(pos);
1681 pos++;
1682 } else {
1683 result1 = null;
1684 if (reportFailures === 0) {
1685 matchFailed("any character");
1686 }
1687 }
1688 if (result1 !== null) {
1689 result0 = [result0, result1];
1690 } else {
1691 result0 = null;
1692 pos = pos1;
1693 }
1694 } else {
1695 result0 = null;
1696 pos = pos1;
1697 }
1698 if (result0 !== null) {
1699 result0 = (function(offset, char_) { return char_; })(pos0, result0[1]);
1700 }
1701 if (result0 === null) {
1702 pos = pos0;
1703 }
1704 return result0;
1705 }
1706
1707 function parse_singleQuotedString() {
1708 var result0, result1, result2;
1709 var pos0, pos1;
1710
1711 pos0 = pos;
1712 pos1 = pos;
1713 if (input.charCodeAt(pos) === 39) {
1714 result0 = "'";
1715 pos++;
1716 } else {
1717 result0 = null;
1718 if (reportFailures === 0) {
1719 matchFailed("\"'\"");
1720 }
1721 }
1722 if (result0 !== null) {
1723 result1 = [];
1724 result2 = parse_singleQuotedCharacter();
1725 while (result2 !== null) {
1726 result1.push(result2);
1727 result2 = parse_singleQuotedCharacter();
1728 }
1729 if (result1 !== null) {
1730 if (input.charCodeAt(pos) === 39) {
1731 result2 = "'";
1732 pos++;
1733 } else {
1734 result2 = null;
1735 if (reportFailures === 0) {
1736 matchFailed("\"'\"");
1737 }
1738 }
1739 if (result2 !== null) {
1740 result0 = [result0, result1, result2];
1741 } else {
1742 result0 = null;
1743 pos = pos1;
1744 }
1745 } else {
1746 result0 = null;
1747 pos = pos1;
1748 }
1749 } else {
1750 result0 = null;
1751 pos = pos1;
1752 }
1753 if (result0 !== null) {
1754 result0 = (function(offset, chars) { return chars.join(""); })(pos0, result0[1]);
1755 }
1756 if (result0 === null) {
1757 pos = pos0;
1758 }
1759 return result0;
1760 }
1761
1762 function parse_singleQuotedCharacter() {
1763 var result0;
1764
1765 result0 = parse_simpleSingleQuotedCharacter();
1766 if (result0 === null) {
1767 result0 = parse_simpleEscapeSequence();
1768 if (result0 === null) {
1769 result0 = parse_zeroEscapeSequence();
1770 if (result0 === null) {
1771 result0 = parse_hexEscapeSequence();
1772 if (result0 === null) {
1773 result0 = parse_unicodeEscapeSequence();
1774 if (result0 === null) {
1775 result0 = parse_eolEscapeSequence();
1776 }
1777 }
1778 }
1779 }
1780 }
1781 return result0;
1782 }
1783
1784 function parse_simpleSingleQuotedCharacter() {
1785 var result0, result1;
1786 var pos0, pos1, pos2;
1787
1788 pos0 = pos;
1789 pos1 = pos;
1790 pos2 = pos;
1791 reportFailures++;
1792 if (input.charCodeAt(pos) === 39) {
1793 result0 = "'";
1794 pos++;
1795 } else {
1796 result0 = null;
1797 if (reportFailures === 0) {
1798 matchFailed("\"'\"");
1799 }
1800 }
1801 if (result0 === null) {
1802 if (input.charCodeAt(pos) === 92) {
1803 result0 = "\\";
1804 pos++;
1805 } else {
1806 result0 = null;
1807 if (reportFailures === 0) {
1808 matchFailed("\"\\\\\"");
1809 }
1810 }
1811 if (result0 === null) {
1812 result0 = parse_eolChar();
1813 }
1814 }
1815 reportFailures--;
1816 if (result0 === null) {
1817 result0 = "";
1818 } else {
1819 result0 = null;
1820 pos = pos2;
1821 }
1822 if (result0 !== null) {
1823 if (input.length > pos) {
1824 result1 = input.charAt(pos);
1825 pos++;
1826 } else {
1827 result1 = null;
1828 if (reportFailures === 0) {
1829 matchFailed("any character");
1830 }
1831 }
1832 if (result1 !== null) {
1833 result0 = [result0, result1];
1834 } else {
1835 result0 = null;
1836 pos = pos1;
1837 }
1838 } else {
1839 result0 = null;
1840 pos = pos1;
1841 }
1842 if (result0 !== null) {
1843 result0 = (function(offset, char_) { return char_; })(pos0, result0[1]);
1844 }
1845 if (result0 === null) {
1846 pos = pos0;
1847 }
1848 return result0;
1849 }
1850
1851 function parse_class() {
1852 var result0, result1, result2, result3, result4, result5;
1853 var pos0, pos1;
1854
1855 reportFailures++;
1856 pos0 = pos;
1857 pos1 = pos;
1858 if (input.charCodeAt(pos) === 91) {
1859 result0 = "[";
1860 pos++;
1861 } else {
1862 result0 = null;
1863 if (reportFailures === 0) {
1864 matchFailed("\"[\"");
1865 }
1866 }
1867 if (result0 !== null) {
1868 if (input.charCodeAt(pos) === 94) {
1869 result1 = "^";
1870 pos++;
1871 } else {
1872 result1 = null;
1873 if (reportFailures === 0) {
1874 matchFailed("\"^\"");
1875 }
1876 }
1877 result1 = result1 !== null ? result1 : "";
1878 if (result1 !== null) {
1879 result2 = [];
1880 result3 = parse_classCharacterRange();
1881 if (result3 === null) {
1882 result3 = parse_classCharacter();
1883 }
1884 while (result3 !== null) {
1885 result2.push(result3);
1886 result3 = parse_classCharacterRange();
1887 if (result3 === null) {
1888 result3 = parse_classCharacter();
1889 }
1890 }
1891 if (result2 !== null) {
1892 if (input.charCodeAt(pos) === 93) {
1893 result3 = "]";
1894 pos++;
1895 } else {
1896 result3 = null;
1897 if (reportFailures === 0) {
1898 matchFailed("\"]\"");
1899 }
1900 }
1901 if (result3 !== null) {
1902 if (input.charCodeAt(pos) === 105) {
1903 result4 = "i";
1904 pos++;
1905 } else {
1906 result4 = null;
1907 if (reportFailures === 0) {
1908 matchFailed("\"i\"");
1909 }
1910 }
1911 result4 = result4 !== null ? result4 : "";
1912 if (result4 !== null) {
1913 result5 = parse___();
1914 if (result5 !== null) {
1915 result0 = [result0, result1, result2, result3, result4, result5];
1916 } else {
1917 result0 = null;
1918 pos = pos1;
1919 }
1920 } else {
1921 result0 = null;
1922 pos = pos1;
1923 }
1924 } else {
1925 result0 = null;
1926 pos = pos1;
1927 }
1928 } else {
1929 result0 = null;
1930 pos = pos1;
1931 }
1932 } else {
1933 result0 = null;
1934 pos = pos1;
1935 }
1936 } else {
1937 result0 = null;
1938 pos = pos1;
1939 }
1940 if (result0 !== null) {
1941 result0 = (function(offset, inverted, parts, flags) {
1942 var partsConverted = map(parts, function(part) { return part.data; });
1943 var rawText = "["
1944 + inverted
1945 + map(parts, function(part) { return part.rawText; }).join("")
1946 + "]"
1947 + flags;
1948
1949 return {
1950 type: "class",
1951 inverted: inverted === "^",
1952 ignoreCase: flags === "i",
1953 parts: partsConverted,
1954 // FIXME: Get the raw text from the input directly.
1955 rawText: rawText
1956 };
1957 })(pos0, result0[1], result0[2], result0[4]);
1958 }
1959 if (result0 === null) {
1960 pos = pos0;
1961 }
1962 reportFailures--;
1963 if (reportFailures === 0 && result0 === null) {
1964 matchFailed("character class");
1965 }
1966 return result0;
1967 }
1968
1969 function parse_classCharacterRange() {
1970 var result0, result1, result2;
1971 var pos0, pos1;
1972
1973 pos0 = pos;
1974 pos1 = pos;
1975 result0 = parse_classCharacter();
1976 if (result0 !== null) {
1977 if (input.charCodeAt(pos) === 45) {
1978 result1 = "-";
1979 pos++;
1980 } else {
1981 result1 = null;
1982 if (reportFailures === 0) {
1983 matchFailed("\"-\"");
1984 }
1985 }
1986 if (result1 !== null) {
1987 result2 = parse_classCharacter();
1988 if (result2 !== null) {
1989 result0 = [result0, result1, result2];
1990 } else {
1991 result0 = null;
1992 pos = pos1;
1993 }
1994 } else {
1995 result0 = null;
1996 pos = pos1;
1997 }
1998 } else {
1999 result0 = null;
2000 pos = pos1;
2001 }
2002 if (result0 !== null) {
2003 result0 = (function(offset, begin, end) {
2004 if (begin.data.charCodeAt(0) > end.data.charCodeAt(0)) {
2005 throw new this.SyntaxError(
2006 "Invalid character range: " + begin.rawText + "-" + end.rawText + "."
2007 );
2008 }
2009
2010 return {
2011 data: [begin.data, end.data],
2012 // FIXME: Get the raw text from the input directly.
2013 rawText: begin.rawText + "-" + end.rawText
2014 };
2015 })(pos0, result0[0], result0[2]);
2016 }
2017 if (result0 === null) {
2018 pos = pos0;
2019 }
2020 return result0;
2021 }
2022
2023 function parse_classCharacter() {
2024 var result0;
2025 var pos0;
2026
2027 pos0 = pos;
2028 result0 = parse_bracketDelimitedCharacter();
2029 if (result0 !== null) {
2030 result0 = (function(offset, char_) {
2031 return {
2032 data: char_,
2033 // FIXME: Get the raw text from the input directly.
2034 rawText: quoteForRegexpClass(char_)
2035 };
2036 })(pos0, result0);
2037 }
2038 if (result0 === null) {
2039 pos = pos0;
2040 }
2041 return result0;
2042 }
2043
2044 function parse_bracketDelimitedCharacter() {
2045 var result0;
2046
2047 result0 = parse_simpleBracketDelimitedCharacter();
2048 if (result0 === null) {
2049 result0 = parse_simpleEscapeSequence();
2050 if (result0 === null) {
2051 result0 = parse_zeroEscapeSequence();
2052 if (result0 === null) {
2053 result0 = parse_hexEscapeSequence();
2054 if (result0 === null) {
2055 result0 = parse_unicodeEscapeSequence();
2056 if (result0 === null) {
2057 result0 = parse_eolEscapeSequence();
2058 }
2059 }
2060 }
2061 }
2062 }
2063 return result0;
2064 }
2065
2066 function parse_simpleBracketDelimitedCharacter() {
2067 var result0, result1;
2068 var pos0, pos1, pos2;
2069
2070 pos0 = pos;
2071 pos1 = pos;
2072 pos2 = pos;
2073 reportFailures++;
2074 if (input.charCodeAt(pos) === 93) {
2075 result0 = "]";
2076 pos++;
2077 } else {
2078 result0 = null;
2079 if (reportFailures === 0) {
2080 matchFailed("\"]\"");
2081 }
2082 }
2083 if (result0 === null) {
2084 if (input.charCodeAt(pos) === 92) {
2085 result0 = "\\";
2086 pos++;
2087 } else {
2088 result0 = null;
2089 if (reportFailures === 0) {
2090 matchFailed("\"\\\\\"");
2091 }
2092 }
2093 if (result0 === null) {
2094 result0 = parse_eolChar();
2095 }
2096 }
2097 reportFailures--;
2098 if (result0 === null) {
2099 result0 = "";
2100 } else {
2101 result0 = null;
2102 pos = pos2;
2103 }
2104 if (result0 !== null) {
2105 if (input.length > pos) {
2106 result1 = input.charAt(pos);
2107 pos++;
2108 } else {
2109 result1 = null;
2110 if (reportFailures === 0) {
2111 matchFailed("any character");
2112 }
2113 }
2114 if (result1 !== null) {
2115 result0 = [result0, result1];
2116 } else {
2117 result0 = null;
2118 pos = pos1;
2119 }
2120 } else {
2121 result0 = null;
2122 pos = pos1;
2123 }
2124 if (result0 !== null) {
2125 result0 = (function(offset, char_) { return char_; })(pos0, result0[1]);
2126 }
2127 if (result0 === null) {
2128 pos = pos0;
2129 }
2130 return result0;
2131 }
2132
2133 function parse_simpleEscapeSequence() {
2134 var result0, result1, result2;
2135 var pos0, pos1, pos2;
2136
2137 pos0 = pos;
2138 pos1 = pos;
2139 if (input.charCodeAt(pos) === 92) {
2140 result0 = "\\";
2141 pos++;
2142 } else {
2143 result0 = null;
2144 if (reportFailures === 0) {
2145 matchFailed("\"\\\\\"");
2146 }
2147 }
2148 if (result0 !== null) {
2149 pos2 = pos;
2150 reportFailures++;
2151 result1 = parse_digit();
2152 if (result1 === null) {
2153 if (input.charCodeAt(pos) === 120) {
2154 result1 = "x";
2155 pos++;
2156 } else {
2157 result1 = null;
2158 if (reportFailures === 0) {
2159 matchFailed("\"x\"");
2160 }
2161 }
2162 if (result1 === null) {
2163 if (input.charCodeAt(pos) === 117) {
2164 result1 = "u";
2165 pos++;
2166 } else {
2167 result1 = null;
2168 if (reportFailures === 0) {
2169 matchFailed("\"u\"");
2170 }
2171 }
2172 if (result1 === null) {
2173 result1 = parse_eolChar();
2174 }
2175 }
2176 }
2177 reportFailures--;
2178 if (result1 === null) {
2179 result1 = "";
2180 } else {
2181 result1 = null;
2182 pos = pos2;
2183 }
2184 if (result1 !== null) {
2185 if (input.length > pos) {
2186 result2 = input.charAt(pos);
2187 pos++;
2188 } else {
2189 result2 = null;
2190 if (reportFailures === 0) {
2191 matchFailed("any character");
2192 }
2193 }
2194 if (result2 !== null) {
2195 result0 = [result0, result1, result2];
2196 } else {
2197 result0 = null;
2198 pos = pos1;
2199 }
2200 } else {
2201 result0 = null;
2202 pos = pos1;
2203 }
2204 } else {
2205 result0 = null;
2206 pos = pos1;
2207 }
2208 if (result0 !== null) {
2209 result0 = (function(offset, char_) {
2210 return char_
2211 .replace("b", "\b")
2212 .replace("f", "\f")
2213 .replace("n", "\n")
2214 .replace("r", "\r")
2215 .replace("t", "\t")
2216 .replace("v", "\x0B"); // IE does not recognize "\v".
2217 })(pos0, result0[2]);
2218 }
2219 if (result0 === null) {
2220 pos = pos0;
2221 }
2222 return result0;
2223 }
2224
2225 function parse_zeroEscapeSequence() {
2226 var result0, result1;
2227 var pos0, pos1, pos2;
2228
2229 pos0 = pos;
2230 pos1 = pos;
2231 if (input.substr(pos, 2) === "\\0") {
2232 result0 = "\\0";
2233 pos += 2;
2234 } else {
2235 result0 = null;
2236 if (reportFailures === 0) {
2237 matchFailed("\"\\\\0\"");
2238 }
2239 }
2240 if (result0 !== null) {
2241 pos2 = pos;
2242 reportFailures++;
2243 result1 = parse_digit();
2244 reportFailures--;
2245 if (result1 === null) {
2246 result1 = "";
2247 } else {
2248 result1 = null;
2249 pos = pos2;
2250 }
2251 if (result1 !== null) {
2252 result0 = [result0, result1];
2253 } else {
2254 result0 = null;
2255 pos = pos1;
2256 }
2257 } else {
2258 result0 = null;
2259 pos = pos1;
2260 }
2261 if (result0 !== null) {
2262 result0 = (function(offset) { return "\x00"; })(pos0);
2263 }
2264 if (result0 === null) {
2265 pos = pos0;
2266 }
2267 return result0;
2268 }
2269
2270 function parse_hexEscapeSequence() {
2271 var result0, result1, result2;
2272 var pos0, pos1;
2273
2274 pos0 = pos;
2275 pos1 = pos;
2276 if (input.substr(pos, 2) === "\\x") {
2277 result0 = "\\x";
2278 pos += 2;
2279 } else {
2280 result0 = null;
2281 if (reportFailures === 0) {
2282 matchFailed("\"\\\\x\"");
2283 }
2284 }
2285 if (result0 !== null) {
2286 result1 = parse_hexDigit();
2287 if (result1 !== null) {
2288 result2 = parse_hexDigit();
2289 if (result2 !== null) {
2290 result0 = [result0, result1, result2];
2291 } else {
2292 result0 = null;
2293 pos = pos1;
2294 }
2295 } else {
2296 result0 = null;
2297 pos = pos1;
2298 }
2299 } else {
2300 result0 = null;
2301 pos = pos1;
2302 }
2303 if (result0 !== null) {
2304 result0 = (function(offset, h1, h2) {
2305 return String.fromCharCode(parseInt(h1 + h2, 16));
2306 })(pos0, result0[1], result0[2]);
2307 }
2308 if (result0 === null) {
2309 pos = pos0;
2310 }
2311 return result0;
2312 }
2313
2314 function parse_unicodeEscapeSequence() {
2315 var result0, result1, result2, result3, result4;
2316 var pos0, pos1;
2317
2318 pos0 = pos;
2319 pos1 = pos;
2320 if (input.substr(pos, 2) === "\\u") {
2321 result0 = "\\u";
2322 pos += 2;
2323 } else {
2324 result0 = null;
2325 if (reportFailures === 0) {
2326 matchFailed("\"\\\\u\"");
2327 }
2328 }
2329 if (result0 !== null) {
2330 result1 = parse_hexDigit();
2331 if (result1 !== null) {
2332 result2 = parse_hexDigit();
2333 if (result2 !== null) {
2334 result3 = parse_hexDigit();
2335 if (result3 !== null) {
2336 result4 = parse_hexDigit();
2337 if (result4 !== null) {
2338 result0 = [result0, result1, result2, result3, result4];
2339 } else {
2340 result0 = null;
2341 pos = pos1;
2342 }
2343 } else {
2344 result0 = null;
2345 pos = pos1;
2346 }
2347 } else {
2348 result0 = null;
2349 pos = pos1;
2350 }
2351 } else {
2352 result0 = null;
2353 pos = pos1;
2354 }
2355 } else {
2356 result0 = null;
2357 pos = pos1;
2358 }
2359 if (result0 !== null) {
2360 result0 = (function(offset, h1, h2, h3, h4) {
2361 return String.fromCharCode(parseInt(h1 + h2 + h3 + h4, 16));
2362 })(pos0, result0[1], result0[2], result0[3], result0[4]);
2363 }
2364 if (result0 === null) {
2365 pos = pos0;
2366 }
2367 return result0;
2368 }
2369
2370 function parse_eolEscapeSequence() {
2371 var result0, result1;
2372 var pos0, pos1;
2373
2374 pos0 = pos;
2375 pos1 = pos;
2376 if (input.charCodeAt(pos) === 92) {
2377 result0 = "\\";
2378 pos++;
2379 } else {
2380 result0 = null;
2381 if (reportFailures === 0) {
2382 matchFailed("\"\\\\\"");
2383 }
2384 }
2385 if (result0 !== null) {
2386 result1 = parse_eol();
2387 if (result1 !== null) {
2388 result0 = [result0, result1];
2389 } else {
2390 result0 = null;
2391 pos = pos1;
2392 }
2393 } else {
2394 result0 = null;
2395 pos = pos1;
2396 }
2397 if (result0 !== null) {
2398 result0 = (function(offset, eol) { return eol; })(pos0, result0[1]);
2399 }
2400 if (result0 === null) {
2401 pos = pos0;
2402 }
2403 return result0;
2404 }
2405
2406 function parse_digit() {
2407 var result0;
2408
2409 if (/^[0-9]/.test(input.charAt(pos))) {
2410 result0 = input.charAt(pos);
2411 pos++;
2412 } else {
2413 result0 = null;
2414 if (reportFailures === 0) {
2415 matchFailed("[0-9]");
2416 }
2417 }
2418 return result0;
2419 }
2420
2421 function parse_hexDigit() {
2422 var result0;
2423
2424 if (/^[0-9a-fA-F]/.test(input.charAt(pos))) {
2425 result0 = input.charAt(pos);
2426 pos++;
2427 } else {
2428 result0 = null;
2429 if (reportFailures === 0) {
2430 matchFailed("[0-9a-fA-F]");
2431 }
2432 }
2433 return result0;
2434 }
2435
2436 function parse_letter() {
2437 var result0;
2438
2439 result0 = parse_lowerCaseLetter();
2440 if (result0 === null) {
2441 result0 = parse_upperCaseLetter();
2442 }
2443 return result0;
2444 }
2445
2446 function parse_lowerCaseLetter() {
2447 var result0;
2448
2449 if (/^[a-z]/.test(input.charAt(pos))) {
2450 result0 = input.charAt(pos);
2451 pos++;
2452 } else {
2453 result0 = null;
2454 if (reportFailures === 0) {
2455 matchFailed("[a-z]");
2456 }
2457 }
2458 return result0;
2459 }
2460
2461 function parse_upperCaseLetter() {
2462 var result0;
2463
2464 if (/^[A-Z]/.test(input.charAt(pos))) {
2465 result0 = input.charAt(pos);
2466 pos++;
2467 } else {
2468 result0 = null;
2469 if (reportFailures === 0) {
2470 matchFailed("[A-Z]");
2471 }
2472 }
2473 return result0;
2474 }
2475
2476 function parse___() {
2477 var result0, result1;
2478
2479 result0 = [];
2480 result1 = parse_whitespace();
2481 if (result1 === null) {
2482 result1 = parse_eol();
2483 if (result1 === null) {
2484 result1 = parse_comment();
2485 }
2486 }
2487 while (result1 !== null) {
2488 result0.push(result1);
2489 result1 = parse_whitespace();
2490 if (result1 === null) {
2491 result1 = parse_eol();
2492 if (result1 === null) {
2493 result1 = parse_comment();
2494 }
2495 }
2496 }
2497 return result0;
2498 }
2499
2500 function parse_comment() {
2501 var result0;
2502
2503 reportFailures++;
2504 result0 = parse_singleLineComment();
2505 if (result0 === null) {
2506 result0 = parse_multiLineComment();
2507 }
2508 reportFailures--;
2509 if (reportFailures === 0 && result0 === null) {
2510 matchFailed("comment");
2511 }
2512 return result0;
2513 }
2514
2515 function parse_singleLineComment() {
2516 var result0, result1, result2, result3;
2517 var pos0, pos1, pos2;
2518
2519 pos0 = pos;
2520 if (input.substr(pos, 2) === "//") {
2521 result0 = "//";
2522 pos += 2;
2523 } else {
2524 result0 = null;
2525 if (reportFailures === 0) {
2526 matchFailed("\"//\"");
2527 }
2528 }
2529 if (result0 !== null) {
2530 result1 = [];
2531 pos1 = pos;
2532 pos2 = pos;
2533 reportFailures++;
2534 result2 = parse_eolChar();
2535 reportFailures--;
2536 if (result2 === null) {
2537 result2 = "";
2538 } else {
2539 result2 = null;
2540 pos = pos2;
2541 }
2542 if (result2 !== null) {
2543 if (input.length > pos) {
2544 result3 = input.charAt(pos);
2545 pos++;
2546 } else {
2547 result3 = null;
2548 if (reportFailures === 0) {
2549 matchFailed("any character");
2550 }
2551 }
2552 if (result3 !== null) {
2553 result2 = [result2, result3];
2554 } else {
2555 result2 = null;
2556 pos = pos1;
2557 }
2558 } else {
2559 result2 = null;
2560 pos = pos1;
2561 }
2562 while (result2 !== null) {
2563 result1.push(result2);
2564 pos1 = pos;
2565 pos2 = pos;
2566 reportFailures++;
2567 result2 = parse_eolChar();
2568 reportFailures--;
2569 if (result2 === null) {
2570 result2 = "";
2571 } else {
2572 result2 = null;
2573 pos = pos2;
2574 }
2575 if (result2 !== null) {
2576 if (input.length > pos) {
2577 result3 = input.charAt(pos);
2578 pos++;
2579 } else {
2580 result3 = null;
2581 if (reportFailures === 0) {
2582 matchFailed("any character");
2583 }
2584 }
2585 if (result3 !== null) {
2586 result2 = [result2, result3];
2587 } else {
2588 result2 = null;
2589 pos = pos1;
2590 }
2591 } else {
2592 result2 = null;
2593 pos = pos1;
2594 }
2595 }
2596 if (result1 !== null) {
2597 result0 = [result0, result1];
2598 } else {
2599 result0 = null;
2600 pos = pos0;
2601 }
2602 } else {
2603 result0 = null;
2604 pos = pos0;
2605 }
2606 return result0;
2607 }
2608
2609 function parse_multiLineComment() {
2610 var result0, result1, result2, result3;
2611 var pos0, pos1, pos2;
2612
2613 pos0 = pos;
2614 if (input.substr(pos, 2) === "/*") {
2615 result0 = "/*";
2616 pos += 2;
2617 } else {
2618 result0 = null;
2619 if (reportFailures === 0) {
2620 matchFailed("\"/*\"");
2621 }
2622 }
2623 if (result0 !== null) {
2624 result1 = [];
2625 pos1 = pos;
2626 pos2 = pos;
2627 reportFailures++;
2628 if (input.substr(pos, 2) === "*/") {
2629 result2 = "*/";
2630 pos += 2;
2631 } else {
2632 result2 = null;
2633 if (reportFailures === 0) {
2634 matchFailed("\"*/\"");
2635 }
2636 }
2637 reportFailures--;
2638 if (result2 === null) {
2639 result2 = "";
2640 } else {
2641 result2 = null;
2642 pos = pos2;
2643 }
2644 if (result2 !== null) {
2645 if (input.length > pos) {
2646 result3 = input.charAt(pos);
2647 pos++;
2648 } else {
2649 result3 = null;
2650 if (reportFailures === 0) {
2651 matchFailed("any character");
2652 }
2653 }
2654 if (result3 !== null) {
2655 result2 = [result2, result3];
2656 } else {
2657 result2 = null;
2658 pos = pos1;
2659 }
2660 } else {
2661 result2 = null;
2662 pos = pos1;
2663 }
2664 while (result2 !== null) {
2665 result1.push(result2);
2666 pos1 = pos;
2667 pos2 = pos;
2668 reportFailures++;
2669 if (input.substr(pos, 2) === "*/") {
2670 result2 = "*/";
2671 pos += 2;
2672 } else {
2673 result2 = null;
2674 if (reportFailures === 0) {
2675 matchFailed("\"*/\"");
2676 }
2677 }
2678 reportFailures--;
2679 if (result2 === null) {
2680 result2 = "";
2681 } else {
2682 result2 = null;
2683 pos = pos2;
2684 }
2685 if (result2 !== null) {
2686 if (input.length > pos) {
2687 result3 = input.charAt(pos);
2688 pos++;
2689 } else {
2690 result3 = null;
2691 if (reportFailures === 0) {
2692 matchFailed("any character");
2693 }
2694 }
2695 if (result3 !== null) {
2696 result2 = [result2, result3];
2697 } else {
2698 result2 = null;
2699 pos = pos1;
2700 }
2701 } else {
2702 result2 = null;
2703 pos = pos1;
2704 }
2705 }
2706 if (result1 !== null) {
2707 if (input.substr(pos, 2) === "*/") {
2708 result2 = "*/";
2709 pos += 2;
2710 } else {
2711 result2 = null;
2712 if (reportFailures === 0) {
2713 matchFailed("\"*/\"");
2714 }
2715 }
2716 if (result2 !== null) {
2717 result0 = [result0, result1, result2];
2718 } else {
2719 result0 = null;
2720 pos = pos0;
2721 }
2722 } else {
2723 result0 = null;
2724 pos = pos0;
2725 }
2726 } else {
2727 result0 = null;
2728 pos = pos0;
2729 }
2730 return result0;
2731 }
2732
2733 function parse_eol() {
2734 var result0;
2735
2736 reportFailures++;
2737 if (input.charCodeAt(pos) === 10) {
2738 result0 = "\n";
2739 pos++;
2740 } else {
2741 result0 = null;
2742 if (reportFailures === 0) {
2743 matchFailed("\"\\n\"");
2744 }
2745 }
2746 if (result0 === null) {
2747 if (input.substr(pos, 2) === "\r\n") {
2748 result0 = "\r\n";
2749 pos += 2;
2750 } else {
2751 result0 = null;
2752 if (reportFailures === 0) {
2753 matchFailed("\"\\r\\n\"");
2754 }
2755 }
2756 if (result0 === null) {
2757 if (input.charCodeAt(pos) === 13) {
2758 result0 = "\r";
2759 pos++;
2760 } else {
2761 result0 = null;
2762 if (reportFailures === 0) {
2763 matchFailed("\"\\r\"");
2764 }
2765 }
2766 if (result0 === null) {
2767 if (input.charCodeAt(pos) === 8232) {
2768 result0 = "\u2028";
2769 pos++;
2770 } else {
2771 result0 = null;
2772 if (reportFailures === 0) {
2773 matchFailed("\"\\u2028\"");
2774 }
2775 }
2776 if (result0 === null) {
2777 if (input.charCodeAt(pos) === 8233) {
2778 result0 = "\u2029";
2779 pos++;
2780 } else {
2781 result0 = null;
2782 if (reportFailures === 0) {
2783 matchFailed("\"\\u2029\"");
2784 }
2785 }
2786 }
2787 }
2788 }
2789 }
2790 reportFailures--;
2791 if (reportFailures === 0 && result0 === null) {
2792 matchFailed("end of line");
2793 }
2794 return result0;
2795 }
2796
2797 function parse_eolChar() {
2798 var result0;
2799
2800 if (/^[\n\r\u2028\u2029]/.test(input.charAt(pos))) {
2801 result0 = input.charAt(pos);
2802 pos++;
2803 } else {
2804 result0 = null;
2805 if (reportFailures === 0) {
2806 matchFailed("[\\n\\r\\u2028\\u2029]");
2807 }
2808 }
2809 return result0;
2810 }
2811
2812 function parse_whitespace() {
2813 var result0;
2814
2815 reportFailures++;
2816 if (/^[ \t\x0B\f\xA0\uFEFF\u1680\u180E\u2000-\u200A\u202F\u205F\u3000]/.test(input.charAt(pos))) {
2817 result0 = input.charAt(pos);
2818 pos++;
2819 } else {
2820 result0 = null;
2821 if (reportFailures === 0) {
2822 matchFailed("[ \\t\\x0B\\f\\xA0\\uFEFF\\u1680\\u180E\\u2000-\\u200A\\u202F\\u205F\\u3000]");
2823 }
2824 }
2825 reportFailures--;
2826 if (reportFailures === 0 && result0 === null) {
2827 matchFailed("whitespace");
2828 }
2829 return result0;
2830 }
2831
2832
2833 function cleanupExpected(expected) {
2834 expected.sort();
2835
2836 var lastExpected = null;
2837 var cleanExpected = [];
2838 for (var i = 0; i < expected.length; i++) {
2839 if (expected[i] !== lastExpected) {
2840 cleanExpected.push(expected[i]);
2841 lastExpected = expected[i];
2842 }
2843 }
2844 return cleanExpected;
2845 }
2846
2847 function computeErrorPosition() {
2848 /*
2849 * The first idea was to use |String.split| to break the input up to the
2850 * error position along newlines and derive the line and column from
2851 * there. However IE's |split| implementation is so broken that it was
2852 * enough to prevent it.
2853 */
2854
2855 var line = 1;
2856 var column = 1;
2857 var seenCR = false;
2858
2859 for (var i = 0; i < Math.max(pos, rightmostFailuresPos); i++) {
2860 var ch = input.charAt(i);
2861 if (ch === "\n") {
2862 if (!seenCR) { line++; }
2863 column = 1;
2864 seenCR = false;
2865 } else if (ch === "\r" || ch === "\u2028" || ch === "\u2029") {
2866 line++;
2867 column = 1;
2868 seenCR = true;
2869 } else {
2870 column++;
2871 seenCR = false;
2872 }
2873 }
2874
2875 return { line: line, column: column };
2876 }
2877
2878
2879 var result = parseFunctions[startRule]();
2880
2881 /*
2882 * The parser is now in one of the following three states:
2883 *
2884 * 1. The parser successfully parsed the whole input.
2885 *
2886 * - |result !== null|
2887 * - |pos === input.length|
2888 * - |rightmostFailuresExpected| may or may not contain something
2889 *
2890 * 2. The parser successfully parsed only a part of the input.
2891 *
2892 * - |result !== null|
2893 * - |pos < input.length|
2894 * - |rightmostFailuresExpected| may or may not contain something
2895 *
2896 * 3. The parser did not successfully parse any part of the input.
2897 *
2898 * - |result === null|
2899 * - |pos === 0|
2900 * - |rightmostFailuresExpected| contains at least one failure
2901 *
2902 * All code following this comment (including called functions) must
2903 * handle these states.
2904 */
2905 if (result === null || pos !== input.length) {
2906 var offset = Math.max(pos, rightmostFailuresPos);
2907 var found = offset < input.length ? input.charAt(offset) : null;
2908 var errorPosition = computeErrorPosition();
2909
2910 throw new this.SyntaxError(
2911 cleanupExpected(rightmostFailuresExpected),
2912 found,
2913 offset,
2914 errorPosition.line,
2915 errorPosition.column
2916 );
2917 }
2918
2919 return result;
2920 },
2921
2922 /* Returns the parser source code. */
2923 toSource: function() { return this._source; }
2924 };
2925
2926 /* Thrown when a parser encounters a syntax error. */
2927
2928 result.SyntaxError = function(expected, found, offset, line, column) {
2929 function buildMessage(expected, found) {
2930 var expectedHumanized, foundHumanized;
2931
2932 switch (expected.length) {
2933 case 0:
2934 expectedHumanized = "end of input";
2935 break;
2936 case 1:
2937 expectedHumanized = expected[0];
2938 break;
2939 default:
2940 expectedHumanized = expected.slice(0, expected.length - 1).join(", ")
2941 + " or "
2942 + expected[expected.length - 1];
2943 }
2944
2945 foundHumanized = found ? quote(found) : "end of input";
2946
2947 return "Expected " + expectedHumanized + " but " + foundHumanized + " found.";
2948 }
2949
2950 this.name = "SyntaxError";
2951 this.expected = expected;
2952 this.found = found;
2953 this.message = buildMessage(expected, found);
2954 this.offset = offset;
2955 this.line = line;
2956 this.column = column;
2957 };
2958
2959 result.SyntaxError.prototype = Error.prototype;
2960
2961 return result;
2962 })();
0 grammar
1 = __ initializer:initializer? rules:rule+ {
0 /*
1 * PEG.js Grammar
2 * ==============
3 *
4 * PEG.js grammar syntax is designed to be simple, expressive, and similar to
5 * JavaScript where possible. This means that many rules, especially in the
6 * lexical part, are based on the grammar from ECMA-262, 5.1 Edition [1]. Some
7 * are directly taken or adapted from the JavaScript example grammar (see
8 * examples/javascript.pegjs).
9 *
10 * Limitations:
11 *
12 * * Non-BMP characters are completely ignored to avoid surrogate pair
13 * handling.
14 *
15 * * One can create identifiers containing illegal characters using Unicode
16 * escape sequences. For example, "abcd\u0020efgh" is not a valid
17 * identifier, but it is accepted by the parser.
18 *
19 * Both limitations could be resolved, but the costs would likely outweigh
20 * the benefits.
21 *
22 * [1] http://www.ecma-international.org/publications/standards/Ecma-262.htm
23 */
24
25 {
26 var OPS_TO_PREFIXED_TYPES = {
27 "$": "text",
28 "&": "simple_and",
29 "!": "simple_not"
30 };
31
32 var OPS_TO_SUFFIXED_TYPES = {
33 "?": "optional",
34 "*": "zero_or_more",
35 "+": "one_or_more"
36 };
37
38 var OPS_TO_SEMANTIC_PREDICATE_TYPES = {
39 "&": "semantic_and",
40 "!": "semantic_not"
41 };
42
43 function filterEmptyStrings(array) {
44 var result = [], i;
45
46 for (i = 0; i < array.length; i++) {
47 if (array[i] !== "") {
48 result.push(array[i]);
49 }
50 }
51
52 return result;
53 }
54
55 function extractOptional(optional, index) {
56 return optional ? optional[index] : null;
57 }
58
59 function extractList(list, index) {
60 var result = new Array(list.length), i;
61
62 for (i = 0; i < list.length; i++) {
63 result[i] = list[i][index];
64 }
65
66 return result;
67 }
68
69 function buildList(head, tail, index) {
70 return [head].concat(extractList(tail, index));
71 }
72 }
73
74 /* ---- Syntactic Grammar ----- */
75
76 Grammar
77 = __ initializer:(Initializer __)? rules:(Rule __)+ {
278 return {
379 type: "grammar",
4 initializer: initializer !== "" ? initializer : null,
5 rules: rules,
6 startRule: rules[0].name
7 };
8 }
9
10 initializer
11 = code:action semicolon? {
12 return {
13 type: "initializer",
14 code: code
15 };
16 }
17
18 rule
19 = name:identifier displayName:string? equals expression:expression semicolon? {
80 initializer: extractOptional(initializer, 0),
81 rules: extractList(rules, 0),
82 location: location()
83 };
84 }
85
86 Initializer
87 = code:CodeBlock EOS {
88 return { type: "initializer", code: code, location: location() };
89 }
90
91 Rule
92 = name:IdentifierName __
93 displayName:(StringLiteral __)?
94 "=" __
95 expression:Expression EOS
96 {
2097 return {
2198 type: "rule",
2299 name: name,
23 displayName: displayName !== "" ? displayName : null,
24 expression: expression
25 };
26 }
27
28 expression
29 = choice
30
31 choice
32 = head:sequence tail:(slash sequence)* {
33 if (tail.length > 0) {
34 var alternatives = [head].concat(map(
35 tail,
36 function(element) { return element[1]; }
37 ));
38 return {
39 type: "choice",
40 alternatives: alternatives
41 };
42 } else {
43 return head;
44 }
45 }
46
47 sequence
48 = elements:labeled* code:action {
49 var expression = elements.length !== 1
100 expression: displayName !== null
101 ? {
102 type: "named",
103 name: displayName[0],
104 expression: expression,
105 location: location()
106 }
107 : expression,
108 location: location()
109 };
110 }
111
112 Expression
113 = ChoiceExpression
114
115 ChoiceExpression
116 = head:ActionExpression tail:(__ "/" __ ActionExpression)* {
117 return tail.length > 0
118 ? {
119 type: "choice",
120 alternatives: buildList(head, tail, 3),
121 location: location()
122 }
123 : head;
124 }
125
126 ActionExpression
127 = expression:SequenceExpression code:(__ CodeBlock)? {
128 return code !== null
129 ? {
130 type: "action",
131 expression: expression,
132 code: code[1],
133 location: location()
134 }
135 : expression;
136 }
137
138 SequenceExpression
139 = head:LabeledExpression tail:(__ LabeledExpression)* {
140 return tail.length > 0
50141 ? {
51142 type: "sequence",
52 elements: elements
143 elements: buildList(head, tail, 1),
144 location: location()
53145 }
54 : elements[0];
55 return {
56 type: "action",
57 expression: expression,
58 code: code
59 };
60 }
61 / elements:labeled* {
62 return elements.length !== 1
63 ? {
64 type: "sequence",
65 elements: elements
66 }
67 : elements[0];
68 }
69
70 labeled
71 = label:identifier colon expression:prefixed {
146 : head;
147 }
148
149 LabeledExpression
150 = label:Identifier __ ":" __ expression:PrefixedExpression {
72151 return {
73152 type: "labeled",
74153 label: label,
75 expression: expression
76 };
77 }
78 / prefixed
79
80 prefixed
81 = and code:action {
82 return {
83 type: "semantic_and",
84 code: code
85 };
86 }
87 / and expression:suffixed {
88 return {
89 type: "simple_and",
90 expression: expression
91 };
92 }
93 / not code:action {
94 return {
95 type: "semantic_not",
96 code: code
97 };
98 }
99 / not expression:suffixed {
100 return {
101 type: "simple_not",
102 expression: expression
103 };
104 }
105 / suffixed
106
107 suffixed
108 = expression:primary question {
109 return {
110 type: "optional",
111 expression: expression
112 };
113 }
114 / expression:primary star {
115 return {
116 type: "zero_or_more",
117 expression: expression
118 };
119 }
120 / expression:primary plus {
121 return {
122 type: "one_or_more",
123 expression: expression
124 };
125 }
126 / primary
127
128 primary
129 = name:identifier !(string? equals) {
130 return {
131 type: "rule_ref",
132 name: name
133 };
134 }
135 / literal
136 / dot { return { type: "any" }; }
137 / class
138 / lparen expression:expression rparen { return expression; }
139
140 /* "Lexical" elements */
141
142 action "action"
143 = braced:braced __ { return braced.substr(1, braced.length - 2); }
144
145 braced
146 = "{" parts:(braced / nonBraceCharacter)* "}" {
147 return "{" + parts.join("") + "}";
148 }
149
150 nonBraceCharacters
151 = chars:nonBraceCharacter+ { return chars.join(""); }
152
153 nonBraceCharacter
154 = [^{}]
155
156 equals = "=" __ { return "="; }
157 colon = ":" __ { return ":"; }
158 semicolon = ";" __ { return ";"; }
159 slash = "/" __ { return "/"; }
160 and = "&" __ { return "&"; }
161 not = "!" __ { return "!"; }
162 question = "?" __ { return "?"; }
163 star = "*" __ { return "*"; }
164 plus = "+" __ { return "+"; }
165 lparen = "(" __ { return "("; }
166 rparen = ")" __ { return ")"; }
167 dot = "." __ { return "."; }
168
169 /*
170 * Modelled after ECMA-262, 5th ed., 7.6, but much simplified:
171 *
172 * * no Unicode escape sequences
173 *
174 * * "Unicode combining marks" and "Unicode connection punctuation" can't be
175 * part of the identifier
176 *
177 * * only [a-zA-Z] is considered a "Unicode letter"
178 *
179 * * only [0-9] is considered a "Unicode digit"
180 *
181 * The simplifications were made just to make the implementation little bit
182 * easier, there is no "philosophical" reason behind them.
183 */
184 identifier "identifier"
185 = head:(letter / "_" / "$") tail:(letter / digit / "_" / "$")* __ {
186 return head + tail.join("");
187 }
188
189 /*
190 * Modelled after ECMA-262, 5th ed., 7.8.4. (syntax & semantics, rules only
191 * vaguely).
192 */
193 literal "literal"
194 = value:(doubleQuotedString / singleQuotedString) flags:"i"? __ {
195 return {
196 type: "literal",
197 value: value,
198 ignoreCase: flags === "i"
199 };
200 }
201
202 string "string"
203 = string:(doubleQuotedString / singleQuotedString) __ { return string; }
204
205 doubleQuotedString
206 = '"' chars:doubleQuotedCharacter* '"' { return chars.join(""); }
207
208 doubleQuotedCharacter
209 = simpleDoubleQuotedCharacter
210 / simpleEscapeSequence
211 / zeroEscapeSequence
212 / hexEscapeSequence
213 / unicodeEscapeSequence
214 / eolEscapeSequence
215
216 simpleDoubleQuotedCharacter
217 = !('"' / "\\" / eolChar) char_:. { return char_; }
218
219 singleQuotedString
220 = "'" chars:singleQuotedCharacter* "'" { return chars.join(""); }
221
222 singleQuotedCharacter
223 = simpleSingleQuotedCharacter
224 / simpleEscapeSequence
225 / zeroEscapeSequence
226 / hexEscapeSequence
227 / unicodeEscapeSequence
228 / eolEscapeSequence
229
230 simpleSingleQuotedCharacter
231 = !("'" / "\\" / eolChar) char_:. { return char_; }
232
233 class "character class"
234 = "[" inverted:"^"? parts:(classCharacterRange / classCharacter)* "]" flags:"i"? __ {
235 var partsConverted = map(parts, function(part) { return part.data; });
236 var rawText = "["
237 + inverted
238 + map(parts, function(part) { return part.rawText; }).join("")
239 + "]"
240 + flags;
241
242 return {
243 type: "class",
244 inverted: inverted === "^",
245 ignoreCase: flags === "i",
246 parts: partsConverted,
247 // FIXME: Get the raw text from the input directly.
248 rawText: rawText
249 };
250 }
251
252 classCharacterRange
253 = begin:classCharacter "-" end:classCharacter {
254 if (begin.data.charCodeAt(0) > end.data.charCodeAt(0)) {
255 throw new this.SyntaxError(
256 "Invalid character range: " + begin.rawText + "-" + end.rawText + "."
257 );
258 }
259
260 return {
261 data: [begin.data, end.data],
262 // FIXME: Get the raw text from the input directly.
263 rawText: begin.rawText + "-" + end.rawText
264 };
265 }
266
267 classCharacter
268 = char_:bracketDelimitedCharacter {
269 return {
270 data: char_,
271 // FIXME: Get the raw text from the input directly.
272 rawText: quoteForRegexpClass(char_)
273 };
274 }
275
276 bracketDelimitedCharacter
277 = simpleBracketDelimitedCharacter
278 / simpleEscapeSequence
279 / zeroEscapeSequence
280 / hexEscapeSequence
281 / unicodeEscapeSequence
282 / eolEscapeSequence
283
284 simpleBracketDelimitedCharacter
285 = !("]" / "\\" / eolChar) char_:. { return char_; }
286
287 simpleEscapeSequence
288 = "\\" !(digit / "x" / "u" / eolChar) char_:. {
289 return char_
290 .replace("b", "\b")
291 .replace("f", "\f")
292 .replace("n", "\n")
293 .replace("r", "\r")
294 .replace("t", "\t")
295 .replace("v", "\x0B"); // IE does not recognize "\v".
296 }
297
298 zeroEscapeSequence
299 = "\\0" !digit { return "\x00"; }
300
301 hexEscapeSequence
302 = "\\x" h1:hexDigit h2:hexDigit {
303 return String.fromCharCode(parseInt(h1 + h2, 16));
304 }
305
306 unicodeEscapeSequence
307 = "\\u" h1:hexDigit h2:hexDigit h3:hexDigit h4:hexDigit {
308 return String.fromCharCode(parseInt(h1 + h2 + h3 + h4, 16));
309 }
310
311 eolEscapeSequence
312 = "\\" eol:eol { return eol; }
313
314 digit
315 = [0-9]
316
317 hexDigit
318 = [0-9a-fA-F]
319
320 letter
321 = lowerCaseLetter
322 / upperCaseLetter
323
324 lowerCaseLetter
325 = [a-z]
326
327 upperCaseLetter
328 = [A-Z]
329
330 __ = (whitespace / eol / comment)*
331
332 /* Modelled after ECMA-262, 5th ed., 7.4. */
333 comment "comment"
334 = singleLineComment
335 / multiLineComment
336
337 singleLineComment
338 = "//" (!eolChar .)*
339
340 multiLineComment
341 = "/*" (!"*/" .)* "*/"
342
343 /* Modelled after ECMA-262, 5th ed., 7.3. */
344 eol "end of line"
154 expression: expression,
155 location: location()
156 };
157 }
158 / PrefixedExpression
159
160 PrefixedExpression
161 = operator:PrefixedOperator __ expression:SuffixedExpression {
162 return {
163 type: OPS_TO_PREFIXED_TYPES[operator],
164 expression: expression,
165 location: location()
166 };
167 }
168 / SuffixedExpression
169
170 PrefixedOperator
171 = "$"
172 / "&"
173 / "!"
174
175 SuffixedExpression
176 = expression:PrimaryExpression __ operator:SuffixedOperator {
177 return {
178 type: OPS_TO_SUFFIXED_TYPES[operator],
179 expression: expression,
180 location: location()
181 };
182 }
183 / PrimaryExpression
184
185 SuffixedOperator
186 = "?"
187 / "*"
188 / "+"
189
190 PrimaryExpression
191 = LiteralMatcher
192 / CharacterClassMatcher
193 / AnyMatcher
194 / RuleReferenceExpression
195 / SemanticPredicateExpression
196 / "(" __ expression:Expression __ ")" {
197 /*
198 * The purpose of the "group" AST node is just to isolate label scope. We
199 * don't need to put it around nodes that can't contain any labels or
200 * nodes that already isolate label scope themselves. This leaves us with
201 * "labeled" and "sequence".
202 */
203 return expression.type === 'labeled' || expression.type === 'sequence'
204 ? { type: "group", expression: expression }
205 : expression;
206 }
207
208 RuleReferenceExpression
209 = name:IdentifierName !(__ (StringLiteral __)? "=") {
210 return { type: "rule_ref", name: name, location: location() };
211 }
212
213 SemanticPredicateExpression
214 = operator:SemanticPredicateOperator __ code:CodeBlock {
215 return {
216 type: OPS_TO_SEMANTIC_PREDICATE_TYPES[operator],
217 code: code,
218 location: location()
219 };
220 }
221
222 SemanticPredicateOperator
223 = "&"
224 / "!"
225
226 /* ---- Lexical Grammar ----- */
227
228 SourceCharacter
229 = .
230
231 WhiteSpace "whitespace"
232 = "\t"
233 / "\v"
234 / "\f"
235 / " "
236 / "\u00A0"
237 / "\uFEFF"
238 / Zs
239
240 LineTerminator
241 = [\n\r\u2028\u2029]
242
243 LineTerminatorSequence "end of line"
345244 = "\n"
346245 / "\r\n"
347246 / "\r"
348247 / "\u2028"
349248 / "\u2029"
350249
351 eolChar
352 = [\n\r\u2028\u2029]
353
354 /* Modelled after ECMA-262, 5th ed., 7.2. */
355 whitespace "whitespace"
356 = [ \t\v\f\u00A0\uFEFF\u1680\u180E\u2000-\u200A\u202F\u205F\u3000]
250 Comment "comment"
251 = MultiLineComment
252 / SingleLineComment
253
254 MultiLineComment
255 = "/*" (!"*/" SourceCharacter)* "*/"
256
257 MultiLineCommentNoLineTerminator
258 = "/*" (!("*/" / LineTerminator) SourceCharacter)* "*/"
259
260 SingleLineComment
261 = "//" (!LineTerminator SourceCharacter)*
262
263 Identifier
264 = !ReservedWord name:IdentifierName { return name; }
265
266 IdentifierName "identifier"
267 = head:IdentifierStart tail:IdentifierPart* { return head + tail.join(""); }
268
269 IdentifierStart
270 = UnicodeLetter
271 / "$"
272 / "_"
273 / "\\" sequence:UnicodeEscapeSequence { return sequence; }
274
275 IdentifierPart
276 = IdentifierStart
277 / UnicodeCombiningMark
278 / UnicodeDigit
279 / UnicodeConnectorPunctuation
280 / "\u200C"
281 / "\u200D"
282
283 UnicodeLetter
284 = Lu
285 / Ll
286 / Lt
287 / Lm
288 / Lo
289 / Nl
290
291 UnicodeCombiningMark
292 = Mn
293 / Mc
294
295 UnicodeDigit
296 = Nd
297
298 UnicodeConnectorPunctuation
299 = Pc
300
301 ReservedWord
302 = Keyword
303 / FutureReservedWord
304 / NullLiteral
305 / BooleanLiteral
306
307 Keyword
308 = BreakToken
309 / CaseToken
310 / CatchToken
311 / ContinueToken
312 / DebuggerToken
313 / DefaultToken
314 / DeleteToken
315 / DoToken
316 / ElseToken
317 / FinallyToken
318 / ForToken
319 / FunctionToken
320 / IfToken
321 / InstanceofToken
322 / InToken
323 / NewToken
324 / ReturnToken
325 / SwitchToken
326 / ThisToken
327 / ThrowToken
328 / TryToken
329 / TypeofToken
330 / VarToken
331 / VoidToken
332 / WhileToken
333 / WithToken
334
335 FutureReservedWord
336 = ClassToken
337 / ConstToken
338 / EnumToken
339 / ExportToken
340 / ExtendsToken
341 / ImportToken
342 / SuperToken
343
344 NullLiteral
345 = NullToken
346
347 BooleanLiteral
348 = TrueToken
349 / FalseToken
350
351 LiteralMatcher "literal"
352 = value:StringLiteral ignoreCase:"i"? {
353 return {
354 type: "literal",
355 value: value,
356 ignoreCase: ignoreCase !== null,
357 location: location()
358 };
359 }
360
361 StringLiteral "string"
362 = '"' chars:DoubleStringCharacter* '"' { return chars.join(""); }
363 / "'" chars:SingleStringCharacter* "'" { return chars.join(""); }
364
365 DoubleStringCharacter
366 = !('"' / "\\" / LineTerminator) SourceCharacter { return text(); }
367 / "\\" sequence:EscapeSequence { return sequence; }
368 / LineContinuation
369
370 SingleStringCharacter
371 = !("'" / "\\" / LineTerminator) SourceCharacter { return text(); }
372 / "\\" sequence:EscapeSequence { return sequence; }
373 / LineContinuation
374
375 CharacterClassMatcher "character class"
376 = "["
377 inverted:"^"?
378 parts:(ClassCharacterRange / ClassCharacter)*
379 "]"
380 ignoreCase:"i"?
381 {
382 return {
383 type: "class",
384 parts: filterEmptyStrings(parts),
385 inverted: inverted !== null,
386 ignoreCase: ignoreCase !== null,
387 location: location()
388 };
389 }
390
391 ClassCharacterRange
392 = begin:ClassCharacter "-" end:ClassCharacter {
393 if (begin.charCodeAt(0) > end.charCodeAt(0)) {
394 error(
395 "Invalid character range: " + text() + "."
396 );
397 }
398
399 return [begin, end];
400 }
401
402 ClassCharacter
403 = !("]" / "\\" / LineTerminator) SourceCharacter { return text(); }
404 / "\\" sequence:EscapeSequence { return sequence; }
405 / LineContinuation
406
407 LineContinuation
408 = "\\" LineTerminatorSequence { return ""; }
409
410 EscapeSequence
411 = CharacterEscapeSequence
412 / "0" !DecimalDigit { return "\0"; }
413 / HexEscapeSequence
414 / UnicodeEscapeSequence
415
416 CharacterEscapeSequence
417 = SingleEscapeCharacter
418 / NonEscapeCharacter
419
420 SingleEscapeCharacter
421 = "'"
422 / '"'
423 / "\\"
424 / "b" { return "\b"; }
425 / "f" { return "\f"; }
426 / "n" { return "\n"; }
427 / "r" { return "\r"; }
428 / "t" { return "\t"; }
429 / "v" { return "\x0B"; } // IE does not recognize "\v".
430
431 NonEscapeCharacter
432 = !(EscapeCharacter / LineTerminator) SourceCharacter { return text(); }
433
434 EscapeCharacter
435 = SingleEscapeCharacter
436 / DecimalDigit
437 / "x"
438 / "u"
439
440 HexEscapeSequence
441 = "x" digits:$(HexDigit HexDigit) {
442 return String.fromCharCode(parseInt(digits, 16));
443 }
444
445 UnicodeEscapeSequence
446 = "u" digits:$(HexDigit HexDigit HexDigit HexDigit) {
447 return String.fromCharCode(parseInt(digits, 16));
448 }
449
450 DecimalDigit
451 = [0-9]
452
453 HexDigit
454 = [0-9a-f]i
455
456 AnyMatcher
457 = "." { return { type: "any", location: location() }; }
458
459 CodeBlock "code block"
460 = "{" code:Code "}" { return code; }
461
462 Code
463 = $((![{}] SourceCharacter)+ / "{" Code "}")*
464
465 /*
466 * Unicode Character Categories
467 *
468 * Extracted from the following Unicode Character Database file:
469 *
470 * http://www.unicode.org/Public/8.0.0/ucd/extracted/DerivedGeneralCategory.txt
471 *
472 * Unix magic used:
473 *
474 * grep "; $CATEGORY" DerivedGeneralCategory.txt | # Filter characters
475 * cut -f1 -d " " | # Extract code points
476 * grep -v '[0-9a-fA-F]\{5\}' | # Exclude non-BMP characters
477 * sed -e 's/\.\./-/' | # Adjust formatting
478 * sed -e 's/\([0-9a-fA-F]\{4\}\)/\\u\1/g' | # Adjust formatting
479 * tr -d '\n' # Join lines
480 *
481 * ECMA-262 allows using Unicode 3.0 or later, version 8.0.0 was the latest one
482 * at the time of writing.
483 *
484 * Non-BMP characters are completely ignored to avoid surrogate pair handling
485 * (detecting surrogate pairs isn't possible with a simple character class and
486 * other methods would degrade performance). I don't consider it a big deal as
487 * even parsers in JavaScript engines of common browsers seem to ignore them.
488 */
489
490 // Letter, Lowercase
491 Ll = [\u0061-\u007A\u00B5\u00DF-\u00F6\u00F8-\u00FF\u0101\u0103\u0105\u0107\u0109\u010B\u010D\u010F\u0111\u0113\u0115\u0117\u0119\u011B\u011D\u011F\u0121\u0123\u0125\u0127\u0129\u012B\u012D\u012F\u0131\u0133\u0135\u0137-\u0138\u013A\u013C\u013E\u0140\u0142\u0144\u0146\u0148-\u0149\u014B\u014D\u014F\u0151\u0153\u0155\u0157\u0159\u015B\u015D\u015F\u0161\u0163\u0165\u0167\u0169\u016B\u016D\u016F\u0171\u0173\u0175\u0177\u017A\u017C\u017E-\u0180\u0183\u0185\u0188\u018C-\u018D\u0192\u0195\u0199-\u019B\u019E\u01A1\u01A3\u01A5\u01A8\u01AA-\u01AB\u01AD\u01B0\u01B4\u01B6\u01B9-\u01BA\u01BD-\u01BF\u01C6\u01C9\u01CC\u01CE\u01D0\u01D2\u01D4\u01D6\u01D8\u01DA\u01DC-\u01DD\u01DF\u01E1\u01E3\u01E5\u01E7\u01E9\u01EB\u01ED\u01EF-\u01F0\u01F3\u01F5\u01F9\u01FB\u01FD\u01FF\u0201\u0203\u0205\u0207\u0209\u020B\u020D\u020F\u0211\u0213\u0215\u0217\u0219\u021B\u021D\u021F\u0221\u0223\u0225\u0227\u0229\u022B\u022D\u022F\u0231\u0233-\u0239\u023C\u023F-\u0240\u0242\u0247\u0249\u024B\u024D\u024F-\u0293\u0295-\u02AF\u0371\u0373\u0377\u037B-\u037D\u0390\u03AC-\u03CE\u03D0-\u03D1\u03D5-\u03D7\u03D9\u03DB\u03DD\u03DF\u03E1\u03E3\u03E5\u03E7\u03E9\u03EB\u03ED\u03EF-\u03F3\u03F5\u03F8\u03FB-\u03FC\u0430-\u045F\u0461\u0463\u0465\u0467\u0469\u046B\u046D\u046F\u0471\u0473\u0475\u0477\u0479\u047B\u047D\u047F\u0481\u048B\u048D\u048F\u0491\u0493\u0495\u0497\u0499\u049B\u049D\u049F\u04A1\u04A3\u04A5\u04A7\u04A9\u04AB\u04AD\u04AF\u04B1\u04B3\u04B5\u04B7\u04B9\u04BB\u04BD\u04BF\u04C2\u04C4\u04C6\u04C8\u04CA\u04CC\u04CE-\u04CF\u04D1\u04D3\u04D5\u04D7\u04D9\u04DB\u04DD\u04DF\u04E1\u04E3\u04E5\u04E7\u04E9\u04EB\u04ED\u04EF\u04F1\u04F3\u04F5\u04F7\u04F9\u04FB\u04FD\u04FF\u0501\u0503\u0505\u0507\u0509\u050B\u050D\u050F\u0511\u0513\u0515\u0517\u0519\u051B\u051D\u051F\u0521\u0523\u0525\u0527\u0529\u052B\u052D\u052F\u0561-\u0587\u13F8-\u13FD\u1D00-\u1D2B\u1D6B-\u1D77\u1D79-\u1D9A\u1E01\u1E03\u1E05\u1E07\u1E09\u1E0B\u1E0D\u1E0F\u1E11\u1E13\u1E15\u1E17\u1E19\u1E1B\u1E1D\u1E1F\u1E21\u1E23\u1E25\u1E27\u1E29\u1E2B\u1E2D\u1E2F\u1E31\u1E33\u1E35\u1E37\u1E39\u1E3B\u1E3D\u1E3F\u1E41\u1E43\u1E45\u1E47\u1E49\u1E4B\u1E4D\u1E4F\u1E51\u1E53\u1E55\u1E57\u1E59\u1E5B\u1E5D\u1E5F\u1E61\u1E63\u1E65\u1E67\u1E69\u1E6B\u1E6D\u1E6F\u1E71\u1E73\u1E75\u1E77\u1E79\u1E7B\u1E7D\u1E7F\u1E81\u1E83\u1E85\u1E87\u1E89\u1E8B\u1E8D\u1E8F\u1E91\u1E93\u1E95-\u1E9D\u1E9F\u1EA1\u1EA3\u1EA5\u1EA7\u1EA9\u1EAB\u1EAD\u1EAF\u1EB1\u1EB3\u1EB5\u1EB7\u1EB9\u1EBB\u1EBD\u1EBF\u1EC1\u1EC3\u1EC5\u1EC7\u1EC9\u1ECB\u1ECD\u1ECF\u1ED1\u1ED3\u1ED5\u1ED7\u1ED9\u1EDB\u1EDD\u1EDF\u1EE1\u1EE3\u1EE5\u1EE7\u1EE9\u1EEB\u1EED\u1EEF\u1EF1\u1EF3\u1EF5\u1EF7\u1EF9\u1EFB\u1EFD\u1EFF-\u1F07\u1F10-\u1F15\u1F20-\u1F27\u1F30-\u1F37\u1F40-\u1F45\u1F50-\u1F57\u1F60-\u1F67\u1F70-\u1F7D\u1F80-\u1F87\u1F90-\u1F97\u1FA0-\u1FA7\u1FB0-\u1FB4\u1FB6-\u1FB7\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FC7\u1FD0-\u1FD3\u1FD6-\u1FD7\u1FE0-\u1FE7\u1FF2-\u1FF4\u1FF6-\u1FF7\u210A\u210E-\u210F\u2113\u212F\u2134\u2139\u213C-\u213D\u2146-\u2149\u214E\u2184\u2C30-\u2C5E\u2C61\u2C65-\u2C66\u2C68\u2C6A\u2C6C\u2C71\u2C73-\u2C74\u2C76-\u2C7B\u2C81\u2C83\u2C85\u2C87\u2C89\u2C8B\u2C8D\u2C8F\u2C91\u2C93\u2C95\u2C97\u2C99\u2C9B\u2C9D\u2C9F\u2CA1\u2CA3\u2CA5\u2CA7\u2CA9\u2CAB\u2CAD\u2CAF\u2CB1\u2CB3\u2CB5\u2CB7\u2CB9\u2CBB\u2CBD\u2CBF\u2CC1\u2CC3\u2CC5\u2CC7\u2CC9\u2CCB\u2CCD\u2CCF\u2CD1\u2CD3\u2CD5\u2CD7\u2CD9\u2CDB\u2CDD\u2CDF\u2CE1\u2CE3-\u2CE4\u2CEC\u2CEE\u2CF3\u2D00-\u2D25\u2D27\u2D2D\uA641\uA643\uA645\uA647\uA649\uA64B\uA64D\uA64F\uA651\uA653\uA655\uA657\uA659\uA65B\uA65D\uA65F\uA661\uA663\uA665\uA667\uA669\uA66B\uA66D\uA681\uA683\uA685\uA687\uA689\uA68B\uA68D\uA68F\uA691\uA693\uA695\uA697\uA699\uA69B\uA723\uA725\uA727\uA729\uA72B\uA72D\uA72F-\uA731\uA733\uA735\uA737\uA739\uA73B\uA73D\uA73F\uA741\uA743\uA745\uA747\uA749\uA74B\uA74D\uA74F\uA751\uA753\uA755\uA757\uA759\uA75B\uA75D\uA75F\uA761\uA763\uA765\uA767\uA769\uA76B\uA76D\uA76F\uA771-\uA778\uA77A\uA77C\uA77F\uA781\uA783\uA785\uA787\uA78C\uA78E\uA791\uA793-\uA795\uA797\uA799\uA79B\uA79D\uA79F\uA7A1\uA7A3\uA7A5\uA7A7\uA7A9\uA7B5\uA7B7\uA7FA\uAB30-\uAB5A\uAB60-\uAB65\uAB70-\uABBF\uFB00-\uFB06\uFB13-\uFB17\uFF41-\uFF5A]
492
493 // Letter, Modifier
494 Lm = [\u02B0-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0374\u037A\u0559\u0640\u06E5-\u06E6\u07F4-\u07F5\u07FA\u081A\u0824\u0828\u0971\u0E46\u0EC6\u10FC\u17D7\u1843\u1AA7\u1C78-\u1C7D\u1D2C-\u1D6A\u1D78\u1D9B-\u1DBF\u2071\u207F\u2090-\u209C\u2C7C-\u2C7D\u2D6F\u2E2F\u3005\u3031-\u3035\u303B\u309D-\u309E\u30FC-\u30FE\uA015\uA4F8-\uA4FD\uA60C\uA67F\uA69C-\uA69D\uA717-\uA71F\uA770\uA788\uA7F8-\uA7F9\uA9CF\uA9E6\uAA70\uAADD\uAAF3-\uAAF4\uAB5C-\uAB5F\uFF70\uFF9E-\uFF9F]
495
496 // Letter, Other
497 Lo = [\u00AA\u00BA\u01BB\u01C0-\u01C3\u0294\u05D0-\u05EA\u05F0-\u05F2\u0620-\u063F\u0641-\u064A\u066E-\u066F\u0671-\u06D3\u06D5\u06EE-\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u0800-\u0815\u0840-\u0858\u08A0-\u08B4\u0904-\u0939\u093D\u0950\u0958-\u0961\u0972-\u0980\u0985-\u098C\u098F-\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC-\u09DD\u09DF-\u09E1\u09F0-\u09F1\u0A05-\u0A0A\u0A0F-\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32-\u0A33\u0A35-\u0A36\u0A38-\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2-\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0-\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F-\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32-\u0B33\u0B35-\u0B39\u0B3D\u0B5C-\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99-\u0B9A\u0B9C\u0B9E-\u0B9F\u0BA3-\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60-\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0-\u0CE1\u0CF1-\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32-\u0E33\u0E40-\u0E45\u0E81-\u0E82\u0E84\u0E87-\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA-\u0EAB\u0EAD-\u0EB0\u0EB2-\u0EB3\u0EBD\u0EC0-\u0EC4\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065-\u1066\u106E-\u1070\u1075-\u1081\u108E\u10D0-\u10FA\u10FD-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17DC\u1820-\u1842\u1844-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE-\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C77\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5-\u1CF6\u2135-\u2138\u2D30-\u2D67\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3006\u303C\u3041-\u3096\u309F\u30A1-\u30FA\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA014\uA016-\uA48C\uA4D0-\uA4F7\uA500-\uA60B\uA610-\uA61F\uA62A-\uA62B\uA66E\uA6A0-\uA6E5\uA78F\uA7F7\uA7FB-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9E0-\uA9E4\uA9E7-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA6F\uAA71-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5-\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADC\uAAE0-\uAAEA\uAAF2\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40-\uFB41\uFB43-\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF66-\uFF6F\uFF71-\uFF9D\uFFA0-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]
498
499 // Letter, Titlecase
500 Lt = [\u01C5\u01C8\u01CB\u01F2\u1F88-\u1F8F\u1F98-\u1F9F\u1FA8-\u1FAF\u1FBC\u1FCC\u1FFC]
501
502 // Letter, Uppercase
503 Lu = [\u0041-\u005A\u00C0-\u00D6\u00D8-\u00DE\u0100\u0102\u0104\u0106\u0108\u010A\u010C\u010E\u0110\u0112\u0114\u0116\u0118\u011A\u011C\u011E\u0120\u0122\u0124\u0126\u0128\u012A\u012C\u012E\u0130\u0132\u0134\u0136\u0139\u013B\u013D\u013F\u0141\u0143\u0145\u0147\u014A\u014C\u014E\u0150\u0152\u0154\u0156\u0158\u015A\u015C\u015E\u0160\u0162\u0164\u0166\u0168\u016A\u016C\u016E\u0170\u0172\u0174\u0176\u0178-\u0179\u017B\u017D\u0181-\u0182\u0184\u0186-\u0187\u0189-\u018B\u018E-\u0191\u0193-\u0194\u0196-\u0198\u019C-\u019D\u019F-\u01A0\u01A2\u01A4\u01A6-\u01A7\u01A9\u01AC\u01AE-\u01AF\u01B1-\u01B3\u01B5\u01B7-\u01B8\u01BC\u01C4\u01C7\u01CA\u01CD\u01CF\u01D1\u01D3\u01D5\u01D7\u01D9\u01DB\u01DE\u01E0\u01E2\u01E4\u01E6\u01E8\u01EA\u01EC\u01EE\u01F1\u01F4\u01F6-\u01F8\u01FA\u01FC\u01FE\u0200\u0202\u0204\u0206\u0208\u020A\u020C\u020E\u0210\u0212\u0214\u0216\u0218\u021A\u021C\u021E\u0220\u0222\u0224\u0226\u0228\u022A\u022C\u022E\u0230\u0232\u023A-\u023B\u023D-\u023E\u0241\u0243-\u0246\u0248\u024A\u024C\u024E\u0370\u0372\u0376\u037F\u0386\u0388-\u038A\u038C\u038E-\u038F\u0391-\u03A1\u03A3-\u03AB\u03CF\u03D2-\u03D4\u03D8\u03DA\u03DC\u03DE\u03E0\u03E2\u03E4\u03E6\u03E8\u03EA\u03EC\u03EE\u03F4\u03F7\u03F9-\u03FA\u03FD-\u042F\u0460\u0462\u0464\u0466\u0468\u046A\u046C\u046E\u0470\u0472\u0474\u0476\u0478\u047A\u047C\u047E\u0480\u048A\u048C\u048E\u0490\u0492\u0494\u0496\u0498\u049A\u049C\u049E\u04A0\u04A2\u04A4\u04A6\u04A8\u04AA\u04AC\u04AE\u04B0\u04B2\u04B4\u04B6\u04B8\u04BA\u04BC\u04BE\u04C0-\u04C1\u04C3\u04C5\u04C7\u04C9\u04CB\u04CD\u04D0\u04D2\u04D4\u04D6\u04D8\u04DA\u04DC\u04DE\u04E0\u04E2\u04E4\u04E6\u04E8\u04EA\u04EC\u04EE\u04F0\u04F2\u04F4\u04F6\u04F8\u04FA\u04FC\u04FE\u0500\u0502\u0504\u0506\u0508\u050A\u050C\u050E\u0510\u0512\u0514\u0516\u0518\u051A\u051C\u051E\u0520\u0522\u0524\u0526\u0528\u052A\u052C\u052E\u0531-\u0556\u10A0-\u10C5\u10C7\u10CD\u13A0-\u13F5\u1E00\u1E02\u1E04\u1E06\u1E08\u1E0A\u1E0C\u1E0E\u1E10\u1E12\u1E14\u1E16\u1E18\u1E1A\u1E1C\u1E1E\u1E20\u1E22\u1E24\u1E26\u1E28\u1E2A\u1E2C\u1E2E\u1E30\u1E32\u1E34\u1E36\u1E38\u1E3A\u1E3C\u1E3E\u1E40\u1E42\u1E44\u1E46\u1E48\u1E4A\u1E4C\u1E4E\u1E50\u1E52\u1E54\u1E56\u1E58\u1E5A\u1E5C\u1E5E\u1E60\u1E62\u1E64\u1E66\u1E68\u1E6A\u1E6C\u1E6E\u1E70\u1E72\u1E74\u1E76\u1E78\u1E7A\u1E7C\u1E7E\u1E80\u1E82\u1E84\u1E86\u1E88\u1E8A\u1E8C\u1E8E\u1E90\u1E92\u1E94\u1E9E\u1EA0\u1EA2\u1EA4\u1EA6\u1EA8\u1EAA\u1EAC\u1EAE\u1EB0\u1EB2\u1EB4\u1EB6\u1EB8\u1EBA\u1EBC\u1EBE\u1EC0\u1EC2\u1EC4\u1EC6\u1EC8\u1ECA\u1ECC\u1ECE\u1ED0\u1ED2\u1ED4\u1ED6\u1ED8\u1EDA\u1EDC\u1EDE\u1EE0\u1EE2\u1EE4\u1EE6\u1EE8\u1EEA\u1EEC\u1EEE\u1EF0\u1EF2\u1EF4\u1EF6\u1EF8\u1EFA\u1EFC\u1EFE\u1F08-\u1F0F\u1F18-\u1F1D\u1F28-\u1F2F\u1F38-\u1F3F\u1F48-\u1F4D\u1F59\u1F5B\u1F5D\u1F5F\u1F68-\u1F6F\u1FB8-\u1FBB\u1FC8-\u1FCB\u1FD8-\u1FDB\u1FE8-\u1FEC\u1FF8-\u1FFB\u2102\u2107\u210B-\u210D\u2110-\u2112\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u2130-\u2133\u213E-\u213F\u2145\u2183\u2C00-\u2C2E\u2C60\u2C62-\u2C64\u2C67\u2C69\u2C6B\u2C6D-\u2C70\u2C72\u2C75\u2C7E-\u2C80\u2C82\u2C84\u2C86\u2C88\u2C8A\u2C8C\u2C8E\u2C90\u2C92\u2C94\u2C96\u2C98\u2C9A\u2C9C\u2C9E\u2CA0\u2CA2\u2CA4\u2CA6\u2CA8\u2CAA\u2CAC\u2CAE\u2CB0\u2CB2\u2CB4\u2CB6\u2CB8\u2CBA\u2CBC\u2CBE\u2CC0\u2CC2\u2CC4\u2CC6\u2CC8\u2CCA\u2CCC\u2CCE\u2CD0\u2CD2\u2CD4\u2CD6\u2CD8\u2CDA\u2CDC\u2CDE\u2CE0\u2CE2\u2CEB\u2CED\u2CF2\uA640\uA642\uA644\uA646\uA648\uA64A\uA64C\uA64E\uA650\uA652\uA654\uA656\uA658\uA65A\uA65C\uA65E\uA660\uA662\uA664\uA666\uA668\uA66A\uA66C\uA680\uA682\uA684\uA686\uA688\uA68A\uA68C\uA68E\uA690\uA692\uA694\uA696\uA698\uA69A\uA722\uA724\uA726\uA728\uA72A\uA72C\uA72E\uA732\uA734\uA736\uA738\uA73A\uA73C\uA73E\uA740\uA742\uA744\uA746\uA748\uA74A\uA74C\uA74E\uA750\uA752\uA754\uA756\uA758\uA75A\uA75C\uA75E\uA760\uA762\uA764\uA766\uA768\uA76A\uA76C\uA76E\uA779\uA77B\uA77D-\uA77E\uA780\uA782\uA784\uA786\uA78B\uA78D\uA790\uA792\uA796\uA798\uA79A\uA79C\uA79E\uA7A0\uA7A2\uA7A4\uA7A6\uA7A8\uA7AA-\uA7AD\uA7B0-\uA7B4\uA7B6\uFF21-\uFF3A]
504
505 // Mark, Spacing Combining
506 Mc = [\u0903\u093B\u093E-\u0940\u0949-\u094C\u094E-\u094F\u0982-\u0983\u09BE-\u09C0\u09C7-\u09C8\u09CB-\u09CC\u09D7\u0A03\u0A3E-\u0A40\u0A83\u0ABE-\u0AC0\u0AC9\u0ACB-\u0ACC\u0B02-\u0B03\u0B3E\u0B40\u0B47-\u0B48\u0B4B-\u0B4C\u0B57\u0BBE-\u0BBF\u0BC1-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCC\u0BD7\u0C01-\u0C03\u0C41-\u0C44\u0C82-\u0C83\u0CBE\u0CC0-\u0CC4\u0CC7-\u0CC8\u0CCA-\u0CCB\u0CD5-\u0CD6\u0D02-\u0D03\u0D3E-\u0D40\u0D46-\u0D48\u0D4A-\u0D4C\u0D57\u0D82-\u0D83\u0DCF-\u0DD1\u0DD8-\u0DDF\u0DF2-\u0DF3\u0F3E-\u0F3F\u0F7F\u102B-\u102C\u1031\u1038\u103B-\u103C\u1056-\u1057\u1062-\u1064\u1067-\u106D\u1083-\u1084\u1087-\u108C\u108F\u109A-\u109C\u17B6\u17BE-\u17C5\u17C7-\u17C8\u1923-\u1926\u1929-\u192B\u1930-\u1931\u1933-\u1938\u1A19-\u1A1A\u1A55\u1A57\u1A61\u1A63-\u1A64\u1A6D-\u1A72\u1B04\u1B35\u1B3B\u1B3D-\u1B41\u1B43-\u1B44\u1B82\u1BA1\u1BA6-\u1BA7\u1BAA\u1BE7\u1BEA-\u1BEC\u1BEE\u1BF2-\u1BF3\u1C24-\u1C2B\u1C34-\u1C35\u1CE1\u1CF2-\u1CF3\u302E-\u302F\uA823-\uA824\uA827\uA880-\uA881\uA8B4-\uA8C3\uA952-\uA953\uA983\uA9B4-\uA9B5\uA9BA-\uA9BB\uA9BD-\uA9C0\uAA2F-\uAA30\uAA33-\uAA34\uAA4D\uAA7B\uAA7D\uAAEB\uAAEE-\uAAEF\uAAF5\uABE3-\uABE4\uABE6-\uABE7\uABE9-\uABEA\uABEC]
507
508 // Mark, Nonspacing
509 Mn = [\u0300-\u036F\u0483-\u0487\u0591-\u05BD\u05BF\u05C1-\u05C2\u05C4-\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7-\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08E3-\u0902\u093A\u093C\u0941-\u0948\u094D\u0951-\u0957\u0962-\u0963\u0981\u09BC\u09C1-\u09C4\u09CD\u09E2-\u09E3\u0A01-\u0A02\u0A3C\u0A41-\u0A42\u0A47-\u0A48\u0A4B-\u0A4D\u0A51\u0A70-\u0A71\u0A75\u0A81-\u0A82\u0ABC\u0AC1-\u0AC5\u0AC7-\u0AC8\u0ACD\u0AE2-\u0AE3\u0B01\u0B3C\u0B3F\u0B41-\u0B44\u0B4D\u0B56\u0B62-\u0B63\u0B82\u0BC0\u0BCD\u0C00\u0C3E-\u0C40\u0C46-\u0C48\u0C4A-\u0C4D\u0C55-\u0C56\u0C62-\u0C63\u0C81\u0CBC\u0CBF\u0CC6\u0CCC-\u0CCD\u0CE2-\u0CE3\u0D01\u0D41-\u0D44\u0D4D\u0D62-\u0D63\u0DCA\u0DD2-\u0DD4\u0DD6\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB-\u0EBC\u0EC8-\u0ECD\u0F18-\u0F19\u0F35\u0F37\u0F39\u0F71-\u0F7E\u0F80-\u0F84\u0F86-\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102D-\u1030\u1032-\u1037\u1039-\u103A\u103D-\u103E\u1058-\u1059\u105E-\u1060\u1071-\u1074\u1082\u1085-\u1086\u108D\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752-\u1753\u1772-\u1773\u17B4-\u17B5\u17B7-\u17BD\u17C6\u17C9-\u17D3\u17DD\u180B-\u180D\u18A9\u1920-\u1922\u1927-\u1928\u1932\u1939-\u193B\u1A17-\u1A18\u1A1B\u1A56\u1A58-\u1A5E\u1A60\u1A62\u1A65-\u1A6C\u1A73-\u1A7C\u1A7F\u1AB0-\u1ABD\u1B00-\u1B03\u1B34\u1B36-\u1B3A\u1B3C\u1B42\u1B6B-\u1B73\u1B80-\u1B81\u1BA2-\u1BA5\u1BA8-\u1BA9\u1BAB-\u1BAD\u1BE6\u1BE8-\u1BE9\u1BED\u1BEF-\u1BF1\u1C2C-\u1C33\u1C36-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE0\u1CE2-\u1CE8\u1CED\u1CF4\u1CF8-\u1CF9\u1DC0-\u1DF5\u1DFC-\u1DFF\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302D\u3099-\u309A\uA66F\uA674-\uA67D\uA69E-\uA69F\uA6F0-\uA6F1\uA802\uA806\uA80B\uA825-\uA826\uA8C4\uA8E0-\uA8F1\uA926-\uA92D\uA947-\uA951\uA980-\uA982\uA9B3\uA9B6-\uA9B9\uA9BC\uA9E5\uAA29-\uAA2E\uAA31-\uAA32\uAA35-\uAA36\uAA43\uAA4C\uAA7C\uAAB0\uAAB2-\uAAB4\uAAB7-\uAAB8\uAABE-\uAABF\uAAC1\uAAEC-\uAAED\uAAF6\uABE5\uABE8\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2F]
510
511 // Number, Decimal Digit
512 Nd = [\u0030-\u0039\u0660-\u0669\u06F0-\u06F9\u07C0-\u07C9\u0966-\u096F\u09E6-\u09EF\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0BE6-\u0BEF\u0C66-\u0C6F\u0CE6-\u0CEF\u0D66-\u0D6F\u0DE6-\u0DEF\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F29\u1040-\u1049\u1090-\u1099\u17E0-\u17E9\u1810-\u1819\u1946-\u194F\u19D0-\u19D9\u1A80-\u1A89\u1A90-\u1A99\u1B50-\u1B59\u1BB0-\u1BB9\u1C40-\u1C49\u1C50-\u1C59\uA620-\uA629\uA8D0-\uA8D9\uA900-\uA909\uA9D0-\uA9D9\uA9F0-\uA9F9\uAA50-\uAA59\uABF0-\uABF9\uFF10-\uFF19]
513
514 // Number, Letter
515 Nl = [\u16EE-\u16F0\u2160-\u2182\u2185-\u2188\u3007\u3021-\u3029\u3038-\u303A\uA6E6-\uA6EF]
516
517 // Punctuation, Connector
518 Pc = [\u005F\u203F-\u2040\u2054\uFE33-\uFE34\uFE4D-\uFE4F\uFF3F]
519
520 // Separator, Space
521 Zs = [\u0020\u00A0\u1680\u2000-\u200A\u202F\u205F\u3000]
522
523 /* Tokens */
524
525 BreakToken = "break" !IdentifierPart
526 CaseToken = "case" !IdentifierPart
527 CatchToken = "catch" !IdentifierPart
528 ClassToken = "class" !IdentifierPart
529 ConstToken = "const" !IdentifierPart
530 ContinueToken = "continue" !IdentifierPart
531 DebuggerToken = "debugger" !IdentifierPart
532 DefaultToken = "default" !IdentifierPart
533 DeleteToken = "delete" !IdentifierPart
534 DoToken = "do" !IdentifierPart
535 ElseToken = "else" !IdentifierPart
536 EnumToken = "enum" !IdentifierPart
537 ExportToken = "export" !IdentifierPart
538 ExtendsToken = "extends" !IdentifierPart
539 FalseToken = "false" !IdentifierPart
540 FinallyToken = "finally" !IdentifierPart
541 ForToken = "for" !IdentifierPart
542 FunctionToken = "function" !IdentifierPart
543 IfToken = "if" !IdentifierPart
544 ImportToken = "import" !IdentifierPart
545 InstanceofToken = "instanceof" !IdentifierPart
546 InToken = "in" !IdentifierPart
547 NewToken = "new" !IdentifierPart
548 NullToken = "null" !IdentifierPart
549 ReturnToken = "return" !IdentifierPart
550 SuperToken = "super" !IdentifierPart
551 SwitchToken = "switch" !IdentifierPart
552 ThisToken = "this" !IdentifierPart
553 ThrowToken = "throw" !IdentifierPart
554 TrueToken = "true" !IdentifierPart
555 TryToken = "try" !IdentifierPart
556 TypeofToken = "typeof" !IdentifierPart
557 VarToken = "var" !IdentifierPart
558 VoidToken = "void" !IdentifierPart
559 WhileToken = "while" !IdentifierPart
560 WithToken = "with" !IdentifierPart
561
562 /* Skipped */
563
564 __
565 = (WhiteSpace / LineTerminatorSequence / Comment)*
566
567 _
568 = (WhiteSpace / MultiLineCommentNoLineTerminator)*
569
570 /* Automatic Semicolon Insertion */
571
572 EOS
573 = __ ";"
574 / _ SingleLineComment? LineTerminatorSequence
575 / __ EOF
576
577 EOF
578 = !.
+0
-412
src/passes.js less more
0 /*
1 * Compiler passes.
2 *
3 * Each pass is a function that is passed the AST. It can perform checks on it
4 * or modify it as needed. If the pass encounters a semantic error, it throws
5 * |PEG.GrammarError|.
6 */
7 PEG.compiler.passes = {
8 /* Checks that all referenced rules exist. */
9 reportMissingRules: function(ast) {
10 function nop() {}
11
12 function checkExpression(node) { check(node.expression); }
13
14 function checkSubnodes(propertyName) {
15 return function(node) { each(node[propertyName], check); };
16 }
17
18 var check = buildNodeVisitor({
19 grammar: checkSubnodes("rules"),
20 rule: checkExpression,
21 choice: checkSubnodes("alternatives"),
22 sequence: checkSubnodes("elements"),
23 labeled: checkExpression,
24 simple_and: checkExpression,
25 simple_not: checkExpression,
26 semantic_and: nop,
27 semantic_not: nop,
28 optional: checkExpression,
29 zero_or_more: checkExpression,
30 one_or_more: checkExpression,
31 action: checkExpression,
32
33 rule_ref:
34 function(node) {
35 if (!findRuleByName(ast, node.name)) {
36 throw new PEG.GrammarError(
37 "Referenced rule \"" + node.name + "\" does not exist."
38 );
39 }
40 },
41
42 literal: nop,
43 any: nop,
44 "class": nop
45 });
46
47 check(ast);
48 },
49
50 /* Checks that no left recursion is present. */
51 reportLeftRecursion: function(ast) {
52 function nop() {}
53
54 function checkExpression(node, appliedRules) {
55 check(node.expression, appliedRules);
56 }
57
58 function checkSubnodes(propertyName) {
59 return function(node, appliedRules) {
60 each(node[propertyName], function(subnode) {
61 check(subnode, appliedRules);
62 });
63 };
64 }
65
66 var check = buildNodeVisitor({
67 grammar: checkSubnodes("rules"),
68
69 rule:
70 function(node, appliedRules) {
71 check(node.expression, appliedRules.concat(node.name));
72 },
73
74 choice: checkSubnodes("alternatives"),
75
76 sequence:
77 function(node, appliedRules) {
78 if (node.elements.length > 0) {
79 check(node.elements[0], appliedRules);
80 }
81 },
82
83 labeled: checkExpression,
84 simple_and: checkExpression,
85 simple_not: checkExpression,
86 semantic_and: nop,
87 semantic_not: nop,
88 optional: checkExpression,
89 zero_or_more: checkExpression,
90 one_or_more: checkExpression,
91 action: checkExpression,
92
93 rule_ref:
94 function(node, appliedRules) {
95 if (contains(appliedRules, node.name)) {
96 throw new PEG.GrammarError(
97 "Left recursion detected for rule \"" + node.name + "\"."
98 );
99 }
100 check(findRuleByName(ast, node.name), appliedRules);
101 },
102
103 literal: nop,
104 any: nop,
105 "class": nop
106 });
107
108 check(ast, []);
109 },
110
111 /*
112 * Removes proxy rules -- that is, rules that only delegate to other rule.
113 */
114 removeProxyRules: function(ast) {
115 function isProxyRule(node) {
116 return node.type === "rule" && node.expression.type === "rule_ref";
117 }
118
119 function replaceRuleRefs(ast, from, to) {
120 function nop() {}
121
122 function replaceInExpression(node, from, to) {
123 replace(node.expression, from, to);
124 }
125
126 function replaceInSubnodes(propertyName) {
127 return function(node, from, to) {
128 each(node[propertyName], function(subnode) {
129 replace(subnode, from, to);
130 });
131 };
132 }
133
134 var replace = buildNodeVisitor({
135 grammar: replaceInSubnodes("rules"),
136 rule: replaceInExpression,
137 choice: replaceInSubnodes("alternatives"),
138 sequence: replaceInSubnodes("elements"),
139 labeled: replaceInExpression,
140 simple_and: replaceInExpression,
141 simple_not: replaceInExpression,
142 semantic_and: nop,
143 semantic_not: nop,
144 optional: replaceInExpression,
145 zero_or_more: replaceInExpression,
146 one_or_more: replaceInExpression,
147 action: replaceInExpression,
148
149 rule_ref:
150 function(node, from, to) {
151 if (node.name === from) {
152 node.name = to;
153 }
154 },
155
156 literal: nop,
157 any: nop,
158 "class": nop
159 });
160
161 replace(ast, from, to);
162 }
163
164 var indices = [];
165
166 each(ast.rules, function(rule, i) {
167 if (isProxyRule(rule)) {
168 replaceRuleRefs(ast, rule.name, rule.expression.name);
169 if (rule.name === ast.startRule) {
170 ast.startRule = rule.expression.name;
171 }
172 indices.push(i);
173 }
174 });
175
176 indices.reverse();
177
178 each(indices, function(index) {
179 ast.rules.splice(index, 1);
180 });
181 },
182
183 /*
184 * Computes names of variables used for storing match results and parse
185 * positions in generated code. These variables are organized as two stacks.
186 * The following will hold after running this pass:
187 *
188 * * All nodes except "grammar" and "rule" nodes will have a |resultVar|
189 * property. It will contain a name of the variable that will store a
190 * match result of the expression represented by the node in generated
191 * code.
192 *
193 * * Some nodes will have a |posVar| property. It will contain a name of the
194 * variable that will store a parse position in generated code.
195 *
196 * * All "rule" nodes will contain |resultVars| and |posVars| properties.
197 * They will contain a list of values of |resultVar| and |posVar|
198 * properties used in rule's subnodes. (This is useful to declare
199 * variables in generated code.)
200 */
201 computeVarNames: function(ast) {
202 function resultVar(index) { return "result" + index; }
203 function posVar(index) { return "pos" + index; }
204
205 function computeLeaf(node, index) {
206 node.resultVar = resultVar(index.result);
207
208 return { result: 0, pos: 0 };
209 }
210
211 function computeFromExpression(delta) {
212 return function(node, index) {
213 var depth = compute(
214 node.expression,
215 {
216 result: index.result + delta.result,
217 pos: index.pos + delta.pos
218 }
219 );
220
221 node.resultVar = resultVar(index.result);
222 if (delta.pos !== 0) {
223 node.posVar = posVar(index.pos);
224 }
225
226 return {
227 result: depth.result + delta.result,
228 pos: depth.pos + delta.pos
229 };
230 };
231 }
232
233 var compute = buildNodeVisitor({
234 grammar:
235 function(node, index) {
236 each(node.rules, function(node) {
237 compute(node, index);
238 });
239 },
240
241 rule:
242 function(node, index) {
243 var depth = compute(node.expression, index);
244
245 node.resultVar = resultVar(index.result);
246 node.resultVars = map(range(depth.result + 1), resultVar);
247 node.posVars = map(range(depth.pos), posVar);
248 },
249
250 choice:
251 function(node, index) {
252 var depths = map(node.alternatives, function(alternative) {
253 return compute(alternative, index);
254 });
255
256 node.resultVar = resultVar(index.result);
257
258 return {
259 result: Math.max.apply(null, pluck(depths, "result")),
260 pos: Math.max.apply(null, pluck(depths, "pos"))
261 };
262 },
263
264 sequence:
265 function(node, index) {
266 var depths = map(node.elements, function(element, i) {
267 return compute(
268 element,
269 { result: index.result + i, pos: index.pos + 1 }
270 );
271 });
272
273 node.resultVar = resultVar(index.result);
274 node.posVar = posVar(index.pos);
275
276 return {
277 result:
278 node.elements.length > 0
279 ? Math.max.apply(
280 null,
281 map(depths, function(d, i) { return i + d.result; })
282 )
283 : 0,
284
285 pos:
286 node.elements.length > 0
287 ? 1 + Math.max.apply(null, pluck(depths, "pos"))
288 : 1
289 };
290 },
291
292 labeled: computeFromExpression({ result: 0, pos: 0 }),
293 simple_and: computeFromExpression({ result: 0, pos: 1 }),
294 simple_not: computeFromExpression({ result: 0, pos: 1 }),
295 semantic_and: computeLeaf,
296 semantic_not: computeLeaf,
297 optional: computeFromExpression({ result: 0, pos: 0 }),
298 zero_or_more: computeFromExpression({ result: 1, pos: 0 }),
299 one_or_more: computeFromExpression({ result: 1, pos: 0 }),
300 action: computeFromExpression({ result: 0, pos: 1 }),
301 rule_ref: computeLeaf,
302 literal: computeLeaf,
303 any: computeLeaf,
304 "class": computeLeaf
305 });
306
307 compute(ast, { result: 0, pos: 0 });
308 },
309
310 /*
311 * This pass walks through the AST and tracks what labels are visible at each
312 * point. For "action", "semantic_and" and "semantic_or" nodes it computes
313 * parameter names and values for the function used in generated code. (In the
314 * emitter, user's code is wrapped into a function that is immediately
315 * executed. Its parameter names correspond to visible labels and its
316 * parameter values to their captured values). Implicitly, this pass defines
317 * scoping rules for labels.
318 *
319 * After running this pass, all "action", "semantic_and" and "semantic_or"
320 * nodes will have a |params| property containing an object mapping parameter
321 * names to the expressions that will be used as their values.
322 */
323 computeParams: function(ast) {
324 var envs = [];
325
326 function scoped(f) {
327 envs.push({});
328 f();
329 envs.pop();
330 }
331
332 function nop() {}
333
334 function computeForScopedExpression(node) {
335 scoped(function() { compute(node.expression); });
336 }
337
338 function computeParams(node) {
339 var env = envs[envs.length - 1], params = {}, name;
340
341 for (name in env) {
342 params[name] = env[name];
343 }
344 node.params = params;
345 }
346
347 var compute = buildNodeVisitor({
348 grammar:
349 function(node) {
350 each(node.rules, compute);
351 },
352
353 rule: computeForScopedExpression,
354
355 choice:
356 function(node) {
357 scoped(function() { each(node.alternatives, compute); });
358 },
359
360 sequence:
361 function(node) {
362 var env = envs[envs.length - 1], name;
363
364 function fixup(name) {
365 each(pluck(node.elements, "resultVar"), function(resultVar, i) {
366 if ((new RegExp("^" + resultVar + "(\\[\\d+\\])*$")).test(env[name])) {
367 env[name] = node.resultVar + "[" + i + "]"
368 + env[name].substr(resultVar.length);
369 }
370 });
371 }
372
373 each(node.elements, compute);
374
375 for (name in env) {
376 fixup(name);
377 }
378 },
379
380 labeled:
381 function(node) {
382 envs[envs.length - 1][node.label] = node.resultVar;
383
384 scoped(function() { compute(node.expression); });
385 },
386
387 simple_and: computeForScopedExpression,
388 simple_not: computeForScopedExpression,
389 semantic_and: computeParams,
390 semantic_not: computeParams,
391 optional: computeForScopedExpression,
392 zero_or_more: computeForScopedExpression,
393 one_or_more: computeForScopedExpression,
394
395 action:
396 function(node) {
397 scoped(function() {
398 compute(node.expression);
399 computeParams(node);
400 });
401 },
402
403 rule_ref: nop,
404 literal: nop,
405 any: nop,
406 "class": nop
407 });
408
409 compute(ast);
410 }
411 };
+0
-50
src/peg.js less more
0 /*
1 * PEG.js @VERSION
2 *
3 * http://pegjs.majda.cz/
4 *
5 * Copyright (c) 2010-2012 David Majda
6 * Licensend under the MIT license.
7 */
8 var PEG = (function(undefined) {
9
10 var PEG = {
11 /* PEG.js version (uses semantic versioning). */
12 VERSION: "@VERSION",
13
14 /*
15 * Generates a parser from a specified grammar and returns it.
16 *
17 * The grammar must be a string in the format described by the metagramar in
18 * the parser.pegjs file.
19 *
20 * Throws |PEG.parser.SyntaxError| if the grammar contains a syntax error or
21 * |PEG.GrammarError| if it contains a semantic error. Note that not all
22 * errors are detected during the generation and some may protrude to the
23 * generated parser and cause its malfunction.
24 */
25 buildParser: function(grammar, options) {
26 return PEG.compiler.compile(PEG.parser.parse(grammar), options);
27 }
28 };
29
30 /* Thrown when the grammar contains an error. */
31
32 PEG.GrammarError = function(message) {
33 this.name = "PEG.GrammarError";
34 this.message = message;
35 };
36
37 PEG.GrammarError.prototype = Error.prototype;
38
39 // @include "utils.js"
40 // @include "parser.js"
41 // @include "compiler.js"
42
43 return PEG;
44
45 })();
46
47 if (typeof module !== "undefined") {
48 module.exports = PEG;
49 }
+0
-183
src/utils.js less more
0 /* Like Python's |range|, but without |step|. */
1 function range(start, stop) {
2 if (stop === undefined) {
3 stop = start;
4 start = 0;
5 }
6
7 var result = new Array(Math.max(0, stop - start));
8 for (var i = 0, j = start; j < stop; i++, j++) {
9 result[i] = j;
10 }
11 return result;
12 }
13
14 function find(array, callback) {
15 var length = array.length;
16 for (var i = 0; i < length; i++) {
17 if (callback(array[i])) {
18 return array[i];
19 }
20 }
21 }
22
23 function contains(array, value) {
24 /*
25 * Stupid IE does not have Array.prototype.indexOf, otherwise this function
26 * would be a one-liner.
27 */
28 var length = array.length;
29 for (var i = 0; i < length; i++) {
30 if (array[i] === value) {
31 return true;
32 }
33 }
34 return false;
35 }
36
37 function each(array, callback) {
38 var length = array.length;
39 for (var i = 0; i < length; i++) {
40 callback(array[i], i);
41 }
42 }
43
44 function map(array, callback) {
45 var result = [];
46 var length = array.length;
47 for (var i = 0; i < length; i++) {
48 result[i] = callback(array[i], i);
49 }
50 return result;
51 }
52
53 function pluck(array, key) {
54 return map(array, function (e) { return e[key]; });
55 }
56
57 function keys(object) {
58 var result = [];
59 for (var key in object) {
60 result.push(key);
61 }
62 return result;
63 }
64
65 function values(object) {
66 var result = [];
67 for (var key in object) {
68 result.push(object[key]);
69 }
70 return result;
71 }
72
73 /*
74 * Returns a string padded on the left to a desired length with a character.
75 *
76 * The code needs to be in sync with the code template in the compilation
77 * function for "action" nodes.
78 */
79 function padLeft(input, padding, length) {
80 var result = input;
81
82 var padLength = length - input.length;
83 for (var i = 0; i < padLength; i++) {
84 result = padding + result;
85 }
86
87 return result;
88 }
89
90 /*
91 * Returns an escape sequence for given character. Uses \x for characters <=
92 * 0xFF to save space, \u for the rest.
93 *
94 * The code needs to be in sync with the code template in the compilation
95 * function for "action" nodes.
96 */
97 function escape(ch) {
98 var charCode = ch.charCodeAt(0);
99 var escapeChar;
100 var length;
101
102 if (charCode <= 0xFF) {
103 escapeChar = 'x';
104 length = 2;
105 } else {
106 escapeChar = 'u';
107 length = 4;
108 }
109
110 return '\\' + escapeChar + padLeft(charCode.toString(16).toUpperCase(), '0', length);
111 }
112
113 /*
114 * Surrounds the string with quotes and escapes characters inside so that the
115 * result is a valid JavaScript string.
116 *
117 * The code needs to be in sync with the code template in the compilation
118 * function for "action" nodes.
119 */
120 function quote(s) {
121 /*
122 * ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a string
123 * literal except for the closing quote character, backslash, carriage return,
124 * line separator, paragraph separator, and line feed. Any character may
125 * appear in the form of an escape sequence.
126 *
127 * For portability, we also escape escape all control and non-ASCII
128 * characters. Note that "\0" and "\v" escape sequences are not used because
129 * JSHint does not like the first and IE the second.
130 */
131 return '"' + s
132 .replace(/\\/g, '\\\\') // backslash
133 .replace(/"/g, '\\"') // closing quote character
134 .replace(/\x08/g, '\\b') // backspace
135 .replace(/\t/g, '\\t') // horizontal tab
136 .replace(/\n/g, '\\n') // line feed
137 .replace(/\f/g, '\\f') // form feed
138 .replace(/\r/g, '\\r') // carriage return
139 .replace(/[\x00-\x07\x0B\x0E-\x1F\x80-\uFFFF]/g, escape)
140 + '"';
141 }
142
143 /*
144 * Escapes characters inside the string so that it can be used as a list of
145 * characters in a character class of a regular expression.
146 */
147 function quoteForRegexpClass(s) {
148 /*
149 * Based on ECMA-262, 5th ed., 7.8.5 & 15.10.1.
150 *
151 * For portability, we also escape escape all control and non-ASCII
152 * characters.
153 */
154 return s
155 .replace(/\\/g, '\\\\') // backslash
156 .replace(/\//g, '\\/') // closing slash
157 .replace(/\]/g, '\\]') // closing bracket
158 .replace(/-/g, '\\-') // dash
159 .replace(/\0/g, '\\0') // null
160 .replace(/\t/g, '\\t') // horizontal tab
161 .replace(/\n/g, '\\n') // line feed
162 .replace(/\v/g, '\\x0B') // vertical tab
163 .replace(/\f/g, '\\f') // form feed
164 .replace(/\r/g, '\\r') // carriage return
165 .replace(/[\x01-\x08\x0E-\x1F\x80-\uFFFF]/g, escape);
166 }
167
168 /*
169 * Builds a node visitor -- a function which takes a node and any number of
170 * other parameters, calls an appropriate function according to the node type,
171 * passes it all its parameters and returns its value. The functions for various
172 * node types are passed in a parameter to |buildNodeVisitor| as a hash.
173 */
174 function buildNodeVisitor(functions) {
175 return function(node) {
176 return functions[node.type].apply(null, arguments);
177 };
178 }
179
180 function findRuleByName(ast, name) {
181 return find(ast.rules, function(r) { return r.name === name; });
182 }
+0
-23
test/README less more
0 PEG.js Test Suite
1 =================
2
3 This is the PEG.js test suite. It ensures PEG.js works correctly. All tests
4 should always pass on all supported platforms.
5
6 Running in a browser
7 --------------------
8
9 1. Open the index.html file in your browser.
10
11 2. Watch the test pass (or fail).
12
13 Running from a command-line
14 ---------------------------
15
16 1. Make sure you have Node.js installed.
17
18 2. Run the following command:
19
20 ./run
21
22 3. Watch the tests pass (or fail).
+0
-1121
test/compiler-test.js less more
0 (function() {
1
2 module("PEG.compiler");
3
4 function testWithVaryingTrackLineAndColumn(name, callback) {
5 test(
6 name + " (with trackLineAndColumn: false) ",
7 function() { callback({ trackLineAndColumn: false }); }
8 );
9 test(
10 name + " (with trackLineAndColumn: true) ",
11 function() { callback({ trackLineAndColumn: true }); }
12 );
13 }
14
15 testWithVaryingTrackLineAndColumn("choices", function(options) {
16 var parser = PEG.buildParser('start = "a" / "b" / "c"', options);
17 parses(parser, "a", "a");
18 parses(parser, "b", "b");
19 parses(parser, "c", "c");
20 doesNotParse(parser, "");
21 doesNotParse(parser, "ab");
22 doesNotParse(parser, "d");
23 });
24
25 testWithVaryingTrackLineAndColumn("sequences", function(options) {
26 var emptySequenceParser = PEG.buildParser('start = ', options);
27 parses(emptySequenceParser, "", []);
28 doesNotParse(emptySequenceParser, "abc");
29
30 var nonEmptySequenceParser = PEG.buildParser('start = "a" "b" "c"', options);
31 parses(nonEmptySequenceParser, "abc", ["a", "b", "c"]);
32 doesNotParse(nonEmptySequenceParser, "");
33 doesNotParse(nonEmptySequenceParser, "ab");
34 doesNotParse(nonEmptySequenceParser, "abcd");
35 doesNotParse(nonEmptySequenceParser, "efg");
36
37 /*
38 * Test that the parsing position returns after unsuccessful parsing of a
39 * sequence.
40 */
41 var posTestParser = PEG.buildParser('start = ("a" "b") / "a"', options);
42 parses(posTestParser, "a", "a");
43 });
44
45 testWithVaryingTrackLineAndColumn("labels", function(options) {
46 var parser = PEG.buildParser('start = label:"a"', options);
47 parses(parser, "a", "a");
48 doesNotParse(parser, "b");
49 });
50
51 testWithVaryingTrackLineAndColumn("simple and", function(options) {
52 var parser = PEG.buildParser('start = "a" &"b" "b"', options);
53 parses(parser, "ab", ["a", "", "b"]);
54 doesNotParse(parser, "ac");
55
56 /*
57 * Test that the parsing position returns after successful parsing of a
58 * predicate is not needed, it is implicit in the tests above.
59 */
60 });
61
62 testWithVaryingTrackLineAndColumn("simple not", function(options) {
63 var parser = PEG.buildParser('start = "a" !"b"', options);
64 parses(parser, "a", ["a", ""]);
65 doesNotParse(parser, "ab");
66
67 /*
68 * Test that the parsing position returns after successful parsing of a
69 * predicate.
70 */
71 var posTestParser = PEG.buildParser('start = "a" !"b" "c"');
72 parses(posTestParser, "ac", ["a", "", "c"]);
73 });
74
75 test("semantic and (with trackLineAndColumn: false)", function() {
76 var options = { trackLineAndColumn: false };
77
78 var acceptingParser = PEG.buildParser(
79 'start = "a" &{ return true; } "b"',
80 options
81 );
82 parses(acceptingParser, "ab", ["a", "", "b"]);
83
84 var rejectingParser = PEG.buildParser(
85 'start = "a" &{ return false; } "b"',
86 options
87 );
88 doesNotParse(rejectingParser, "ab");
89
90 var singleElementUnlabeledParser = PEG.buildParser(
91 'start = "a" &{ return arguments.length === 1 && offset === 1; }',
92 options
93 );
94 parses(singleElementUnlabeledParser, "a", ["a", ""]);
95
96 var singleElementLabeledParser = PEG.buildParser([
97 'start = a:"a" &{',
98 ' return arguments.length === 2',
99 ' && offset === 1',
100 ' && a === "a";',
101 ' }'
102 ].join("\n"), options);
103 parses(singleElementLabeledParser, "a", ["a", ""]);
104
105 var multiElementUnlabeledParser = PEG.buildParser(
106 'start = "a" "b" "c" &{ return arguments.length === 1 && offset === 3; }',
107 options
108 );
109 parses(multiElementUnlabeledParser, "abc", ["a", "b", "c", ""]);
110
111 var multiElementLabeledParser = PEG.buildParser([
112 'start = a:"a" "b" c:"c" &{',
113 ' return arguments.length === 3',
114 ' && offset === 3',
115 ' && a === "a"',
116 ' && c === "c";',
117 ' }'
118 ].join("\n"), options);
119 parses(multiElementLabeledParser, "abc", ["a", "b", "c", ""]);
120
121 var innerElementsUnlabeledParser = PEG.buildParser([
122 'start = "a"',
123 ' ("b" "c" "d" &{ return arguments.length === 1 && offset === 4; })',
124 ' "e"'
125 ].join("\n"), options);
126 parses(innerElementsUnlabeledParser, "abcde", ["a", ["b", "c", "d", ""], "e"]);
127
128 var innerElementsLabeledParser = PEG.buildParser([
129 'start = "a"',
130 ' (',
131 ' b:"b" "c" d:"d" &{',
132 ' return arguments.length === 3',
133 ' && offset === 4',
134 ' && b === "b"',
135 ' && d === "d";',
136 ' }',
137 ' )',
138 ' "e"'
139 ].join("\n"), options);
140 parses(innerElementsLabeledParser, "abcde", ["a", ["b", "c", "d", ""], "e"]);
141 });
142
143 test("semantic and (with trackLineAndColumn: true)", function() {
144 var options = { trackLineAndColumn: true };
145
146 var acceptingParser = PEG.buildParser(
147 'start = "a" &{ return true; } "b"',
148 options
149 );
150 parses(acceptingParser, "ab", ["a", "", "b"]);
151
152 var rejectingParser = PEG.buildParser(
153 'start = "a" &{ return false; } "b"',
154 options
155 );
156 doesNotParse(rejectingParser, "ab");
157
158 var singleElementUnlabeledParser = PEG.buildParser([
159 'start = "a" &{',
160 ' return arguments.length === 3',
161 ' && offset === 1',
162 ' && line === 1',
163 ' && column === 2;',
164 ' }'
165 ].join("\n"), options);
166 parses(singleElementUnlabeledParser, "a", ["a", ""]);
167
168 var singleElementLabeledParser = PEG.buildParser([
169 'start = a:"a" &{',
170 ' return arguments.length === 4',
171 ' && offset === 1',
172 ' && line === 1',
173 ' && column === 2',
174 ' && a === "a";',
175 ' }'
176 ].join("\n"), options);
177 parses(singleElementLabeledParser, "a", ["a", ""]);
178
179 var multiElementUnlabeledParser = PEG.buildParser([
180 'start = "a" "b" "c" &{',
181 ' return arguments.length === 3',
182 ' && offset === 3',
183 ' && line === 1',
184 ' && column === 4;',
185 ' }'
186 ].join("\n"), options);
187 parses(multiElementUnlabeledParser, "abc", ["a", "b", "c", ""]);
188
189 var multiElementLabeledParser = PEG.buildParser([
190 'start = a:"a" "b" c:"c" &{',
191 ' return arguments.length === 5',
192 ' && offset === 3',
193 ' && line === 1',
194 ' && column === 4',
195 ' && a === "a"',
196 ' && c === "c";',
197 ' }'
198 ].join("\n"), options);
199 parses(multiElementLabeledParser, "abc", ["a", "b", "c", ""]);
200
201 var innerElementsUnlabeledParser = PEG.buildParser([
202 'start = "a"',
203 ' (',
204 ' "b" "c" "d" &{',
205 ' return arguments.length === 3',
206 ' && offset === 4',
207 ' && line === 1',
208 ' && column === 5;',
209 ' }',
210 ' )',
211 ' "e"'
212 ].join("\n"), options);
213 parses(innerElementsUnlabeledParser, "abcde", ["a", ["b", "c", "d", ""], "e"]);
214
215 var innerElementsLabeledParser = PEG.buildParser([
216 'start = "a"',
217 ' (',
218 ' b:"b" "c" d:"d" &{',
219 ' return arguments.length === 5',
220 ' && offset === 4',
221 ' && line === 1',
222 ' && column === 5',
223 ' && b === "b"',
224 ' && d === "d";',
225 ' }',
226 ' )',
227 ' "e"'
228 ].join("\n"), options);
229 parses(innerElementsLabeledParser, "abcde", ["a", ["b", "c", "d", ""], "e"]);
230
231 var digitsParser = PEG.buildParser([
232 '{ var result; }',
233 'start = line (nl+ line)* { return result; }',
234 'line = thing (" "+ thing)*',
235 'thing = digit / mark',
236 'digit = [0-9]',
237 'mark = &{ result = [line, column]; return true; } "x"',
238 'nl = ("\\r" / "\\n" / "\\u2028" / "\\u2029")'
239 ].join("\n"), options);
240
241 parses(digitsParser, "1\n2\n\n3\n\n\n4 5 x", [7, 5]);
242
243 /* Non-Unix newlines */
244 parses(digitsParser, "1\rx", [2, 1]); // Old Mac
245 parses(digitsParser, "1\r\nx", [2, 1]); // Windows
246 parses(digitsParser, "1\n\rx", [3, 1]); // mismatched
247
248 /* Strange newlines */
249 parses(digitsParser, "1\u2028x", [2, 1]); // line separator
250 parses(digitsParser, "1\u2029x", [2, 1]); // paragraph separator
251 });
252
253 test("semantic not (with trackLineAndColumn: false)", function() {
254 var options = { trackLineAndColumn: false };
255
256 var acceptingParser = PEG.buildParser(
257 'start = "a" !{ return false; } "b"',
258 options
259 );
260 parses(acceptingParser, "ab", ["a", "", "b"]);
261
262 var rejectingParser = PEG.buildParser(
263 'start = "a" !{ return true; } "b"',
264 options
265 );
266 doesNotParse(rejectingParser, "ab");
267
268 var singleElementUnlabeledParser = PEG.buildParser(
269 'start = "a" !{ return arguments.length !== 1 || offset !== 1; }',
270 options
271 );
272 parses(singleElementUnlabeledParser, "a", ["a", ""]);
273
274 var singleElementLabeledParser = PEG.buildParser([
275 'start = a:"a" !{',
276 ' return arguments.length !== 2',
277 ' || offset !== 1',
278 ' || a !== "a";',
279 ' }'
280 ].join("\n"), options);
281 parses(singleElementLabeledParser, "a", ["a", ""]);
282
283 var multiElementUnlabeledParser = PEG.buildParser(
284 'start = "a" "b" "c" !{ return arguments.length !== 1 || offset !== 3; }',
285 options
286 );
287 parses(multiElementUnlabeledParser, "abc", ["a", "b", "c", ""]);
288
289 var multiElementLabeledParser = PEG.buildParser([
290 'start = a:"a" "b" c:"c" !{',
291 ' return arguments.length !== 3',
292 ' || offset !== 3',
293 ' || a !== "a"',
294 ' || c !== "c";',
295 ' }'
296 ].join("\n"), options);
297 parses(multiElementLabeledParser, "abc", ["a", "b", "c", ""]);
298
299 var innerElementsUnlabeledParser = PEG.buildParser([
300 'start = "a"',
301 ' ("b" "c" "d" !{ return arguments.length !== 1 || offset !== 4; })',
302 ' "e"'
303 ].join("\n"), options);
304 parses(innerElementsUnlabeledParser, "abcde", ["a", ["b", "c", "d", ""], "e"]);
305
306 var innerElementsLabeledParser = PEG.buildParser([
307 'start = "a"',
308 ' (',
309 ' b:"b" "c" d:"d" !{',
310 ' return arguments.length !== 3',
311 ' || offset !== 4',
312 ' || b !== "b"',
313 ' || d !== "d";',
314 ' }',
315 ' )',
316 ' "e"'
317 ].join("\n"), options);
318 parses(innerElementsLabeledParser, "abcde", ["a", ["b", "c", "d", ""], "e"]);
319 });
320
321 test("semantic not (with trackLineAndColumn: true)", function() {
322 var options = { trackLineAndColumn: true };
323
324 var acceptingParser = PEG.buildParser(
325 'start = "a" !{ return false; } "b"',
326 options
327 );
328 parses(acceptingParser, "ab", ["a", "", "b"]);
329
330 var rejectingParser = PEG.buildParser(
331 'start = "a" !{ return true; } "b"',
332 options
333 );
334 doesNotParse(rejectingParser, "ab");
335
336 var singleElementUnlabeledParser = PEG.buildParser([
337 'start = "a" !{',
338 ' return arguments.length !== 3',
339 ' || offset !== 1',
340 ' || line !== 1',
341 ' || column !== 2;',
342 ' }'
343 ].join("\n"), options);
344 parses(singleElementUnlabeledParser, "a", ["a", ""]);
345
346 var singleElementLabeledParser = PEG.buildParser([
347 'start = a:"a" !{',
348 ' return arguments.length !== 4',
349 ' || offset !== 1',
350 ' || line !== 1',
351 ' || column !== 2',
352 ' || a !== "a";',
353 ' }'
354 ].join("\n"), options);
355 parses(singleElementLabeledParser, "a", ["a", ""]);
356
357 var multiElementUnlabeledParser = PEG.buildParser([
358 'start = "a" "b" "c" !{',
359 ' return arguments.length !== 3',
360 ' || offset !== 3',
361 ' || line !== 1',
362 ' || column !== 4;',
363 ' }'
364 ].join("\n"), options);
365 parses(multiElementUnlabeledParser, "abc", ["a", "b", "c", ""]);
366
367 var multiElementLabeledParser = PEG.buildParser([
368 'start = a:"a" "b" c:"c" !{',
369 ' return arguments.length !== 5',
370 ' || offset !== 3',
371 ' || line !== 1',
372 ' || column !== 4',
373 ' || a !== "a"',
374 ' || c !== "c";',
375 ' }'
376 ].join("\n"), options);
377 parses(multiElementLabeledParser, "abc", ["a", "b", "c", ""]);
378
379 var innerElementsUnlabeledParser = PEG.buildParser([
380 'start = "a"',
381 ' (',
382 ' "b" "c" "d" !{',
383 ' return arguments.length !== 3',
384 ' || offset !== 4',
385 ' || line !== 1',
386 ' || column !== 5;',
387 ' }',
388 ' )',
389 ' "e"'
390 ].join("\n"), options);
391 parses(innerElementsUnlabeledParser, "abcde", ["a", ["b", "c", "d", ""], "e"]);
392
393 var innerElementsLabeledParser = PEG.buildParser([
394 'start = "a"',
395 ' (',
396 ' b:"b" "c" d:"d" !{',
397 ' return arguments.length !== 5',
398 ' || offset !== 4',
399 ' || line !== 1',
400 ' || column !== 5',
401 ' || b !== "b"',
402 ' || d !== "d";',
403 ' }',
404 ' )',
405 ' "e"'
406 ].join("\n"), options);
407 parses(innerElementsLabeledParser, "abcde", ["a", ["b", "c", "d", ""], "e"]);
408
409 var digitsParser = PEG.buildParser([
410 '{ var result; }',
411 'start = line (nl+ line)* { return result; }',
412 'line = thing (" "+ thing)*',
413 'thing = digit / mark',
414 'digit = [0-9]',
415 'mark = !{ result = [line, column]; return false; } "x"',
416 'nl = ("\\r" / "\\n" / "\\u2028" / "\\u2029")'
417 ].join("\n"), options);
418
419 parses(digitsParser, "1\n2\n\n3\n\n\n4 5 x", [7, 5]);
420
421 /* Non-Unix newlines */
422 parses(digitsParser, "1\rx", [2, 1]); // Old Mac
423 parses(digitsParser, "1\r\nx", [2, 1]); // Windows
424 parses(digitsParser, "1\n\rx", [3, 1]); // mismatched
425
426 /* Strange newlines */
427 parses(digitsParser, "1\u2028x", [2, 1]); // line separator
428 parses(digitsParser, "1\u2029x", [2, 1]); // paragraph separator
429 });
430
431 testWithVaryingTrackLineAndColumn("optional expressions", function(options) {
432 var parser = PEG.buildParser('start = "a"?', options);
433 parses(parser, "", "");
434 parses(parser, "a", "a");
435 });
436
437 testWithVaryingTrackLineAndColumn("zero or more expressions", function(options) {
438 var parser = PEG.buildParser('start = "a"*', options);
439 parses(parser, "", []);
440 parses(parser, "a", ["a"]);
441 parses(parser, "aaa", ["a", "a", "a"]);
442 });
443
444 testWithVaryingTrackLineAndColumn("one or more expressions", function(options) {
445 var parser = PEG.buildParser('start = "a"+', options);
446 doesNotParse(parser, "");
447 parses(parser, "a", ["a"]);
448 parses(parser, "aaa", ["a", "a", "a"]);
449 });
450
451 test("actions (with trackLineAndColumn: false)", function() {
452 var options = { trackLineAndColumn: false };
453
454 var singleElementUnlabeledParser = PEG.buildParser(
455 'start = "a" { return arguments.length; }',
456 options
457 );
458 parses(singleElementUnlabeledParser, "a", 1);
459
460 var singleElementLabeledParser = PEG.buildParser(
461 'start = a:"a" { return [arguments.length, offset, a]; }',
462 options
463 );
464 parses(singleElementLabeledParser, "a", [2, 0, "a"]);
465
466 var multiElementUnlabeledParser = PEG.buildParser(
467 'start = "a" "b" "c" { return arguments.length; }',
468 options
469 );
470 parses(multiElementUnlabeledParser, "abc", 1);
471
472 var multiElementLabeledParser = PEG.buildParser(
473 'start = a:"a" "b" c:"c" { return [arguments.length, offset, a, c]; }',
474 options
475 );
476 parses(multiElementLabeledParser, "abc", [3, 0, "a", "c"]);
477
478 var innerElementsUnlabeledParser = PEG.buildParser(
479 'start = "a" ("b" "c" "d" { return arguments.length; }) "e"',
480 options
481 );
482 parses(innerElementsUnlabeledParser, "abcde", ["a", 1, "e"]);
483
484 var innerElementsLabeledParser = PEG.buildParser([
485 'start = "a"',
486 ' (b:"b" "c" d:"d" { return [arguments.length, offset, b, d]; })',
487 ' "e"'
488 ].join("\n"), options);
489 parses(innerElementsLabeledParser, "abcde", ["a", [3, 1, "b", "d"], "e"]);
490
491 /*
492 * Test that the parsing position returns after successfull parsing of the
493 * action expression and action returning |null|.
494 */
495 var posTestParser = PEG.buildParser(
496 'start = "a" { return null; } / "a"',
497 options
498 );
499 parses(posTestParser, "a", "a");
500
501 /* Test that the action is not called when its expression does not match. */
502 var notAMatchParser = PEG.buildParser(
503 'start = "a" { ok(false, "action got called when it should not be"); }',
504 options
505 );
506 doesNotParse(notAMatchParser, "b");
507 });
508
509 test("actions (with trackLineAndColumn: true)", function() {
510 var options = { trackLineAndColumn: true };
511
512 var singleElementUnlabeledParser = PEG.buildParser(
513 'start = "a" { return arguments.length; }',
514 options
515 );
516 parses(singleElementUnlabeledParser, "a", 3);
517
518 var singleElementLabeledParser = PEG.buildParser(
519 'start = a:"a" { return [arguments.length, offset, line, column, a]; }',
520 options
521 );
522 parses(singleElementLabeledParser, "a", [4, 0, 1, 1, "a"]);
523
524 var multiElementUnlabeledParser = PEG.buildParser(
525 'start = "a" "b" "c" { return arguments.length; }',
526 options
527 );
528 parses(multiElementUnlabeledParser, "abc", 3);
529
530 var multiElementLabeledParser = PEG.buildParser([
531 'start = a:"a" "b" c:"c" {',
532 ' return [arguments.length, offset, line, column, a, c];',
533 '}'
534 ].join("\n"), options);
535 parses(multiElementLabeledParser, "abc", [5, 0, 1, 1, "a", "c"]);
536
537 var innerElementsUnlabeledParser = PEG.buildParser(
538 'start = "a" ("b" "c" "d" { return arguments.length; }) "e"',
539 options
540 );
541 parses(innerElementsUnlabeledParser, "abcde", ["a", 3, "e"]);
542
543 var innerElementsLabeledParser = PEG.buildParser([
544 'start = "a"',
545 ' (',
546 ' b:"b" "c" d:"d" {',
547 ' return [arguments.length, offset, line, column, b, d];',
548 ' }',
549 ' )',
550 ' "e"'
551 ].join("\n"), options);
552 parses(
553 innerElementsLabeledParser,
554 "abcde",
555 ["a", [5, 1, 1, 2, "b", "d"], "e"]
556 );
557
558 /*
559 * Test that the parsing position returns after successfull parsing of the
560 * action expression and action returning |null|.
561 */
562 var posTestParser = PEG.buildParser(
563 'start = "a" { return null; } / "a"',
564 options
565 );
566 parses(posTestParser, "a", "a");
567
568 /* Test that the action is not called when its expression does not match. */
569 var notAMatchParser = PEG.buildParser(
570 'start = "a" { ok(false, "action got called when it should not be"); }',
571 options
572 );
573 doesNotParse(notAMatchParser, "b");
574
575 var numbersParser = PEG.buildParser([
576 '{ var result; }',
577 'start = line (nl+ line)* { return result; }',
578 'line = thing (" "+ thing)*',
579 'thing = digit / mark',
580 'digit = [0-9]',
581 'mark = "x" { result = [line, column]; }',
582 'nl = ("\\r" / "\\n" / "\\u2028" / "\\u2029")'
583 ].join("\n"), options);
584
585 parses(numbersParser, "1\n2\n\n3\n\n\n4 5 x", [7, 5]);
586
587 /* Non-Unix newlines */
588 parses(numbersParser, "1\rx", [2, 1]); // Old Mac
589 parses(numbersParser, "1\r\nx", [2, 1]); // Windows
590 parses(numbersParser, "1\n\rx", [3, 1]); // mismatched
591
592 /* Strange newlines */
593 parses(numbersParser, "1\u2028x", [2, 1]); // line separator
594 parses(numbersParser, "1\u2029x", [2, 1]); // paragraph separator
595 });
596
597 testWithVaryingTrackLineAndColumn("initializer", function(options) {
598 var variableInActionParser = PEG.buildParser(
599 '{ a = 42; }; start = "a" { return a; }',
600 options
601 );
602 parses(variableInActionParser, "a", 42);
603
604 var functionInActionParser = PEG.buildParser(
605 '{ function f() { return 42; } }; start = "a" { return f(); }',
606 options
607 );
608 parses(functionInActionParser, "a", 42);
609
610 var variableInSemanticAndParser = PEG.buildParser(
611 '{ a = 42; }; start = "a" &{ return a === 42; }',
612 options
613 );
614 parses(variableInSemanticAndParser, "a", ["a", ""]);
615
616 var functionInSemanticAndParser = PEG.buildParser(
617 '{ function f() { return 42; } }; start = "a" &{ return f() === 42; }',
618 options
619 );
620 parses(functionInSemanticAndParser, "a", ["a", ""]);
621
622 var variableInSemanticNotParser = PEG.buildParser(
623 '{ a = 42; }; start = "a" !{ return a !== 42; }',
624 options
625 );
626 parses(variableInSemanticNotParser, "a", ["a", ""]);
627
628 var functionInSemanticNotParser = PEG.buildParser(
629 '{ function f() { return 42; } }; start = "a" !{ return f() !== 42; }',
630 options
631 );
632 parses(functionInSemanticNotParser, "a", ["a", ""]);
633 });
634
635 testWithVaryingTrackLineAndColumn("rule references", function(options) {
636 var parser = PEG.buildParser([
637 'start = static / dynamic',
638 'static = "C" / "C++" / "Java" / "C#"',
639 'dynamic = "Ruby" / "Python" / "JavaScript"'
640 ].join("\n"), options);
641 parses(parser, "Java", "Java");
642 parses(parser, "Python", "Python");
643 });
644
645 testWithVaryingTrackLineAndColumn("literals", function(options) {
646 var zeroCharParser = PEG.buildParser('start = ""', options);
647 parses(zeroCharParser, "", "");
648 doesNotParse(zeroCharParser, "a");
649
650 var oneCharCaseSensitiveParser = PEG.buildParser('start = "a"', options);
651 parses(oneCharCaseSensitiveParser, "a", "a");
652 doesNotParse(oneCharCaseSensitiveParser, "");
653 doesNotParse(oneCharCaseSensitiveParser, "A");
654 doesNotParse(oneCharCaseSensitiveParser, "b");
655
656 var multiCharCaseSensitiveParser = PEG.buildParser('start = "abcd"', options);
657 parses(multiCharCaseSensitiveParser, "abcd", "abcd");
658 doesNotParse(multiCharCaseSensitiveParser, "");
659 doesNotParse(multiCharCaseSensitiveParser, "abc");
660 doesNotParse(multiCharCaseSensitiveParser, "abcde");
661 doesNotParse(multiCharCaseSensitiveParser, "ABCD");
662 doesNotParse(multiCharCaseSensitiveParser, "efgh");
663
664 var oneCharCaseInsensitiveParser = PEG.buildParser('start = "a"i', options);
665 parses(oneCharCaseInsensitiveParser, "a", "a");
666 parses(oneCharCaseInsensitiveParser, "A", "A");
667 doesNotParse(oneCharCaseInsensitiveParser, "");
668 doesNotParse(oneCharCaseInsensitiveParser, "b");
669
670 var multiCharCaseInsensitiveParser = PEG.buildParser(
671 'start = "abcd"i',
672 options
673 );
674 parses(multiCharCaseInsensitiveParser, "abcd", "abcd");
675 parses(multiCharCaseInsensitiveParser, "ABCD", "ABCD");
676 doesNotParse(multiCharCaseInsensitiveParser, "");
677 doesNotParse(multiCharCaseInsensitiveParser, "abc");
678 doesNotParse(multiCharCaseInsensitiveParser, "abcde");
679 doesNotParse(multiCharCaseInsensitiveParser, "efgh");
680
681 /*
682 * Test that the parsing position moves forward after successful parsing of
683 * a literal.
684 */
685 var posTestParser = PEG.buildParser('start = "a" "b"', options);
686 parses(posTestParser, "ab", ["a", "b"]);
687 });
688
689 testWithVaryingTrackLineAndColumn("anys", function(options) {
690 var parser = PEG.buildParser('start = .', options);
691 parses(parser, "a", "a");
692 doesNotParse(parser, "");
693 doesNotParse(parser, "ab");
694
695 /*
696 * Test that the parsing position moves forward after successful parsing of
697 * an any.
698 */
699 var posTestParser = PEG.buildParser('start = . .', options);
700 parses(posTestParser, "ab", ["a", "b"]);
701 });
702
703 testWithVaryingTrackLineAndColumn("classes", function(options) {
704 var emptyClassParser = PEG.buildParser('start = []', options);
705 doesNotParse(emptyClassParser, "");
706 doesNotParse(emptyClassParser, "a");
707 doesNotParse(emptyClassParser, "ab");
708
709 var invertedEmptyClassParser = PEG.buildParser('start = [^]', options);
710 doesNotParse(invertedEmptyClassParser, "");
711 parses(invertedEmptyClassParser, "a", "a");
712 doesNotParse(invertedEmptyClassParser, "ab");
713
714 var nonEmptyCaseSensitiveClassParser = PEG.buildParser(
715 'start = [ab-d]',
716 options
717 );
718 parses(nonEmptyCaseSensitiveClassParser, "a", "a");
719 parses(nonEmptyCaseSensitiveClassParser, "b", "b");
720 parses(nonEmptyCaseSensitiveClassParser, "c", "c");
721 parses(nonEmptyCaseSensitiveClassParser, "d", "d");
722 doesNotParse(nonEmptyCaseSensitiveClassParser, "");
723 doesNotParse(nonEmptyCaseSensitiveClassParser, "A");
724 doesNotParse(nonEmptyCaseSensitiveClassParser, "B");
725 doesNotParse(nonEmptyCaseSensitiveClassParser, "C");
726 doesNotParse(nonEmptyCaseSensitiveClassParser, "D");
727 doesNotParse(nonEmptyCaseSensitiveClassParser, "e");
728 doesNotParse(nonEmptyCaseSensitiveClassParser, "ab");
729
730 var invertedNonEmptyCaseSensitiveClassParser = PEG.buildParser(
731 'start = [^ab-d]',
732 options
733 );
734 parses(invertedNonEmptyCaseSensitiveClassParser, "A", "A");
735 parses(invertedNonEmptyCaseSensitiveClassParser, "B", "B");
736 parses(invertedNonEmptyCaseSensitiveClassParser, "C", "C");
737 parses(invertedNonEmptyCaseSensitiveClassParser, "D", "D");
738 parses(invertedNonEmptyCaseSensitiveClassParser, "e", "e");
739 doesNotParse(invertedNonEmptyCaseSensitiveClassParser, "a", "a");
740 doesNotParse(invertedNonEmptyCaseSensitiveClassParser, "b", "b");
741 doesNotParse(invertedNonEmptyCaseSensitiveClassParser, "c", "c");
742 doesNotParse(invertedNonEmptyCaseSensitiveClassParser, "d", "d");
743 doesNotParse(invertedNonEmptyCaseSensitiveClassParser, "");
744 doesNotParse(invertedNonEmptyCaseSensitiveClassParser, "ab");
745
746 var nonEmptyCaseInsensitiveClassParser = PEG.buildParser(
747 'start = [ab-d]i',
748 options
749 );
750 parses(nonEmptyCaseInsensitiveClassParser, "a", "a");
751 parses(nonEmptyCaseInsensitiveClassParser, "b", "b");
752 parses(nonEmptyCaseInsensitiveClassParser, "c", "c");
753 parses(nonEmptyCaseInsensitiveClassParser, "d", "d");
754 parses(nonEmptyCaseInsensitiveClassParser, "A", "A");
755 parses(nonEmptyCaseInsensitiveClassParser, "B", "B");
756 parses(nonEmptyCaseInsensitiveClassParser, "C", "C");
757 parses(nonEmptyCaseInsensitiveClassParser, "D", "D");
758 doesNotParse(nonEmptyCaseInsensitiveClassParser, "");
759 doesNotParse(nonEmptyCaseInsensitiveClassParser, "e");
760 doesNotParse(nonEmptyCaseInsensitiveClassParser, "ab");
761
762 var invertedNonEmptyCaseInsensitiveClassParser = PEG.buildParser(
763 'start = [^ab-d]i',
764 options
765 );
766 parses(invertedNonEmptyCaseInsensitiveClassParser, "e", "e");
767 doesNotParse(invertedNonEmptyCaseInsensitiveClassParser, "a", "a");
768 doesNotParse(invertedNonEmptyCaseInsensitiveClassParser, "b", "b");
769 doesNotParse(invertedNonEmptyCaseInsensitiveClassParser, "c", "c");
770 doesNotParse(invertedNonEmptyCaseInsensitiveClassParser, "d", "d");
771 doesNotParse(invertedNonEmptyCaseInsensitiveClassParser, "A", "A");
772 doesNotParse(invertedNonEmptyCaseInsensitiveClassParser, "B", "B");
773 doesNotParse(invertedNonEmptyCaseInsensitiveClassParser, "C", "C");
774 doesNotParse(invertedNonEmptyCaseInsensitiveClassParser, "D", "D");
775 doesNotParse(invertedNonEmptyCaseInsensitiveClassParser, "");
776 doesNotParse(invertedNonEmptyCaseInsensitiveClassParser, "ab");
777
778 /*
779 * Test that the parsing position moves forward after successful parsing of
780 * a class.
781 */
782 var posTestParser = PEG.buildParser('start = [ab-d] [ab-d]', options);
783 parses(posTestParser, "ab", ["a", "b"]);
784 });
785
786 testWithVaryingTrackLineAndColumn("cache", function(options) {
787 var grammar = [
788 '{ var n = 0; }',
789 'start = (a "b") / (a "c") { return n; }',
790 'a = "a" { n++; }'
791 ].join("\n");
792
793 /* Without cache */
794
795 parses(PEG.buildParser(grammar, options), "ac", 2);
796
797 options.cache = false;
798 parses(PEG.buildParser(grammar, options), "ac", 2);
799
800 /* With cache */
801
802 options.cache = true;
803 parses(PEG.buildParser(grammar, options), "ac", 1);
804 });
805
806 testWithVaryingTrackLineAndColumn("indempotence", function(options) {
807 var parser1 = PEG.buildParser('start = "abcd"', options);
808 var parser2 = PEG.buildParser('start = "abcd"', options);
809
810 strictEqual(parser1.toSource(), parser2.toSource());
811 });
812
813 testWithVaryingTrackLineAndColumn("error details", function(options) {
814 var literalParser = PEG.buildParser('start = "abcd"', options);
815 doesNotParseWithDetails(
816 literalParser,
817 "",
818 ["\"abcd\""],
819 null,
820 'Expected "abcd" but end of input found.'
821 );
822 doesNotParseWithDetails(
823 literalParser,
824 "efgh",
825 ["\"abcd\""],
826 "e",
827 'Expected "abcd" but "e" found.'
828 );
829 doesNotParseWithDetails(
830 literalParser,
831 "abcde",
832 [],
833 "e",
834 'Expected end of input but "e" found.'
835 );
836
837 var classParser = PEG.buildParser('start = [a-d]', options);
838 doesNotParseWithDetails(
839 classParser,
840 "",
841 ["[a-d]"],
842 null,
843 'Expected [a-d] but end of input found.'
844 );
845 var negativeClassParser = PEG.buildParser('start = [^a-d]', options);
846 doesNotParseWithDetails(
847 negativeClassParser,
848 "",
849 ["[^a-d]"],
850 null,
851 'Expected [^a-d] but end of input found.'
852 );
853
854 var anyParser = PEG.buildParser('start = .', options);
855 doesNotParseWithDetails(
856 anyParser,
857 "",
858 ["any character"],
859 null,
860 'Expected any character but end of input found.'
861 );
862
863 var namedRuleWithLiteralParser = PEG.buildParser(
864 'start "digit" = [0-9]',
865 options
866 );
867 doesNotParseWithDetails(
868 namedRuleWithLiteralParser,
869 "a",
870 ["digit"],
871 "a",
872 'Expected digit but "a" found.'
873 );
874
875 var namedRuleWithAnyParser = PEG.buildParser('start "whatever" = .', options);
876 doesNotParseWithDetails(
877 namedRuleWithAnyParser,
878 "",
879 ["whatever"],
880 null,
881 'Expected whatever but end of input found.'
882 );
883
884 var namedRuleWithNamedRuleParser = PEG.buildParser([
885 'start "digits" = digit+',
886 'digit "digit" = [0-9]'
887 ].join("\n"), options);
888 doesNotParseWithDetails(
889 namedRuleWithNamedRuleParser,
890 "",
891 ["digits"],
892 null,
893 'Expected digits but end of input found.'
894 );
895
896 var choiceParser1 = PEG.buildParser('start = "a" / "b" / "c"', options);
897 doesNotParseWithDetails(
898 choiceParser1,
899 "def",
900 ["\"a\"", "\"b\"", "\"c\""],
901 "d",
902 'Expected "a", "b" or "c" but "d" found.'
903 );
904
905 var choiceParser2 = PEG.buildParser('start = "a" "b" "c" / "a"', options);
906 doesNotParseWithDetails(
907 choiceParser2,
908 "abd",
909 ["\"c\""],
910 "d",
911 'Expected "c" but "d" found.'
912 );
913
914 var simpleNotParser = PEG.buildParser('start = !"a" "b"', options);
915 doesNotParseWithDetails(
916 simpleNotParser,
917 "c",
918 ["\"b\""],
919 "c",
920 'Expected "b" but "c" found.'
921 );
922
923 var simpleAndParser = PEG.buildParser('start = &"a" [a-b]', options);
924 doesNotParseWithDetails(
925 simpleAndParser,
926 "c",
927 [],
928 "c",
929 'Expected end of input but "c" found.'
930 );
931
932 var emptyParser = PEG.buildParser('start = ', options);
933 doesNotParseWithDetails(
934 emptyParser,
935 "something",
936 [],
937 "s",
938 'Expected end of input but "s" found.'
939 );
940
941 var duplicateErrorParser = PEG.buildParser('start = "a" / "a"', options);
942 doesNotParseWithDetails(
943 duplicateErrorParser,
944 "",
945 ["\"a\""],
946 null,
947 'Expected "a" but end of input found.'
948 );
949
950 var unsortedErrorsParser = PEG.buildParser('start = "b" / "a"', options);
951 doesNotParseWithDetails(
952 unsortedErrorsParser,
953 "",
954 ["\"a\"", "\"b\""],
955 null,
956 'Expected "a" or "b" but end of input found.'
957 );
958 });
959
960 testWithVaryingTrackLineAndColumn("error positions", function(options) {
961 var simpleParser = PEG.buildParser('start = "a"', options);
962
963 /* Regular match failure */
964 doesNotParseWithPos(simpleParser, "b", 0, 1, 1);
965
966 /* Trailing input */
967 doesNotParseWithPos(simpleParser, "ab", 1, 1, 2);
968
969 var digitsParser = PEG.buildParser([
970 'start = line (("\\r" / "\\n" / "\\u2028" / "\\u2029")+ line)*',
971 'line = digits (" "+ digits)*',
972 'digits = digits:[0-9]+ { return digits.join(""); }'
973 ].join("\n"), options);
974
975 doesNotParseWithPos(digitsParser, "1\n2\n\n3\n\n\n4 5 x", 13, 7, 5);
976
977 /* Non-Unix newlines */
978 doesNotParseWithPos(digitsParser, "1\rx", 2, 2, 1); // Old Mac
979 doesNotParseWithPos(digitsParser, "1\r\nx", 3, 2, 1); // Windows
980 doesNotParseWithPos(digitsParser, "1\n\rx", 3, 3, 1); // mismatched
981
982 /* Strange newlines */
983 doesNotParseWithPos(digitsParser, "1\u2028x", 2, 2, 1); // line separator
984 doesNotParseWithPos(digitsParser, "1\u2029x", 2, 2, 1); // paragraph separator
985 });
986
987 testWithVaryingTrackLineAndColumn("start rule", function(options) {
988 var parser = PEG.buildParser([
989 'a = .* { return "alpha"; }',
990 'b = .* { return "beta"; }'
991 ].join("\n"), options);
992
993 /* Default start rule = the first one */
994 parses(parser, "whatever", "alpha");
995
996 /* Explicit specification of the start rule */
997 parsesWithStartRule(parser, "whatever", "a", "alpha");
998 parsesWithStartRule(parser, "whatever", "b", "beta");
999
1000 /* Invalid rule name */
1001 raises(
1002 function() { parser.parse("whatever", "c"); },
1003 function(e) {
1004 return e instanceof Error && e.message === "Invalid rule name: \"c\".";
1005 }
1006 );
1007 });
1008
1009 /*
1010 * Following examples are from Wikipedia, see
1011 * http://en.wikipedia.org/w/index.php?title=Parsing_expression_grammar&oldid=335106938.
1012 */
1013
1014 testWithVaryingTrackLineAndColumn("arithmetics", function(options) {
1015 /*
1016 * Value ← [0-9]+ / '(' Expr ')'
1017 * Product ← Value (('*' / '/') Value)*
1018 * Sum ← Product (('+' / '-') Product)*
1019 * Expr ← Sum
1020 */
1021 var parser = PEG.buildParser([
1022 'Expr = Sum',
1023 'Sum = head:Product tail:(("+" / "-") Product)* {',
1024 ' var result = head;',
1025 ' for (var i = 0; i < tail.length; i++) {',
1026 ' if (tail[i][0] == "+") { result += tail[i][1]; }',
1027 ' if (tail[i][0] == "-") { result -= tail[i][1]; }',
1028 ' }',
1029 ' return result;',
1030 ' }',
1031 'Product = head:Value tail:(("*" / "/") Value)* {',
1032 ' var result = head;',
1033 ' for (var i = 0; i < tail.length; i++) {',
1034 ' if (tail[i][0] == "*") { result *= tail[i][1]; }',
1035 ' if (tail[i][0] == "/") { result /= tail[i][1]; }',
1036 ' }',
1037 ' return result;',
1038 ' }',
1039 'Value = digits:[0-9]+ { return parseInt(digits.join("")); }',
1040 ' / "(" expr:Expr ")" { return expr; }'
1041 ].join("\n"), options);
1042
1043 /* Test "value" rule. */
1044 parses(parser, "0", 0);
1045 parses(parser, "123", 123);
1046 parses(parser, "(42+43)", 42+43);
1047
1048 /* Test "product" rule. */
1049 parses(parser, "42", 42);
1050 parses(parser, "42*43", 42*43);
1051 parses(parser, "42*43*44*45", 42*43*44*45);
1052 parses(parser, "42/43", 42/43);
1053 parses(parser, "42/43/44/45", 42/43/44/45);
1054
1055 /* Test "sum" rule. */
1056 parses(parser, "42*43", 42*43);
1057 parses(parser, "42*43+44*45", 42*43+44*45);
1058 parses(parser, "42*43+44*45+46*47+48*49", 42*43+44*45+46*47+48*49);
1059 parses(parser, "42*43-44*45", 42*43-44*45);
1060 parses(parser, "42*43-44*45-46*47-48*49", 42*43-44*45-46*47-48*49);
1061
1062 /* Test "expr" rule. */
1063 parses(parser, "42+43", 42+43);
1064
1065 /* Complex test */
1066 parses(parser, "(1+2)*(3+4)",(1+2)*(3+4));
1067 });
1068
1069 testWithVaryingTrackLineAndColumn("non-context-free language", function(options) {
1070 /* The following parsing expression grammar describes the classic
1071 * non-context-free language { a^n b^n c^n : n >= 1 }:
1072 *
1073 * S ← &(A c) a+ B !(a/b/c)
1074 * A ← a A? b
1075 * B ← b B? c
1076 */
1077 var parser = PEG.buildParser([
1078 'S = &(A "c") a:"a"+ B:B !("a" / "b" / "c") { return a.join("") + B; }',
1079 'A = a:"a" A:A? b:"b" { return a + A + b; }',
1080 'B = b:"b" B:B? c:"c" { return b + B + c; }'
1081 ].join("\n"), options);
1082
1083 parses(parser, "abc", "abc");
1084 parses(parser, "aaabbbccc", "aaabbbccc");
1085 doesNotParse(parser, "aabbbccc");
1086 doesNotParse(parser, "aaaabbbccc");
1087 doesNotParse(parser, "aaabbccc");
1088 doesNotParse(parser, "aaabbbbccc");
1089 doesNotParse(parser, "aaabbbcc");
1090 doesNotParse(parser, "aaabbbcccc");
1091 });
1092
1093 testWithVaryingTrackLineAndColumn("nested comments", function(options) {
1094 /*
1095 * Begin ← "(*"
1096 * End ← "*)"
1097 * C ← Begin N* End
1098 * N ← C / (!Begin !End Z)
1099 * Z ← any single character
1100 */
1101 var parser = PEG.buildParser([
1102 'C = begin:Begin ns:N* end:End { return begin + ns.join("") + end; }',
1103 'N = C',
1104 ' / !Begin !End z:Z { return z; }',
1105 'Z = .',
1106 'Begin = "(*"',
1107 'End = "*)"'
1108 ].join("\n"), options);
1109
1110 parses(parser, "(**)", "(**)");
1111 parses(parser, "(*abc*)", "(*abc*)");
1112 parses(parser, "(*(**)*)", "(*(**)*)");
1113 parses(
1114 parser,
1115 "(*abc(*def*)ghi(*(*(*jkl*)*)*)mno*)",
1116 "(*abc(*def*)ghi(*(*(*jkl*)*)*)mno*)"
1117 );
1118 });
1119
1120 })();
+0
-72
test/helpers.js less more
0 (function(global) {
1
2 var extensions = {
3 parses: function(parser, input, expected) {
4 QUnit.deepEqual(parser.parse(input), expected);
5 },
6
7 parsesWithStartRule: function(parser, input, startRule, expected) {
8 QUnit.deepEqual(parser.parse(input, startRule), expected);
9 },
10
11 doesNotParse: function(parser, input) {
12 QUnit.raises(function() { parser.parse(input); }, parser.SyntaxError);
13 },
14
15 doesNotParseWithMessage: function(parser, input, message) {
16 QUnit.raises(
17 function() { parser.parse(input); },
18 function(e) {
19 return e instanceof parser.SyntaxError && e.message === message;
20 }
21 );
22 },
23
24 doesNotParseWithDetails: function(parser, input, expected, found, message) {
25 QUnit.raises(
26 function() { parser.parse(input); },
27 function(e) {
28 var i;
29
30 if (!(e instanceof parser.SyntaxError)) { return false; }
31 if (e.expected.length !== expected.length) { return false; }
32 for (i = 0; i < e.expected.length; i++) {
33 if (e.expected[i] !== expected[i]) { return false; }
34 }
35 if (e.found !== found) { return false; }
36 if (e.message !== message) { return false; }
37
38 return true;
39 }
40 );
41 },
42
43 doesNotParseWithPos: function(parser, input, offset, line, column) {
44 QUnit.raises(
45 function() { parser.parse(input); },
46 function(e) {
47 return e instanceof parser.SyntaxError
48 && e.offset === offset
49 && e.line === line
50 && e.column === column;
51 }
52 );
53 },
54
55 parserParses: function(input, expected) {
56 QUnit.parses(PEG.parser, input, expected);
57 },
58
59 parserDoesNotParse: function(input) {
60 QUnit.doesNotParse(PEG.parser, input);
61 },
62
63 parserDoesNotParseWithMessage: function(input, message) {
64 QUnit.doesNotParseWithMessage(PEG.parser, input, message);
65 }
66 };
67
68 QUnit.extend(QUnit, extensions);
69 QUnit.extend(global, extensions);
70
71 })(this);
+0
-21
test/index.html less more
0 <!DOCTYPE html>
1 <html>
2 <head>
3 <meta charset="utf-8">
4 <title>PEG.js Test Suite</title>
5 <link rel="stylesheet" href="vendor/qunit/qunit.css">
6 <script src="../lib/peg.js"></script>
7 <script src="vendor/qunit/qunit.js"></script>
8 <script src="helpers.js"></script>
9 <script src="parser-test.js"></script>
10 <script src="passes-test.js"></script>
11 <script src="compiler-test.js"></script>
12 </head>
13 <body>
14 <h1 id="qunit-header">PEG.js Test Suite</h1>
15 <h2 id="qunit-banner"></h2>
16 <div id="qunit-testrunner-toolbar"></div>
17 <h2 id="qunit-userAgent"></h2>
18 <ol id="qunit-tests"></ol>
19 </body>
20 </html>
+0
-610
test/parser-test.js less more
0 (function() {
1
2 module("PEG.parser");
3
4 function initializer(code) {
5 return {
6 type: "initializer",
7 code: code
8 };
9 }
10
11 function rule(name, displayName, expression) {
12 return {
13 type: "rule",
14 name: name,
15 displayName: displayName,
16 expression: expression
17 };
18 }
19
20 function choice(alternatives) {
21 return {
22 type: "choice",
23 alternatives: alternatives
24 };
25 }
26
27 function sequence(elements) {
28 return {
29 type: "sequence",
30 elements: elements
31 };
32 }
33
34 function labeled(label, expression) {
35 return {
36 type: "labeled",
37 label: label,
38 expression: expression
39 };
40 }
41
42 function nodeWithExpressionConstructor(type) {
43 return function(expression) {
44 return {
45 type: type,
46 expression: expression
47 };
48 };
49 }
50
51 function nodeWithCodeConstructor(type) {
52 return function(code) {
53 return {
54 type: type,
55 code: code
56 };
57 };
58 }
59
60 var simpleAnd = nodeWithExpressionConstructor("simple_and");
61 var simpleNot = nodeWithExpressionConstructor("simple_not");
62
63 var semanticAnd = nodeWithCodeConstructor("semantic_and");
64 var semanticNot = nodeWithCodeConstructor("semantic_not");
65
66 var optional = nodeWithExpressionConstructor("optional");
67 var zeroOrMore = nodeWithExpressionConstructor("zero_or_more");
68 var oneOrMore = nodeWithExpressionConstructor("one_or_more");
69
70 function action(expression, code) {
71 return {
72 type: "action",
73 expression: expression,
74 code: code
75 };
76 }
77
78 function ruleRef(name) {
79 return {
80 type: "rule_ref",
81 name: name
82 };
83 }
84
85 function literal(value, ignoreCase) {
86 return {
87 type: "literal",
88 value: value,
89 ignoreCase: ignoreCase
90 };
91 }
92
93 function any() {
94 return { type: "any" };
95 }
96
97 function klass(inverted, ignoreCase, parts, rawText) {
98 return {
99 type: "class",
100 inverted: inverted,
101 ignoreCase: ignoreCase,
102 parts: parts,
103 rawText: rawText
104 };
105 }
106
107 var literalAbcd = literal("abcd", false);
108 var literalEfgh = literal("efgh", false);
109 var literalIjkl = literal("ijkl", false);
110
111 var optionalLiteral = optional(literalAbcd);
112
113 var labeledAbcd = labeled("a", literalAbcd);
114 var labeledEfgh = labeled("e", literalEfgh);
115 var labeledIjkl = labeled("i", literalIjkl);
116
117 var sequenceEmpty = sequence([]);
118 var sequenceLabeleds = sequence([labeledAbcd, labeledEfgh, labeledIjkl]);
119 var sequenceLiterals = sequence([literalAbcd, literalEfgh, literalIjkl]);
120
121 var choiceLiterals = choice([literalAbcd, literalEfgh, literalIjkl]);
122
123 function oneRuleGrammar(expression) {
124 return {
125 type: "grammar",
126 initializer: null,
127 rules: [rule("start", null, expression)],
128 startRule: "start"
129 };
130 }
131
132 var simpleGrammar = oneRuleGrammar(literal("abcd", false));
133
134 function identifierGrammar(identifier) {
135 return oneRuleGrammar(ruleRef(identifier));
136 }
137
138 var literal_ = literal;
139 function literalGrammar(literal) {
140 return oneRuleGrammar(literal_(literal, false));
141 }
142
143 function classGrammar(inverted, parts, rawText) {
144 return oneRuleGrammar(klass(inverted, false, parts, rawText));
145 }
146
147 var anyGrammar = oneRuleGrammar(any());
148
149 var action_ = action;
150 function actionGrammar(action) {
151 return oneRuleGrammar(action_(literal("a", false), action));
152 }
153
154 var initializerGrammar = {
155 type: "grammar",
156 initializer: initializer(" code "),
157 rules: [rule("a", null, literalAbcd)],
158 startRule: "a"
159 };
160
161 var namedRuleGrammar = {
162 type: "grammar",
163 initializer: null,
164 rules: [rule("start", "abcd", literalAbcd)],
165 startRule: "start"
166 };
167
168 /* Canonical grammar is "a: \"abcd\"; b: \"efgh\"; c: \"ijkl\";". */
169 test("parses grammar", function() {
170 parserParses(
171 'a = "abcd"',
172 {
173 type: "grammar",
174 initializer: null,
175 rules: [rule("a", null, literalAbcd)],
176 startRule: "a"
177 }
178 );
179 parserParses('{ code }; a = "abcd"', initializerGrammar);
180 parserParses(
181 'a = "abcd"; b = "efgh"; c = "ijkl"',
182 {
183 type: "grammar",
184 initializer: null,
185 rules: [
186 rule("a", null, literalAbcd),
187 rule("b", null, literalEfgh),
188 rule("c", null, literalIjkl)
189 ],
190 startRule: "a"
191 }
192 );
193 });
194
195 /* Canonical initializer is "{ code }". */
196 test("parses initializer", function() {
197 parserParses('{ code }a = "abcd"', initializerGrammar);
198 parserParses('{ code };a = "abcd"', initializerGrammar);
199 });
200
201 /* Canonical rule is "a: \"abcd\"". */
202 test("parses rule", function() {
203 parserParses(
204 'start = "abcd" / "efgh" / "ijkl"',
205 oneRuleGrammar(choiceLiterals)
206 );
207 parserParses(
208 'start "start rule" = "abcd" / "efgh" / "ijkl"',
209 {
210 type: "grammar",
211 initializer: null,
212 rules: [rule("start", "start rule", choiceLiterals)],
213 startRule: "start"
214 }
215 );
216 parserParses(
217 'start = "abcd" / "efgh" / "ijkl";',
218 oneRuleGrammar(choiceLiterals)
219 );
220 });
221
222 /* Canonical expression is "\"abcd\" / \"efgh\" / \"ijkl\"". */
223 test("parses expression", function() {
224 parserParses(
225 'start = "abcd" / "efgh" / "ijkl"',
226 oneRuleGrammar(choiceLiterals)
227 );
228 });
229
230 /* Canonical choice is "\"abcd\" / \"efgh\" / \"ijkl\"". */
231 test("parses choice", function() {
232 parserParses(
233 'start = "abcd" "efgh" "ijkl"',
234 oneRuleGrammar(sequenceLiterals)
235 );
236 parserParses(
237 'start = "abcd" "efgh" "ijkl" / "abcd" "efgh" "ijkl" / "abcd" "efgh" "ijkl"',
238 oneRuleGrammar(choice([
239 sequenceLiterals,
240 sequenceLiterals,
241 sequenceLiterals
242 ]))
243 );
244 });
245
246 /* Canonical sequence is "\"abcd\" \"efgh\" \"ijkl\"". */
247 test("parses sequence", function() {
248 parserParses(
249 'start = { code }',
250 oneRuleGrammar(action(sequenceEmpty, " code "))
251 );
252 parserParses(
253 'start = a:"abcd" { code }',
254 oneRuleGrammar(action(labeledAbcd, " code "))
255 );
256 parserParses(
257 'start = a:"abcd" e:"efgh" i:"ijkl" { code }',
258 oneRuleGrammar(action(sequenceLabeleds, " code "))
259 );
260
261 parserParses('start = ', oneRuleGrammar(sequenceEmpty));
262 parserParses('start = a:"abcd"', oneRuleGrammar(labeledAbcd));
263 parserParses(
264 'start = a:"abcd" e:"efgh" i:"ijkl"',
265 oneRuleGrammar(sequenceLabeleds)
266 );
267 });
268
269 /* Canonical labeled is "label:\"abcd\"". */
270 test("parses labeled", function() {
271 parserParses(
272 'start = label:!"abcd"',
273 oneRuleGrammar(labeled("label", simpleNot(literalAbcd)))
274 );
275 parserParses('start = !"abcd"', oneRuleGrammar(simpleNot(literalAbcd)));
276 });
277
278 /* Canonical prefixed is "!\"abcd\"". */
279 test("parses prefixed", function() {
280 parserParses('start = &{ code }', oneRuleGrammar(semanticAnd(" code ")));
281 parserParses('start = &"abcd"?', oneRuleGrammar(simpleAnd(optionalLiteral)));
282 parserParses('start = !{ code }', oneRuleGrammar(semanticNot(" code ")));
283 parserParses('start = !"abcd"?', oneRuleGrammar(simpleNot(optionalLiteral)));
284 parserParses('start = "abcd"?', oneRuleGrammar(optionalLiteral));
285 });
286
287 /* Canonical suffixed is "\"abcd\"?". */
288 test("parses suffixed", function() {
289 parserParses('start = "abcd"?', oneRuleGrammar(optionalLiteral));
290 parserParses('start = "abcd"*', oneRuleGrammar(zeroOrMore(literalAbcd)));
291 parserParses('start = "abcd"+', oneRuleGrammar(oneOrMore(literalAbcd)));
292 parserParses('start = "abcd"', literalGrammar("abcd"));
293 });
294
295 /* Canonical primary is "\"abcd\"". */
296 test("parses primary", function() {
297 parserParses('start = a', identifierGrammar("a"));
298 parserParses('start = "abcd"', literalGrammar("abcd"));
299 parserParses('start = .', anyGrammar);
300 parserParses('start = [a-d]', classGrammar(false, [["a", "d"]], "[a-d]"));
301 parserParses('start = ("abcd")', literalGrammar("abcd"));
302 });
303
304 /* Canonical action is "{ code }". */
305 test("parses action", function() {
306 parserParses('start = "a" { code }', actionGrammar(" code "));
307 });
308
309 /* Canonical braced is "{ code }". */
310 test("parses braced", function() {
311 parserParses('start = "a" {}', actionGrammar(""));
312 parserParses('start = "a" {a}', actionGrammar("a"));
313 parserParses('start = "a" {{a}}', actionGrammar("{a}"));
314 parserParses('start = "a" {aaa}', actionGrammar("aaa"));
315 });
316
317 /* Trivial character rules are not tested. */
318
319 /* Canonical identifier is "a". */
320 test("parses identifier", function() {
321 parserParses('start = a', identifierGrammar("a"));
322 parserParses('start = z', identifierGrammar("z"));
323 parserParses('start = A', identifierGrammar("A"));
324 parserParses('start = Z', identifierGrammar("Z"));
325 parserParses('start = _', identifierGrammar("_"));
326 parserParses('start = $', identifierGrammar("$"));
327 parserParses('start = aa', identifierGrammar("aa"));
328 parserParses('start = az', identifierGrammar("az"));
329 parserParses('start = aA', identifierGrammar("aA"));
330 parserParses('start = aZ', identifierGrammar("aZ"));
331 parserParses('start = a0', identifierGrammar("a0"));
332 parserParses('start = a9', identifierGrammar("a9"));
333 parserParses('start = a_', identifierGrammar("a_"));
334 parserParses('start = a$', identifierGrammar("a$"));
335 parserParses('start = abcd', identifierGrammar("abcd"));
336
337 parserParses('start = a\n', identifierGrammar("a"));
338 });
339
340 /* Canonical literal is "\"abcd\"". */
341 test("parses literal", function() {
342 parserParses('start = "abcd"', literalGrammar("abcd"));
343 parserParses("start = 'abcd'", literalGrammar("abcd"));
344 parserParses('start = "abcd"i', oneRuleGrammar(literal("abcd", true)));
345
346 parserParses('start = "abcd"\n', literalGrammar("abcd"));
347 });
348
349 /* Canonical string is "\"abcd\"". */
350 test("parses string", function() {
351 parserParses('start "abcd" = "abcd"', namedRuleGrammar);
352 parserParses('start \'abcd\' = "abcd"', namedRuleGrammar);
353
354 parserParses('start "abcd"\n= "abcd"', namedRuleGrammar);
355 });
356
357 /* Canonical doubleQuotedString is "\"abcd\"". */
358 test("parses doubleQuotedString", function() {
359 parserParses('start = ""', literalGrammar(""));
360 parserParses('start = "a"', literalGrammar("a"));
361 parserParses('start = "abc"', literalGrammar("abc"));
362 });
363
364 /* Canonical doubleQuotedCharacter is "a". */
365 test("parses doubleQuotedCharacter", function() {
366 parserParses('start = "a"', literalGrammar("a"));
367 parserParses('start = "\\n"', literalGrammar("\n"));
368 parserParses('start = "\\0"', literalGrammar("\x00"));
369 parserParses('start = "\\x00"', literalGrammar("\x00"));
370 parserParses('start = "\\u0120"', literalGrammar("\u0120"));
371 parserParses('start = "\\\n"', literalGrammar("\n"));
372 });
373
374 /* Canonical simpleDoubleQuotedCharacter is "a". */
375 test("parses simpleDoubleQuotedCharacter", function() {
376 parserParses('start = "a"', literalGrammar("a"));
377 parserParses('start = "\'"', literalGrammar("'"));
378 parserDoesNotParse('start = """');
379 parserDoesNotParse('start = "\\"');
380 parserDoesNotParse('start = "\n"');
381 parserDoesNotParse('start = "\r"');
382 parserDoesNotParse('start = "\u2028"');
383 parserDoesNotParse('start = "\u2029"');
384 });
385
386 /* Canonical singleQuotedString is "'abcd'". */
387 test("parses singleQuotedString", function() {
388 parserParses("start = ''", literalGrammar(""));
389 parserParses("start = 'a'", literalGrammar("a"));
390 parserParses("start = 'abc'", literalGrammar("abc"));
391 });
392
393 /* Canonical singleQuotedCharacter is "a". */
394 test("parses singleQuotedCharacter", function() {
395 parserParses("start = 'a'", literalGrammar("a"));
396 parserParses("start = '\\n'", literalGrammar("\n"));
397 parserParses("start = '\\0'", literalGrammar("\x00"));
398 parserParses("start = '\\x00'", literalGrammar("\x00"));
399 parserParses("start = '\\u0120'", literalGrammar("\u0120"));
400 parserParses("start = '\\\n'", literalGrammar("\n"));
401 });
402
403 /* Canonical simpleSingleQuotedCharacter is "a". */
404 test("parses simpleSingleQuotedCharacter", function() {
405 parserParses("start = 'a'", literalGrammar("a"));
406 parserParses("start = '\"'", literalGrammar("\""));
407 parserDoesNotParse("start = '''");
408 parserDoesNotParse("start = '\\'");
409 parserDoesNotParse("start = '\n'");
410 parserDoesNotParse("start = '\r'");
411 parserDoesNotParse("start = '\u2028'");
412 parserDoesNotParse("start = '\u2029'");
413 });
414
415 /* Canonical class is "[a-d]". */
416 test("parses class", function() {
417 parserParses("start = []", classGrammar(false, [], "[]"));
418 parserParses("start = [a-d]", classGrammar(false, [["a", "d"]], "[a-d]"));
419 parserParses("start = [^a-d]", classGrammar(true, [["a", "d"]], "[^a-d]"));
420 parserParses("start = [a]", classGrammar(false, ["a"], "[a]"));
421 parserParses(
422 "start = [a-de-hi-l]",
423 classGrammar(false, [["a", "d"], ["e", "h"], ["i", "l"]], "[a-de-hi-l]")
424 );
425 parserParses(
426 "start = [a-d]i",
427 oneRuleGrammar(klass(false, true, [["a", "d"]], "[a-d]i"))
428 );
429
430 parserParses("start = [a-d]\n", classGrammar(false, [["a", "d"]], "[a-d]"));
431 });
432
433 /* Canonical classCharacterRange is "a-d". */
434 test("parses classCharacterRange", function() {
435 parserParses("start = [a-d]", classGrammar(false, [["a", "d"]], "[a-d]"));
436 parserParses("start = [a-a]", classGrammar(false, [["a", "a"]], "[a-a]"));
437 parserDoesNotParse("start = [b-a]");
438 parserDoesNotParseWithMessage(
439 "start = [b-a]",
440 "Invalid character range: b-a."
441 );
442 });
443
444 /* Canonical classCharacter is "a". */
445 test("parses classCharacter", function() {
446 parserParses("start = [a]", classGrammar(false, ["a"], "[a]"));
447 });
448
449 /* Canonical bracketDelimitedCharacter is "a". */
450 test("parses bracketDelimitedCharacter", function() {
451 parserParses("start = [a]", classGrammar(false, ["a"], "[a]"));
452 parserParses("start = [\\n]", classGrammar(false, ["\n"], "[\\n]"));
453 parserParses("start = [\\0]", classGrammar(false, ["\x00"], "[\\0]"));
454 parserParses("start = [\\x00]", classGrammar(false, ["\x00"], "[\\0]"));
455 parserParses("start = [\\u0120]", classGrammar(false, ["\u0120"], "[\\u0120]"));
456 parserParses("start = [\\\n]", classGrammar(false, ["\n"], "[\\n]"));
457 });
458
459 /* Canonical simpleBracketDelimiedCharacter is "a". */
460 test("parses simpleBracketDelimitedCharacter", function() {
461 parserParses("start = [a]", classGrammar(false, ["a"], "[a]"));
462 parserParses("start = [[]", classGrammar(false, ["["], "[[]"));
463 parserDoesNotParse("start = []]");
464 parserDoesNotParse("start = [\\]");
465 parserDoesNotParse("start = [\n]");
466 parserDoesNotParse("start = [\r]");
467 parserDoesNotParse("start = [\u2028]");
468 parserDoesNotParse("start = [\u2029]");
469 });
470
471 /* Canonical simpleEscapeSequence is "\\n". */
472 test("parses simpleEscapeSequence", function() {
473 parserParses('start = "\\\'"', literalGrammar("'"));
474 parserParses('start = "\\""', literalGrammar("\""));
475 parserParses('start = "\\\\"', literalGrammar("\\"));
476 parserParses('start = "\\b"', literalGrammar("\b"));
477 parserParses('start = "\\f"', literalGrammar("\f"));
478 parserParses('start = "\\n"', literalGrammar("\n"));
479 parserParses('start = "\\r"', literalGrammar("\r"));
480 parserParses('start = "\\t"', literalGrammar("\t"));
481 /* IE does not recognize "\v". */
482 parserParses('start = "\\v"', literalGrammar("\x0B"));
483
484 parserParses('start = "\\a"', literalGrammar("a"));
485 });
486
487 /* Canonical zeroEscapeSequence is "\\0". */
488 test("parses zeroEscapeSequence", function() {
489 parserParses('start = "\\0"', literalGrammar("\x00"));
490 parserDoesNotParse('start = "\\00"');
491 parserDoesNotParse('start = "\\09"');
492 });
493
494 /* Canonical hexEscapeSequence is "\\x00". */
495 test("parses hexEscapeSequence", function() {
496 parserParses('start = "\\x00"', literalGrammar("\x00"));
497 parserParses('start = "\\x09"', literalGrammar("\x09"));
498 parserParses('start = "\\x0a"', literalGrammar("\x0a"));
499 parserParses('start = "\\x0f"', literalGrammar("\x0f"));
500 parserParses('start = "\\x0A"', literalGrammar("\x0A"));
501 parserParses('start = "\\x0F"', literalGrammar("\x0F"));
502 parserDoesNotParse('start = "\\x0"');
503 parserParses('start = "\\x000"', literalGrammar("\x000"));
504 });
505
506 /* Canonical unicodeEscapeSequence is "\\u0120". */
507 test("parses unicodeEscapeSequence", function() {
508 parserParses('start = "\\u0120"', literalGrammar("\u0120"));
509 parserParses('start = "\\u0129"', literalGrammar("\u0129"));
510 parserParses('start = "\\u012a"', literalGrammar("\u012a"));
511 parserParses('start = "\\u012f"', literalGrammar("\u012f"));
512 parserParses('start = "\\u012A"', literalGrammar("\u012A"));
513 parserParses('start = "\\u012F"', literalGrammar("\u012F"));
514 parserDoesNotParse('start = "\\u012"');
515 parserParses('start = "\\u01234"', literalGrammar("\u01234"));
516 });
517
518 /* Canonical eolEscapeSequence is "\\\n". */
519 test("parses eolEscapeSequence", function() {
520 parserParses('start = "\\\n"', literalGrammar("\n"));
521 parserParses('start = "\\\r\n"', literalGrammar("\r\n"));
522 parserParses('start = "\\\r"', literalGrammar("\r"));
523 parserParses('start = "\\\u2028"', literalGrammar("\u2028"));
524 parserParses('start = "\\\u2029"', literalGrammar("\u2029"));
525 });
526
527 /* Canonical __ is "\n". */
528 test("parses __", function() {
529 parserParses('start ="abcd"', simpleGrammar);
530 parserParses('start = "abcd"', simpleGrammar);
531 parserParses('start =\n"abcd"', simpleGrammar);
532 parserParses('start =/* comment */"abcd"', simpleGrammar);
533 parserParses('start = "abcd"', simpleGrammar);
534 });
535
536 /* Trivial character class rules are not tested. */
537
538 // Canonical comment is "\/* comment *\/".
539 test("parses comment", function() {
540 parserParses('start =// comment\n"abcd"', simpleGrammar);
541 parserParses('start =/* comment */"abcd"', simpleGrammar);
542 });
543 /* Canonical singleLineComment is "// comment". */
544 test("parses singleLineComment", function() {
545 parserParses('start =//\n"abcd"', simpleGrammar);
546 parserParses('start =//a\n"abcd"', simpleGrammar);
547 parserParses('start =//aaa\n"abcd"', simpleGrammar);
548 parserParses('start = "abcd"//', simpleGrammar);
549 });
550
551 // Canonical multiLineComment is "\/* comment *\/".
552 test("parses multiLineComment", function() {
553 parserParses('start =/**/"abcd"', simpleGrammar);
554 parserParses('start =/*a*/"abcd"', simpleGrammar);
555 parserParses('start =/*aaa*/"abcd"', simpleGrammar);
556 parserParses('start =/*\n*/"abcd"', simpleGrammar);
557 parserParses('start =/***/"abcd"', simpleGrammar);
558 parserParses('start =/*a/*/"abcd"', simpleGrammar);
559
560 parserDoesNotParse('start =/*"abcd"');
561 parserDoesNotParse('start =/*/"abcd"');
562 parserDoesNotParse('start =/*/**/*/"abcd"');
563 });
564
565 /* Canonical eol is "\n". */
566 test("parses eol", function() {
567 parserParses('start =\n"abcd"', simpleGrammar);
568 parserParses('start =\r\n"abcd"', simpleGrammar);
569 parserParses('start =\r"abcd"', simpleGrammar);
570 parserParses('start =\u2028"abcd"', simpleGrammar);
571 parserParses('start =\u2029"abcd"', simpleGrammar);
572 });
573
574 /* Canonical eolChar is "\n". */
575 test("parses eolChar", function() {
576 parserParses('start =\n"abcd"', simpleGrammar);
577 parserParses('start =\r"abcd"', simpleGrammar);
578 parserParses('start =\u2028"abcd"', simpleGrammar);
579 parserParses('start =\u2029"abcd"', simpleGrammar);
580 });
581
582 /* Canonical whitespace is " ". */
583 test("parses whitespace", function() {
584 parserParses('start =\t"abcd"', simpleGrammar);
585 /* IE does not recognize "\v". */
586 parserParses('start =\x0B"abcd"', simpleGrammar);
587 parserParses('start =\f"abcd"', simpleGrammar);
588 parserParses('start = "abcd"', simpleGrammar);
589 parserParses('start =\u00A0"abcd"', simpleGrammar);
590 parserParses('start =\uFEFF"abcd"', simpleGrammar);
591 parserParses('start =\u1680"abcd"', simpleGrammar);
592 parserParses('start =\u180E"abcd"', simpleGrammar);
593 parserParses('start =\u2000"abcd"', simpleGrammar);
594 parserParses('start =\u2001"abcd"', simpleGrammar);
595 parserParses('start =\u2002"abcd"', simpleGrammar);
596 parserParses('start =\u2003"abcd"', simpleGrammar);
597 parserParses('start =\u2004"abcd"', simpleGrammar);
598 parserParses('start =\u2005"abcd"', simpleGrammar);
599 parserParses('start =\u2006"abcd"', simpleGrammar);
600 parserParses('start =\u2007"abcd"', simpleGrammar);
601 parserParses('start =\u2008"abcd"', simpleGrammar);
602 parserParses('start =\u2009"abcd"', simpleGrammar);
603 parserParses('start =\u200A"abcd"', simpleGrammar);
604 parserParses('start =\u202F"abcd"', simpleGrammar);
605 parserParses('start =\u205F"abcd"', simpleGrammar);
606 parserParses('start =\u3000"abcd"', simpleGrammar);
607 });
608
609 })();
+0
-607
test/passes-test.js less more
0 (function() {
1
2 module("PEG.compiler.passes");
3
4 test("reports missing referenced rules", function() {
5 function testGrammar(grammar) {
6 raises(
7 function() {
8 var ast = PEG.parser.parse(grammar);
9 PEG.compiler.passes.reportMissingRules(ast);
10 },
11 function(e) {
12 return e instanceof PEG.GrammarError
13 && e.message === "Referenced rule \"missing\" does not exist.";
14 }
15 );
16 }
17
18 var grammars = [
19 'start = missing',
20 'start = missing / "a" / "b"',
21 'start = "a" / "b" / missing',
22 'start = missing "a" "b"',
23 'start = "a" "b" missing',
24 'start = label:missing',
25 'start = &missing',
26 'start = !missing',
27 'start = missing?',
28 'start = missing*',
29 'start = missing+',
30 'start = missing { }'
31 ];
32
33 for (var i = 0; i < grammars.length; i++) { testGrammar(grammars[i]); }
34 });
35
36 test("reports left recursion", function() {
37 function testGrammar(grammar) {
38 raises(
39 function() {
40 var ast = PEG.parser.parse(grammar);
41 PEG.compiler.passes.reportLeftRecursion(ast);
42 },
43 function(e) {
44 return e instanceof PEG.GrammarError
45 && e.message === "Left recursion detected for rule \"start\".";
46 }
47 );
48 }
49
50 var grammars = [
51 /* Direct */
52 'start = start',
53 'start = start / "a" / "b"',
54 'start = "a" / "b" / start',
55 'start = start "a" "b"',
56 'start = label:start',
57 'start = &start',
58 'start = !start',
59 'start = start?',
60 'start = start*',
61 'start = start+',
62 'start = start { }',
63
64 /* Indirect */
65 'start = stop; stop = start'
66 ];
67
68 for (var i = 0; i < grammars.length; i++) { testGrammar(grammars[i]); }
69 });
70
71 test("removes proxy rules", function() {
72 function simpleGrammar(rules, startRule) {
73 return {
74 type: "grammar",
75 initializer: null,
76 rules: rules,
77 startRule: startRule
78 };
79 }
80
81 var proxiedRule = {
82 type: "rule",
83 name: "proxied",
84 displayName: null,
85 expression: { type: "literal", value: "a", ignoreCase: false }
86 };
87
88 var proxiedRuleRef = {
89 type: "rule_ref",
90 name: "proxied"
91 };
92
93 function simpleGrammarWithStartAndProxied(startRuleExpression) {
94 return simpleGrammar(
95 [
96 {
97 type: "rule",
98 name: "start",
99 displayName: null,
100 expression: startRuleExpression
101 },
102 proxiedRule
103 ],
104 "start"
105 );
106 }
107
108 var cases = [
109 {
110 grammar: 'start = proxy; proxy = proxied; proxied = "a"',
111 ast: simpleGrammar([proxiedRule], "proxied")
112 },
113 {
114 grammar: 'start = proxy / "a" / "b"; proxy = proxied; proxied = "a"',
115 ast: simpleGrammarWithStartAndProxied({
116 type: "choice",
117 alternatives: [
118 proxiedRuleRef,
119 { type: "literal", value: "a", ignoreCase: false },
120 { type: "literal", value: "b", ignoreCase: false }
121 ]
122 })
123 },
124 {
125 grammar: 'start = "a" / "b" / proxy; proxy = proxied; proxied = "a"',
126 ast: simpleGrammarWithStartAndProxied({
127 type: "choice",
128 alternatives: [
129 { type: "literal", value: "a", ignoreCase: false },
130 { type: "literal", value: "b", ignoreCase: false },
131 proxiedRuleRef
132 ]
133 })
134 },
135 {
136 grammar: 'start = proxy "a" "b"; proxy = proxied; proxied = "a"',
137 ast: simpleGrammarWithStartAndProxied({
138 type: "sequence",
139 elements: [
140 proxiedRuleRef,
141 { type: "literal", value: "a", ignoreCase: false },
142 { type: "literal", value: "b", ignoreCase: false }
143 ]
144 })
145 },
146 {
147 grammar: 'start = "a" "b" proxy; proxy = proxied; proxied = "a"',
148 ast: simpleGrammarWithStartAndProxied({
149 type: "sequence",
150 elements: [
151 { type: "literal", value: "a", ignoreCase: false },
152 { type: "literal", value: "b", ignoreCase: false },
153 proxiedRuleRef
154 ]
155 })
156 },
157 {
158 grammar: 'start = label:proxy; proxy = proxied; proxied = "a"',
159 ast: simpleGrammarWithStartAndProxied({
160 type: "labeled",
161 label: "label",
162 expression: proxiedRuleRef
163 })
164 },
165 {
166 grammar: 'start = &proxy; proxy = proxied; proxied = "a"',
167 ast: simpleGrammarWithStartAndProxied({
168 type: "simple_and",
169 expression: proxiedRuleRef
170 })
171 },
172 {
173 grammar: 'start = !proxy; proxy = proxied; proxied = "a"',
174 ast: simpleGrammarWithStartAndProxied({
175 type: "simple_not",
176 expression: proxiedRuleRef
177 })
178 },
179 {
180 grammar: 'start = proxy?; proxy = proxied; proxied = "a"',
181 ast: simpleGrammarWithStartAndProxied({
182 type: "optional",
183 expression: proxiedRuleRef
184 })
185 },
186 {
187 grammar: 'start = proxy*; proxy = proxied; proxied = "a"',
188 ast: simpleGrammarWithStartAndProxied({
189 type: "zero_or_more",
190 expression: proxiedRuleRef
191 })
192 },
193 {
194 grammar: 'start = proxy+; proxy = proxied; proxied = "a"',
195 ast: simpleGrammarWithStartAndProxied({
196 type: "one_or_more",
197 expression: proxiedRuleRef
198 })
199 },
200 {
201 grammar: 'start = proxy { }; proxy = proxied; proxied = "a"',
202 ast: simpleGrammarWithStartAndProxied({
203 type: "action",
204 code: " ",
205 expression: proxiedRuleRef
206 })
207 }
208 ];
209
210 for (var i = 0; i < cases.length; i++) {
211 var ast = PEG.parser.parse(cases[i].grammar);
212 PEG.compiler.passes.removeProxyRules(ast);
213
214 deepEqual(ast, cases[i].ast);
215 }
216 });
217
218 test("computes variable names", function() {
219 var leafDetails = { resultVar: "result0" },
220 choiceDetails = {
221 resultVar: "result0",
222 alternatives: [
223 { resultVar: "result0", posVar: "pos0" },
224 { resultVar: "result0", posVar: "pos0" },
225 { resultVar: "result0", posVar: "pos0" }
226 ]
227 },
228 sequenceDetails = {
229 resultVar: "result0",
230 posVar: "pos0",
231 elements: [
232 { resultVar: "result0", posVar: "pos1" },
233 { resultVar: "result1", posVar: "pos1" },
234 { resultVar: "result2", posVar: "pos1" }
235 ]
236 };
237
238 var cases = [
239 /* Choice */
240 {
241 grammar: 'start = &"a" / &"b" / &"c"',
242 resultVars: ["result0"],
243 posVars: ["pos0"],
244 details: choiceDetails
245 },
246 {
247 grammar: 'start = &"a" / &"b"* / &"c"',
248 resultVars: ["result0", "result1"],
249 posVars: ["pos0"],
250 details: choiceDetails
251 },
252 {
253 grammar: 'start = &"a" / &(&"b") / &"c"',
254 resultVars: ["result0"],
255 posVars: ["pos0", "pos1"],
256 details: choiceDetails
257 },
258
259 /* Sequence */
260 {
261 grammar: 'start = ',
262 resultVars: ["result0"],
263 posVars: ["pos0"],
264 details: { resultVar: "result0", posVar: "pos0" }
265 },
266 {
267 grammar: 'start = &"a" &"b" &"c"',
268 resultVars: ["result0", "result1", "result2"],
269 posVars: ["pos0", "pos1"],
270 details: sequenceDetails
271 },
272 {
273 grammar: 'start = &"a" &"b" &"c"*',
274 resultVars: ["result0", "result1", "result2", "result3"],
275 posVars: ["pos0", "pos1"],
276 details: sequenceDetails
277 },
278 {
279 grammar: 'start = &"a" &"b"* &"c"',
280 resultVars: ["result0", "result1", "result2"],
281 posVars: ["pos0", "pos1"],
282 details: sequenceDetails
283 },
284 {
285 grammar: 'start = &"a" &("b"*)* &"c"',
286 resultVars: ["result0", "result1", "result2", "result3"],
287 posVars: ["pos0", "pos1"],
288 details: sequenceDetails
289 },
290 {
291 grammar: 'start = &"a"* &"b" &"c"',
292 resultVars: ["result0", "result1", "result2"],
293 posVars: ["pos0", "pos1"],
294 details: sequenceDetails
295 },
296 {
297 grammar: 'start = &("a"*)* &"b" &"c"',
298 resultVars: ["result0", "result1", "result2"],
299 posVars: ["pos0", "pos1"],
300 details: sequenceDetails
301 },
302 {
303 grammar: 'start = &(("a"*)*)* &"b" &"c"',
304 resultVars: ["result0", "result1", "result2", "result3"],
305 posVars: ["pos0", "pos1"],
306 details: sequenceDetails
307 },
308 {
309 grammar: 'start = &"a" &(&"b") &"c"',
310 resultVars: ["result0", "result1", "result2"],
311 posVars: ["pos0", "pos1", "pos2"],
312 details: sequenceDetails
313 },
314
315 /* Others */
316 {
317 grammar: 'start = label:&"a"',
318 resultVars: ["result0"],
319 posVars: ["pos0"],
320 details: {
321 resultVar: "result0",
322 expression: { resultVar: "result0", posVar: "pos0" }
323 }
324 },
325 {
326 grammar: 'start = &(&"a")',
327 resultVars: ["result0"],
328 posVars: ["pos0", "pos1"],
329 details: {
330 resultVar: "result0",
331 posVar: "pos0",
332 expression: { resultVar: "result0", posVar: "pos1" }
333 }
334 },
335 {
336 grammar: 'start = !(&"a")',
337 resultVars: ["result0"],
338 posVars: ["pos0", "pos1"],
339 details: {
340 resultVar: "result0",
341 posVar: "pos0",
342 expression: { resultVar: "result0", posVar: "pos1" }
343 }
344 },
345 {
346 grammar: 'start = &{ code }',
347 resultVars: ["result0"],
348 posVars: [],
349 details: leafDetails
350 },
351 {
352 grammar: 'start = !{ code }',
353 resultVars: ["result0"],
354 posVars: [],
355 details: leafDetails
356 },
357 {
358 grammar: 'start = (&"a")?',
359 resultVars: ["result0"],
360 posVars: ["pos0"],
361 details: {
362 resultVar: "result0",
363 expression: { resultVar: "result0", posVar: "pos0" }
364 }
365 },
366 {
367 grammar: 'start = (&"a")*',
368 resultVars: ["result0", "result1"],
369 posVars: ["pos0"],
370 details: {
371 resultVar: "result0",
372 expression: { resultVar: "result1", posVar: "pos0" }
373 }
374 },
375 {
376 grammar: 'start = (&"a")+',
377 resultVars: ["result0", "result1"],
378 posVars: ["pos0"],
379 details: {
380 resultVar: "result0",
381 expression: { resultVar: "result1", posVar: "pos0" }
382 }
383 },
384 {
385 grammar: 'start = &"a" { code }',
386 resultVars: ["result0"],
387 posVars: ["pos0", "pos1"],
388 details: {
389 resultVar: "result0",
390 posVar: "pos0",
391 expression: { resultVar: "result0", posVar: "pos1" }
392 }
393 },
394 {
395 grammar: 'start = a',
396 resultVars: ["result0"],
397 posVars: [],
398 details: leafDetails
399 },
400 {
401 grammar: 'start = "a"',
402 resultVars: ["result0"],
403 posVars: [],
404 details: leafDetails
405 },
406 {
407 grammar: 'start = .',
408 resultVars: ["result0"],
409 posVars: [],
410 details: leafDetails
411 },
412 {
413 grammar: 'start = [a-z]',
414 resultVars: ["result0"],
415 posVars: [],
416 details: leafDetails
417 }
418 ];
419
420 function checkDetails(node, details) {
421 for (var key in details) {
422 if (Object.prototype.toString.call(details[key]) === "[object Array]") {
423 for (var i = 0; i < details[key].length; i++) {
424 checkDetails(node[key][i], details[key][i]);
425 }
426 } else if (typeof details[key] === "object") {
427 checkDetails(node[key], details[key]);
428 } else {
429 strictEqual(node[key], details[key]);
430 }
431 }
432 }
433
434 for (var i = 0; i < cases.length; i++) {
435 var ast = PEG.parser.parse(cases[i].grammar);
436 PEG.compiler.passes.computeVarNames(ast);
437
438 deepEqual(ast.rules[0].resultVars, cases[i].resultVars);
439 deepEqual(ast.rules[0].posVars, cases[i].posVars);
440 checkDetails(ast.rules[0].expression, cases[i].details);
441 }
442 });
443
444 test("computes params", function() {
445 function extractNode(node) { return node; }
446 function extractExpression(node) { return node.expression; }
447
448 var cases = [
449 /* Bacics */
450 {
451 grammar: 'start = a:"a" { }',
452 extractor: extractNode,
453 params: { a: "result0" }
454 },
455 {
456 grammar: 'start = a:"a" &{ }',
457 extractor: function(node) { return node.elements[1]; },
458 params: { a: "result0" }
459 },
460 {
461 grammar: 'start = a:"a" !{ }',
462 extractor: function(node) { return node.elements[1]; },
463 params: { a: "result0" }
464 },
465
466 /* Recursive walk */
467 {
468 grammar: 'start = a:"a" { } / "b" / "c"',
469 extractor: function(node) { return node.alternatives[0]; },
470 params: { a: "result0" }
471 },
472 {
473 grammar: 'start = "a" / "b" / c:"c" { }',
474 extractor: function(node) { return node.alternatives[2]; },
475 params: { c: "result0" }
476 },
477 {
478 grammar: 'start = (a:"a" { }) "b" "c"',
479 extractor: function(node) { return node.elements[0]; },
480 params: { a: "result0" }
481 },
482 {
483 grammar: 'start = "a" "b" (c:"c" { })',
484 extractor: function(node) { return node.elements[2]; },
485 params: { c: "result2" }
486 },
487 {
488 grammar: 'start = a:(b:"b" { })',
489 extractor: extractExpression,
490 params: { b: "result0" }
491 },
492 {
493 grammar: 'start = &(a:"a" { })',
494 extractor: extractExpression,
495 params: { a: "result0" }
496 },
497 {
498 grammar: 'start = !(a:"a" { })',
499 extractor: extractExpression,
500 params: { a: "result0" }
501 },
502 {
503 grammar: 'start = (a:"a" { })?',
504 extractor: extractExpression,
505 params: { a: "result0" }
506 },
507 {
508 grammar: 'start = (a:"a" { })*',
509 extractor: extractExpression,
510 params: { a: "result1" }
511 },
512 {
513 grammar: 'start = (a:"a" { })+',
514 extractor: extractExpression,
515 params: { a: "result1" }
516 },
517 {
518 grammar: 'start = (a:"a" { }) { }',
519 extractor: extractExpression,
520 params: { a: "result0" }
521 },
522
523 /* Scoping */
524 {
525 grammar: 'start = (a:"a" / b:"b" / c:"c") { }',
526 extractor: extractNode,
527 params: { }
528 },
529 {
530 grammar: 'start = a:(b:"b") { }',
531 extractor: extractNode,
532 params: { a: "result0" }
533 },
534 {
535 grammar: 'start = &(a:"a") { }',
536 extractor: extractNode,
537 params: { }
538 },
539 {
540 grammar: 'start = !(a:"a") { }',
541 extractor: extractNode,
542 params: { }
543 },
544 {
545 grammar: 'start = (a:"a")? { }',
546 extractor: extractNode,
547 params: { }
548 },
549 {
550 grammar: 'start = (a:"a")* { }',
551 extractor: extractNode,
552 params: { }
553 },
554 {
555 grammar: 'start = (a:"a")+ { }',
556 extractor: extractNode,
557 params: { }
558 },
559 {
560 grammar: 'start = (a:"a" { }) { }',
561 extractor: extractNode,
562 params: { }
563 },
564
565 /* Sequences */
566 {
567 grammar: 'start = a:"a" b:"b" c:"c" { }',
568 extractor: extractNode,
569 params: { a: "result0[0]", b: "result0[1]", c: "result0[2]" }
570 },
571 {
572 grammar: 'start = a:"a" (b:"b" c:"c" d:"d") e:"e"{ }',
573 extractor: extractNode,
574 params: {
575 a: "result0[0]",
576 b: "result0[1][0]",
577 c: "result0[1][1]",
578 d: "result0[1][2]",
579 e: "result0[2]"
580 }
581 },
582 /*
583 * Regression tests for a bug where e.g. resultVar names like |result10|
584 * were incorrectly treated as names derived from |result1|, leading to
585 * incorrect substitution.
586 */
587 {
588 grammar: 'start = ("a" "b" "c" "d" "e" "f" "g" "h" "i" j:"j" { })*',
589 extractor: extractExpression,
590 params: { j: "result1[9]" } // Buggy code put "result1[0]0" here.
591 }
592 ];
593
594 for (var i = 0; i < cases.length; i++) {
595 var ast = PEG.parser.parse(cases[i].grammar);
596 PEG.compiler.passes.computeVarNames(ast);
597 PEG.compiler.passes.computeParams(ast);
598
599 deepEqual(
600 cases[i].extractor(ast.rules[0].expression).params,
601 cases[i].params
602 );
603 }
604 });
605
606 })();
+0
-85
test/run less more
0 #!/usr/bin/env node
1
2 var util = require("util"),
3 fs = require("fs"),
4 PEG = require("../lib/peg"),
5 QUnit = require("./vendor/qunit/qunit");
6
7 var failedAssertions = [];
8
9 function bold(s) { return "\u001B[1m" + s + "\u001B[22m"; };
10 function message(s) { return "\u001B[35m" + s + "\u001B[39m"; };
11 function ok(s) { return "\u001B[32m" + s + "\u001B[39m"; };
12 function error(s) { return "\u001B[31m" + s + "\u001B[39m"; };
13
14 function indent(s) { return s.replace(/^/gm, " "); }
15
16 QUnit.init();
17 QUnit.config.blocking = true;
18 QUnit.config.updateRate = 0;
19
20 QUnit.moduleStart(function(details) {
21 util.puts("");
22 util.puts(bold(details.name));
23 });
24
25 QUnit.testStart(function(details) {
26 failedAssertions = [];
27 });
28
29 QUnit.testDone(function(details) {
30 if (details.failed == 0) {
31 util.puts('✔ ' + details.name);
32 } else {
33 util.puts(error('✖ ' + details.name));
34 util.puts("");
35 failedAssertions.forEach(function(assertion) {
36 util.puts(assertion);
37 });
38 }
39 });
40
41 QUnit.log(function(details) {
42 var output = "";
43
44 if (details.result) { return; }
45
46 if (details.message) {
47 output += indent("Message: " + message(details.message)) + "\n";
48 }
49 if (details.actual && details.expected) {
50 output += indent("Expected: " + QUnit.jsDump.parse(details.expected)) + "\n";
51 if (details.actual != details.expected) {
52 output += indent("Actual: " + QUnit.jsDump.parse(details.actual));
53 }
54 }
55
56 failedAssertions.push(output);
57 });
58
59 QUnit.done(function(details) {
60 util.puts("");
61 if (details.failed > 0) {
62 util.puts(bold(error("FAILURES: "))
63 + details.failed + "/"
64 + details.total + " assertions failed ("
65 + details.runtime + " ms)"
66 );
67 } else {
68 util.puts(bold(ok('OK: '))
69 + details.total + " assertions ("
70 + details.runtime + " ms)"
71 )
72 }
73 });
74
75 [
76 "helpers.js",
77 "parser-test.js",
78 "passes-test.js",
79 "compiler-test.js",
80 ].forEach(function(file) {
81 eval("with (QUnit) {" + fs.readFileSync(__dirname + "/" + file, "utf8") + "}");
82 });
83
84 QUnit.start();
+0
-235
test/vendor/qunit/qunit.css less more
0 /**
1 * QUnit v1.5.0 - A JavaScript Unit Testing Framework
2 *
3 * http://docs.jquery.com/QUnit
4 *
5 * Copyright (c) 2012 John Resig, Jörn Zaefferer
6 * Dual licensed under the MIT (MIT-LICENSE.txt)
7 * or GPL (GPL-LICENSE.txt) licenses.
8 */
9
10 /** Font Family and Sizes */
11
12 #qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
13 font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
14 }
15
16 #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
17 #qunit-tests { font-size: smaller; }
18
19
20 /** Resets */
21
22 #qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult {
23 margin: 0;
24 padding: 0;
25 }
26
27
28 /** Header */
29
30 #qunit-header {
31 padding: 0.5em 0 0.5em 1em;
32
33 color: #8699a4;
34 background-color: #0d3349;
35
36 font-size: 1.5em;
37 line-height: 1em;
38 font-weight: normal;
39
40 border-radius: 15px 15px 0 0;
41 -moz-border-radius: 15px 15px 0 0;
42 -webkit-border-top-right-radius: 15px;
43 -webkit-border-top-left-radius: 15px;
44 }
45
46 #qunit-header a {
47 text-decoration: none;
48 color: #c2ccd1;
49 }
50
51 #qunit-header a:hover,
52 #qunit-header a:focus {
53 color: #fff;
54 }
55
56 #qunit-header label {
57 display: inline-block;
58 }
59
60 #qunit-banner {
61 height: 5px;
62 }
63
64 #qunit-testrunner-toolbar {
65 padding: 0.5em 0 0.5em 2em;
66 color: #5E740B;
67 background-color: #eee;
68 }
69
70 #qunit-userAgent {
71 padding: 0.5em 0 0.5em 2.5em;
72 background-color: #2b81af;
73 color: #fff;
74 text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
75 }
76
77
78 /** Tests: Pass/Fail */
79
80 #qunit-tests {
81 list-style-position: inside;
82 }
83
84 #qunit-tests li {
85 padding: 0.4em 0.5em 0.4em 2.5em;
86 border-bottom: 1px solid #fff;
87 list-style-position: inside;
88 }
89
90 #qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running {
91 display: none;
92 }
93
94 #qunit-tests li strong {
95 cursor: pointer;
96 }
97
98 #qunit-tests li a {
99 padding: 0.5em;
100 color: #c2ccd1;
101 text-decoration: none;
102 }
103 #qunit-tests li a:hover,
104 #qunit-tests li a:focus {
105 color: #000;
106 }
107
108 #qunit-tests ol {
109 margin-top: 0.5em;
110 padding: 0.5em;
111
112 background-color: #fff;
113
114 border-radius: 15px;
115 -moz-border-radius: 15px;
116 -webkit-border-radius: 15px;
117
118 box-shadow: inset 0px 2px 13px #999;
119 -moz-box-shadow: inset 0px 2px 13px #999;
120 -webkit-box-shadow: inset 0px 2px 13px #999;
121 }
122
123 #qunit-tests table {
124 border-collapse: collapse;
125 margin-top: .2em;
126 }
127
128 #qunit-tests th {
129 text-align: right;
130 vertical-align: top;
131 padding: 0 .5em 0 0;
132 }
133
134 #qunit-tests td {
135 vertical-align: top;
136 }
137
138 #qunit-tests pre {
139 margin: 0;
140 white-space: pre-wrap;
141 word-wrap: break-word;
142 }
143
144 #qunit-tests del {
145 background-color: #e0f2be;
146 color: #374e0c;
147 text-decoration: none;
148 }
149
150 #qunit-tests ins {
151 background-color: #ffcaca;
152 color: #500;
153 text-decoration: none;
154 }
155
156 /*** Test Counts */
157
158 #qunit-tests b.counts { color: black; }
159 #qunit-tests b.passed { color: #5E740B; }
160 #qunit-tests b.failed { color: #710909; }
161
162 #qunit-tests li li {
163 margin: 0.5em;
164 padding: 0.4em 0.5em 0.4em 0.5em;
165 background-color: #fff;
166 border-bottom: none;
167 list-style-position: inside;
168 }
169
170 /*** Passing Styles */
171
172 #qunit-tests li li.pass {
173 color: #5E740B;
174 background-color: #fff;
175 border-left: 26px solid #C6E746;
176 }
177
178 #qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; }
179 #qunit-tests .pass .test-name { color: #366097; }
180
181 #qunit-tests .pass .test-actual,
182 #qunit-tests .pass .test-expected { color: #999999; }
183
184 #qunit-banner.qunit-pass { background-color: #C6E746; }
185
186 /*** Failing Styles */
187
188 #qunit-tests li li.fail {
189 color: #710909;
190 background-color: #fff;
191 border-left: 26px solid #EE5757;
192 white-space: pre;
193 }
194
195 #qunit-tests > li:last-child {
196 border-radius: 0 0 15px 15px;
197 -moz-border-radius: 0 0 15px 15px;
198 -webkit-border-bottom-right-radius: 15px;
199 -webkit-border-bottom-left-radius: 15px;
200 }
201
202 #qunit-tests .fail { color: #000000; background-color: #EE5757; }
203 #qunit-tests .fail .test-name,
204 #qunit-tests .fail .module-name { color: #000000; }
205
206 #qunit-tests .fail .test-actual { color: #EE5757; }
207 #qunit-tests .fail .test-expected { color: green; }
208
209 #qunit-banner.qunit-fail { background-color: #EE5757; }
210
211
212 /** Result */
213
214 #qunit-testresult {
215 padding: 0.5em 0.5em 0.5em 2.5em;
216
217 color: #2b81af;
218 background-color: #D2E0E6;
219
220 border-bottom: 1px solid white;
221 }
222 #qunit-testresult .module-name {
223 font-weight: bold;
224 }
225
226 /** Fixture */
227
228 #qunit-fixture {
229 position: absolute;
230 top: -10000px;
231 left: -10000px;
232 width: 1000px;
233 height: 1000px;
234 }
+0
-1669
test/vendor/qunit/qunit.js less more
0 /**
1 * QUnit v1.5.0 - A JavaScript Unit Testing Framework
2 *
3 * http://docs.jquery.com/QUnit
4 *
5 * Copyright (c) 2012 John Resig, Jörn Zaefferer
6 * Dual licensed under the MIT (MIT-LICENSE.txt)
7 * or GPL (GPL-LICENSE.txt) licenses.
8 */
9
10 (function(window) {
11
12 var defined = {
13 setTimeout: typeof window.setTimeout !== "undefined",
14 sessionStorage: (function() {
15 var x = "qunit-test-string";
16 try {
17 sessionStorage.setItem(x, x);
18 sessionStorage.removeItem(x);
19 return true;
20 } catch(e) {
21 return false;
22 }
23 }())
24 };
25
26 var testId = 0,
27 toString = Object.prototype.toString,
28 hasOwn = Object.prototype.hasOwnProperty;
29
30 var Test = function(name, testName, expected, async, callback) {
31 this.name = name;
32 this.testName = testName;
33 this.expected = expected;
34 this.async = async;
35 this.callback = callback;
36 this.assertions = [];
37 };
38 Test.prototype = {
39 init: function() {
40 var tests = id("qunit-tests");
41 if (tests) {
42 var b = document.createElement("strong");
43 b.innerHTML = "Running " + this.name;
44 var li = document.createElement("li");
45 li.appendChild( b );
46 li.className = "running";
47 li.id = this.id = "test-output" + testId++;
48 tests.appendChild( li );
49 }
50 },
51 setup: function() {
52 if (this.module != config.previousModule) {
53 if ( config.previousModule ) {
54 runLoggingCallbacks('moduleDone', QUnit, {
55 name: config.previousModule,
56 failed: config.moduleStats.bad,
57 passed: config.moduleStats.all - config.moduleStats.bad,
58 total: config.moduleStats.all
59 } );
60 }
61 config.previousModule = this.module;
62 config.moduleStats = { all: 0, bad: 0 };
63 runLoggingCallbacks( 'moduleStart', QUnit, {
64 name: this.module
65 } );
66 } else if (config.autorun) {
67 runLoggingCallbacks( 'moduleStart', QUnit, {
68 name: this.module
69 } );
70 }
71
72 config.current = this;
73 this.testEnvironment = extend({
74 setup: function() {},
75 teardown: function() {}
76 }, this.moduleTestEnvironment);
77
78 runLoggingCallbacks( 'testStart', QUnit, {
79 name: this.testName,
80 module: this.module
81 });
82
83 // allow utility functions to access the current test environment
84 // TODO why??
85 QUnit.current_testEnvironment = this.testEnvironment;
86
87 if ( !config.pollution ) {
88 saveGlobal();
89 }
90 if ( config.notrycatch ) {
91 this.testEnvironment.setup.call(this.testEnvironment);
92 return;
93 }
94 try {
95 this.testEnvironment.setup.call(this.testEnvironment);
96 } catch(e) {
97 QUnit.pushFailure( "Setup failed on " + this.testName + ": " + e.message, extractStacktrace( e, 1 ) );
98 }
99 },
100 run: function() {
101 config.current = this;
102
103 var running = id("qunit-testresult");
104
105 if ( running ) {
106 running.innerHTML = "Running: <br/>" + this.name;
107 }
108
109 if ( this.async ) {
110 QUnit.stop();
111 }
112
113 if ( config.notrycatch ) {
114 this.callback.call(this.testEnvironment);
115 return;
116 }
117 try {
118 this.callback.call(this.testEnvironment);
119 } catch(e) {
120 QUnit.pushFailure( "Died on test #" + (this.assertions.length + 1) + ": " + e.message, extractStacktrace( e, 1 ) );
121 // else next test will carry the responsibility
122 saveGlobal();
123
124 // Restart the tests if they're blocking
125 if ( config.blocking ) {
126 QUnit.start();
127 }
128 }
129 },
130 teardown: function() {
131 config.current = this;
132 if ( config.notrycatch ) {
133 this.testEnvironment.teardown.call(this.testEnvironment);
134 return;
135 } else {
136 try {
137 this.testEnvironment.teardown.call(this.testEnvironment);
138 } catch(e) {
139 QUnit.pushFailure( "Teardown failed on " + this.testName + ": " + e.message, extractStacktrace( e, 1 ) );
140 }
141 }
142 checkPollution();
143 },
144 finish: function() {
145 config.current = this;
146 if ( this.expected != null && this.expected != this.assertions.length ) {
147 QUnit.pushFailure( "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run" );
148 } else if ( this.expected == null && !this.assertions.length ) {
149 QUnit.pushFailure( "Expected at least one assertion, but none were run - call expect(0) to accept zero assertions." );
150 }
151
152 var good = 0, bad = 0,
153 li, i,
154 tests = id("qunit-tests");
155
156 config.stats.all += this.assertions.length;
157 config.moduleStats.all += this.assertions.length;
158
159 if ( tests ) {
160 var ol = document.createElement("ol");
161
162 for ( i = 0; i < this.assertions.length; i++ ) {
163 var assertion = this.assertions[i];
164
165 li = document.createElement("li");
166 li.className = assertion.result ? "pass" : "fail";
167 li.innerHTML = assertion.message || (assertion.result ? "okay" : "failed");
168 ol.appendChild( li );
169
170 if ( assertion.result ) {
171 good++;
172 } else {
173 bad++;
174 config.stats.bad++;
175 config.moduleStats.bad++;
176 }
177 }
178
179 // store result when possible
180 if ( QUnit.config.reorder && defined.sessionStorage ) {
181 if (bad) {
182 sessionStorage.setItem("qunit-test-" + this.module + "-" + this.testName, bad);
183 } else {
184 sessionStorage.removeItem("qunit-test-" + this.module + "-" + this.testName);
185 }
186 }
187
188 if (bad === 0) {
189 ol.style.display = "none";
190 }
191
192 var b = document.createElement("strong");
193 b.innerHTML = this.name + " <b class='counts'>(<b class='failed'>" + bad + "</b>, <b class='passed'>" + good + "</b>, " + this.assertions.length + ")</b>";
194
195 var a = document.createElement("a");
196 a.innerHTML = "Rerun";
197 a.href = QUnit.url({ filter: getText([b]).replace(/\([^)]+\)$/, "").replace(/(^\s*|\s*$)/g, "") });
198
199 addEvent(b, "click", function() {
200 var next = b.nextSibling.nextSibling,
201 display = next.style.display;
202 next.style.display = display === "none" ? "block" : "none";
203 });
204
205 addEvent(b, "dblclick", function(e) {
206 var target = e && e.target ? e.target : window.event.srcElement;
207 if ( target.nodeName.toLowerCase() == "span" || target.nodeName.toLowerCase() == "b" ) {
208 target = target.parentNode;
209 }
210 if ( window.location && target.nodeName.toLowerCase() === "strong" ) {
211 window.location = QUnit.url({ filter: getText([target]).replace(/\([^)]+\)$/, "").replace(/(^\s*|\s*$)/g, "") });
212 }
213 });
214
215 li = id(this.id);
216 li.className = bad ? "fail" : "pass";
217 li.removeChild( li.firstChild );
218 li.appendChild( b );
219 li.appendChild( a );
220 li.appendChild( ol );
221
222 } else {
223 for ( i = 0; i < this.assertions.length; i++ ) {
224 if ( !this.assertions[i].result ) {
225 bad++;
226 config.stats.bad++;
227 config.moduleStats.bad++;
228 }
229 }
230 }
231
232 QUnit.reset();
233
234 runLoggingCallbacks( 'testDone', QUnit, {
235 name: this.testName,
236 module: this.module,
237 failed: bad,
238 passed: this.assertions.length - bad,
239 total: this.assertions.length
240 } );
241 },
242
243 queue: function() {
244 var test = this;
245 synchronize(function() {
246 test.init();
247 });
248 function run() {
249 // each of these can by async
250 synchronize(function() {
251 test.setup();
252 });
253 synchronize(function() {
254 test.run();
255 });
256 synchronize(function() {
257 test.teardown();
258 });
259 synchronize(function() {
260 test.finish();
261 });
262 }
263 // defer when previous test run passed, if storage is available
264 var bad = QUnit.config.reorder && defined.sessionStorage && +sessionStorage.getItem("qunit-test-" + this.module + "-" + this.testName);
265 if (bad) {
266 run();
267 } else {
268 synchronize(run, true);
269 }
270 }
271
272 };
273
274 var QUnit = {
275
276 // call on start of module test to prepend name to all tests
277 module: function(name, testEnvironment) {
278 config.currentModule = name;
279 config.currentModuleTestEnviroment = testEnvironment;
280 },
281
282 asyncTest: function(testName, expected, callback) {
283 if ( arguments.length === 2 ) {
284 callback = expected;
285 expected = null;
286 }
287
288 QUnit.test(testName, expected, callback, true);
289 },
290
291 test: function(testName, expected, callback, async) {
292 var name = '<span class="test-name">' + escapeInnerText(testName) + '</span>';
293
294 if ( arguments.length === 2 ) {
295 callback = expected;
296 expected = null;
297 }
298
299 if ( config.currentModule ) {
300 name = '<span class="module-name">' + config.currentModule + "</span>: " + name;
301 }
302
303 if ( !validTest(config.currentModule + ": " + testName) ) {
304 return;
305 }
306
307 var test = new Test(name, testName, expected, async, callback);
308 test.module = config.currentModule;
309 test.moduleTestEnvironment = config.currentModuleTestEnviroment;
310 test.queue();
311 },
312
313 // Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through.
314 expect: function(asserts) {
315 config.current.expected = asserts;
316 },
317
318 // Asserts true.
319 // @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" );
320 ok: function(result, msg) {
321 if (!config.current) {
322 throw new Error("ok() assertion outside test context, was " + sourceFromStacktrace(2));
323 }
324 result = !!result;
325 var details = {
326 result: result,
327 message: msg
328 };
329 msg = escapeInnerText(msg || (result ? "okay" : "failed"));
330 if ( !result ) {
331 var source = sourceFromStacktrace(2);
332 if (source) {
333 details.source = source;
334 msg += '<table><tr class="test-source"><th>Source: </th><td><pre>' + escapeInnerText(source) + '</pre></td></tr></table>';
335 }
336 }
337 runLoggingCallbacks( 'log', QUnit, details );
338 config.current.assertions.push({
339 result: result,
340 message: msg
341 });
342 },
343
344 // Checks that the first two arguments are equal, with an optional message. Prints out both actual and expected values.
345 // @example equal( format("Received {0} bytes.", 2), "Received 2 bytes." );
346 equal: function(actual, expected, message) {
347 QUnit.push(expected == actual, actual, expected, message);
348 },
349
350 notEqual: function(actual, expected, message) {
351 QUnit.push(expected != actual, actual, expected, message);
352 },
353
354 deepEqual: function(actual, expected, message) {
355 QUnit.push(QUnit.equiv(actual, expected), actual, expected, message);
356 },
357
358 notDeepEqual: function(actual, expected, message) {
359 QUnit.push(!QUnit.equiv(actual, expected), actual, expected, message);
360 },
361
362 strictEqual: function(actual, expected, message) {
363 QUnit.push(expected === actual, actual, expected, message);
364 },
365
366 notStrictEqual: function(actual, expected, message) {
367 QUnit.push(expected !== actual, actual, expected, message);
368 },
369
370 raises: function(block, expected, message) {
371 var actual, ok = false;
372
373 if (typeof expected === 'string') {
374 message = expected;
375 expected = null;
376 }
377
378 try {
379 block.call(config.current.testEnvironment);
380 } catch (e) {
381 actual = e;
382 }
383
384 if (actual) {
385 // we don't want to validate thrown error
386 if (!expected) {
387 ok = true;
388 // expected is a regexp
389 } else if (QUnit.objectType(expected) === "regexp") {
390 ok = expected.test(actual);
391 // expected is a constructor
392 } else if (actual instanceof expected) {
393 ok = true;
394 // expected is a validation function which returns true is validation passed
395 } else if (expected.call({}, actual) === true) {
396 ok = true;
397 }
398 }
399
400 QUnit.ok(ok, message);
401 },
402
403 start: function(count) {
404 config.semaphore -= count || 1;
405 if (config.semaphore > 0) {
406 // don't start until equal number of stop-calls
407 return;
408 }
409 if (config.semaphore < 0) {
410 // ignore if start is called more often then stop
411 config.semaphore = 0;
412 }
413 // A slight delay, to avoid any current callbacks
414 if ( defined.setTimeout ) {
415 window.setTimeout(function() {
416 if (config.semaphore > 0) {
417 return;
418 }
419 if ( config.timeout ) {
420 clearTimeout(config.timeout);
421 }
422
423 config.blocking = false;
424 process(true);
425 }, 13);
426 } else {
427 config.blocking = false;
428 process(true);
429 }
430 },
431
432 stop: function(count) {
433 config.semaphore += count || 1;
434 config.blocking = true;
435
436 if ( config.testTimeout && defined.setTimeout ) {
437 clearTimeout(config.timeout);
438 config.timeout = window.setTimeout(function() {
439 QUnit.ok( false, "Test timed out" );
440 config.semaphore = 1;
441 QUnit.start();
442 }, config.testTimeout);
443 }
444 }
445 };
446
447 //We want access to the constructor's prototype
448 (function() {
449 function F(){}
450 F.prototype = QUnit;
451 QUnit = new F();
452 //Make F QUnit's constructor so that we can add to the prototype later
453 QUnit.constructor = F;
454 }());
455
456 // deprecated; still export them to window to provide clear error messages
457 // next step: remove entirely
458 QUnit.equals = function() {
459 QUnit.push(false, false, false, "QUnit.equals has been deprecated since 2009 (e88049a0), use QUnit.equal instead");
460 };
461 QUnit.same = function() {
462 QUnit.push(false, false, false, "QUnit.same has been deprecated since 2009 (e88049a0), use QUnit.deepEqual instead");
463 };
464
465 // Maintain internal state
466 var config = {
467 // The queue of tests to run
468 queue: [],
469
470 // block until document ready
471 blocking: true,
472
473 // when enabled, show only failing tests
474 // gets persisted through sessionStorage and can be changed in UI via checkbox
475 hidepassed: false,
476
477 // by default, run previously failed tests first
478 // very useful in combination with "Hide passed tests" checked
479 reorder: true,
480
481 // by default, modify document.title when suite is done
482 altertitle: true,
483
484 urlConfig: ['noglobals', 'notrycatch'],
485
486 //logging callback queues
487 begin: [],
488 done: [],
489 log: [],
490 testStart: [],
491 testDone: [],
492 moduleStart: [],
493 moduleDone: []
494 };
495
496 // Load paramaters
497 (function() {
498 var location = window.location || { search: "", protocol: "file:" },
499 params = location.search.slice( 1 ).split( "&" ),
500 length = params.length,
501 urlParams = {},
502 current;
503
504 if ( params[ 0 ] ) {
505 for ( var i = 0; i < length; i++ ) {
506 current = params[ i ].split( "=" );
507 current[ 0 ] = decodeURIComponent( current[ 0 ] );
508 // allow just a key to turn on a flag, e.g., test.html?noglobals
509 current[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true;
510 urlParams[ current[ 0 ] ] = current[ 1 ];
511 }
512 }
513
514 QUnit.urlParams = urlParams;
515 config.filter = urlParams.filter;
516
517 // Figure out if we're running the tests from a server or not
518 QUnit.isLocal = location.protocol === 'file:';
519 }());
520
521 // Expose the API as global variables, unless an 'exports'
522 // object exists, in that case we assume we're in CommonJS - export everything at the end
523 if ( typeof exports === "undefined" || typeof require === "undefined" ) {
524 extend(window, QUnit);
525 window.QUnit = QUnit;
526 }
527
528 // define these after exposing globals to keep them in these QUnit namespace only
529 extend(QUnit, {
530 config: config,
531
532 // Initialize the configuration options
533 init: function() {
534 extend(config, {
535 stats: { all: 0, bad: 0 },
536 moduleStats: { all: 0, bad: 0 },
537 started: +new Date(),
538 updateRate: 1000,
539 blocking: false,
540 autostart: true,
541 autorun: false,
542 filter: "",
543 queue: [],
544 semaphore: 0
545 });
546
547 var qunit = id( "qunit" );
548 if ( qunit ) {
549 qunit.innerHTML =
550 '<h1 id="qunit-header">' + escapeInnerText( document.title ) + '</h1>' +
551 '<h2 id="qunit-banner"></h2>' +
552 '<div id="qunit-testrunner-toolbar"></div>' +
553 '<h2 id="qunit-userAgent"></h2>' +
554 '<ol id="qunit-tests"></ol>';
555 }
556
557 var tests = id( "qunit-tests" ),
558 banner = id( "qunit-banner" ),
559 result = id( "qunit-testresult" );
560
561 if ( tests ) {
562 tests.innerHTML = "";
563 }
564
565 if ( banner ) {
566 banner.className = "";
567 }
568
569 if ( result ) {
570 result.parentNode.removeChild( result );
571 }
572
573 if ( tests ) {
574 result = document.createElement( "p" );
575 result.id = "qunit-testresult";
576 result.className = "result";
577 tests.parentNode.insertBefore( result, tests );
578 result.innerHTML = 'Running...<br/>&nbsp;';
579 }
580 },
581
582 // Resets the test setup. Useful for tests that modify the DOM.
583 // If jQuery is available, uses jQuery's html(), otherwise just innerHTML.
584 reset: function() {
585 if ( window.jQuery ) {
586 jQuery( "#qunit-fixture" ).html( config.fixture );
587 } else {
588 var main = id( 'qunit-fixture' );
589 if ( main ) {
590 main.innerHTML = config.fixture;
591 }
592 }
593 },
594
595 // Trigger an event on an element.
596 // @example triggerEvent( document.body, "click" );
597 triggerEvent: function( elem, type, event ) {
598 if ( document.createEvent ) {
599 event = document.createEvent("MouseEvents");
600 event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView,
601 0, 0, 0, 0, 0, false, false, false, false, 0, null);
602 elem.dispatchEvent( event );
603
604 } else if ( elem.fireEvent ) {
605 elem.fireEvent("on"+type);
606 }
607 },
608
609 // Safe object type checking
610 is: function( type, obj ) {
611 return QUnit.objectType( obj ) == type;
612 },
613
614 objectType: function( obj ) {
615 if (typeof obj === "undefined") {
616 return "undefined";
617
618 // consider: typeof null === object
619 }
620 if (obj === null) {
621 return "null";
622 }
623
624 var type = toString.call( obj ).match(/^\[object\s(.*)\]$/)[1] || '';
625
626 switch (type) {
627 case 'Number':
628 if (isNaN(obj)) {
629 return "nan";
630 }
631 return "number";
632 case 'String':
633 case 'Boolean':
634 case 'Array':
635 case 'Date':
636 case 'RegExp':
637 case 'Function':
638 return type.toLowerCase();
639 }
640 if (typeof obj === "object") {
641 return "object";
642 }
643 return undefined;
644 },
645
646 push: function(result, actual, expected, message) {
647 if (!config.current) {
648 throw new Error("assertion outside test context, was " + sourceFromStacktrace());
649 }
650 var details = {
651 result: result,
652 message: message,
653 actual: actual,
654 expected: expected
655 };
656
657 message = escapeInnerText(message) || (result ? "okay" : "failed");
658 message = '<span class="test-message">' + message + "</span>";
659 var output = message;
660 if (!result) {
661 expected = escapeInnerText(QUnit.jsDump.parse(expected));
662 actual = escapeInnerText(QUnit.jsDump.parse(actual));
663 output += '<table><tr class="test-expected"><th>Expected: </th><td><pre>' + expected + '</pre></td></tr>';
664 if (actual != expected) {
665 output += '<tr class="test-actual"><th>Result: </th><td><pre>' + actual + '</pre></td></tr>';
666 output += '<tr class="test-diff"><th>Diff: </th><td><pre>' + QUnit.diff(expected, actual) +'</pre></td></tr>';
667 }
668 var source = sourceFromStacktrace();
669 if (source) {
670 details.source = source;
671 output += '<tr class="test-source"><th>Source: </th><td><pre>' + escapeInnerText(source) + '</pre></td></tr>';
672 }
673 output += "</table>";
674 }
675
676 runLoggingCallbacks( 'log', QUnit, details );
677
678 config.current.assertions.push({
679 result: !!result,
680 message: output
681 });
682 },
683
684 pushFailure: function(message, source) {
685 var details = {
686 result: false,
687 message: message
688 };
689 var output = escapeInnerText(message);
690 if (source) {
691 details.source = source;
692 output += '<table><tr class="test-source"><th>Source: </th><td><pre>' + escapeInnerText(source) + '</pre></td></tr></table>';
693 }
694 runLoggingCallbacks( 'log', QUnit, details );
695 config.current.assertions.push({
696 result: false,
697 message: output
698 });
699 },
700
701 url: function( params ) {
702 params = extend( extend( {}, QUnit.urlParams ), params );
703 var querystring = "?",
704 key;
705 for ( key in params ) {
706 if ( !hasOwn.call( params, key ) ) {
707 continue;
708 }
709 querystring += encodeURIComponent( key ) + "=" +
710 encodeURIComponent( params[ key ] ) + "&";
711 }
712 return window.location.pathname + querystring.slice( 0, -1 );
713 },
714
715 extend: extend,
716 id: id,
717 addEvent: addEvent
718 });
719
720 //QUnit.constructor is set to the empty F() above so that we can add to it's prototype later
721 //Doing this allows us to tell if the following methods have been overwritten on the actual
722 //QUnit object, which is a deprecated way of using the callbacks.
723 extend(QUnit.constructor.prototype, {
724 // Logging callbacks; all receive a single argument with the listed properties
725 // run test/logs.html for any related changes
726 begin: registerLoggingCallback('begin'),
727 // done: { failed, passed, total, runtime }
728 done: registerLoggingCallback('done'),
729 // log: { result, actual, expected, message }
730 log: registerLoggingCallback('log'),
731 // testStart: { name }
732 testStart: registerLoggingCallback('testStart'),
733 // testDone: { name, failed, passed, total }
734 testDone: registerLoggingCallback('testDone'),
735 // moduleStart: { name }
736 moduleStart: registerLoggingCallback('moduleStart'),
737 // moduleDone: { name, failed, passed, total }
738 moduleDone: registerLoggingCallback('moduleDone')
739 });
740
741 if ( typeof document === "undefined" || document.readyState === "complete" ) {
742 config.autorun = true;
743 }
744
745 QUnit.load = function() {
746 runLoggingCallbacks( 'begin', QUnit, {} );
747
748 // Initialize the config, saving the execution queue
749 var oldconfig = extend({}, config);
750 QUnit.init();
751 extend(config, oldconfig);
752
753 config.blocking = false;
754
755 var urlConfigHtml = '', len = config.urlConfig.length;
756 for ( var i = 0, val; i < len; i++ ) {
757 val = config.urlConfig[i];
758 config[val] = QUnit.urlParams[val];
759 urlConfigHtml += '<label><input name="' + val + '" type="checkbox"' + ( config[val] ? ' checked="checked"' : '' ) + '>' + val + '</label>';
760 }
761
762 var userAgent = id("qunit-userAgent");
763 if ( userAgent ) {
764 userAgent.innerHTML = navigator.userAgent;
765 }
766 var banner = id("qunit-header");
767 if ( banner ) {
768 banner.innerHTML = '<a href="' + QUnit.url({ filter: undefined }) + '"> ' + banner.innerHTML + '</a> ' + urlConfigHtml;
769 addEvent( banner, "change", function( event ) {
770 var params = {};
771 params[ event.target.name ] = event.target.checked ? true : undefined;
772 window.location = QUnit.url( params );
773 });
774 }
775
776 var toolbar = id("qunit-testrunner-toolbar");
777 if ( toolbar ) {
778 var filter = document.createElement("input");
779 filter.type = "checkbox";
780 filter.id = "qunit-filter-pass";
781 addEvent( filter, "click", function() {
782 var ol = document.getElementById("qunit-tests");
783 if ( filter.checked ) {
784 ol.className = ol.className + " hidepass";
785 } else {
786 var tmp = " " + ol.className.replace( /[\n\t\r]/g, " " ) + " ";
787 ol.className = tmp.replace(/ hidepass /, " ");
788 }
789 if ( defined.sessionStorage ) {
790 if (filter.checked) {
791 sessionStorage.setItem("qunit-filter-passed-tests", "true");
792 } else {
793 sessionStorage.removeItem("qunit-filter-passed-tests");
794 }
795 }
796 });
797 if ( config.hidepassed || defined.sessionStorage && sessionStorage.getItem("qunit-filter-passed-tests") ) {
798 filter.checked = true;
799 var ol = document.getElementById("qunit-tests");
800 ol.className = ol.className + " hidepass";
801 }
802 toolbar.appendChild( filter );
803
804 var label = document.createElement("label");
805 label.setAttribute("for", "qunit-filter-pass");
806 label.innerHTML = "Hide passed tests";
807 toolbar.appendChild( label );
808 }
809
810 var main = id('qunit-fixture');
811 if ( main ) {
812 config.fixture = main.innerHTML;
813 }
814
815 if (config.autostart) {
816 QUnit.start();
817 }
818 };
819
820 addEvent(window, "load", QUnit.load);
821
822 // addEvent(window, "error") gives us a useless event object
823 window.onerror = function( message, file, line ) {
824 if ( QUnit.config.current ) {
825 QUnit.pushFailure( message, file + ":" + line );
826 } else {
827 QUnit.test( "global failure", function() {
828 QUnit.pushFailure( message, file + ":" + line );
829 });
830 }
831 };
832
833 function done() {
834 config.autorun = true;
835
836 // Log the last module results
837 if ( config.currentModule ) {
838 runLoggingCallbacks( 'moduleDone', QUnit, {
839 name: config.currentModule,
840 failed: config.moduleStats.bad,
841 passed: config.moduleStats.all - config.moduleStats.bad,
842 total: config.moduleStats.all
843 } );
844 }
845
846 var banner = id("qunit-banner"),
847 tests = id("qunit-tests"),
848 runtime = +new Date() - config.started,
849 passed = config.stats.all - config.stats.bad,
850 html = [
851 'Tests completed in ',
852 runtime,
853 ' milliseconds.<br/>',
854 '<span class="passed">',
855 passed,
856 '</span> tests of <span class="total">',
857 config.stats.all,
858 '</span> passed, <span class="failed">',
859 config.stats.bad,
860 '</span> failed.'
861 ].join('');
862
863 if ( banner ) {
864 banner.className = (config.stats.bad ? "qunit-fail" : "qunit-pass");
865 }
866
867 if ( tests ) {
868 id( "qunit-testresult" ).innerHTML = html;
869 }
870
871 if ( config.altertitle && typeof document !== "undefined" && document.title ) {
872 // show ✖ for good, ✔ for bad suite result in title
873 // use escape sequences in case file gets loaded with non-utf-8-charset
874 document.title = [
875 (config.stats.bad ? "\u2716" : "\u2714"),
876 document.title.replace(/^[\u2714\u2716] /i, "")
877 ].join(" ");
878 }
879
880 // clear own sessionStorage items if all tests passed
881 if ( config.reorder && defined.sessionStorage && config.stats.bad === 0 ) {
882 var key;
883 for ( var i = 0; i < sessionStorage.length; i++ ) {
884 key = sessionStorage.key( i++ );
885 if ( key.indexOf("qunit-test-") === 0 ) {
886 sessionStorage.removeItem( key );
887 }
888 }
889 }
890
891 runLoggingCallbacks( 'done', QUnit, {
892 failed: config.stats.bad,
893 passed: passed,
894 total: config.stats.all,
895 runtime: runtime
896 } );
897 }
898
899 function validTest( name ) {
900 var filter = config.filter,
901 run = false;
902
903 if ( !filter ) {
904 return true;
905 }
906
907 var not = filter.charAt( 0 ) === "!";
908 if ( not ) {
909 filter = filter.slice( 1 );
910 }
911
912 if ( name.indexOf( filter ) !== -1 ) {
913 return !not;
914 }
915
916 if ( not ) {
917 run = true;
918 }
919
920 return run;
921 }
922
923 // so far supports only Firefox, Chrome and Opera (buggy), Safari (for real exceptions)
924 // Later Safari and IE10 are supposed to support error.stack as well
925 // See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack
926 function extractStacktrace( e, offset ) {
927 offset = offset || 3;
928 if (e.stacktrace) {
929 // Opera
930 return e.stacktrace.split("\n")[offset + 3];
931 } else if (e.stack) {
932 // Firefox, Chrome
933 var stack = e.stack.split("\n");
934 if (/^error$/i.test(stack[0])) {
935 stack.shift();
936 }
937 return stack[offset];
938 } else if (e.sourceURL) {
939 // Safari, PhantomJS
940 // hopefully one day Safari provides actual stacktraces
941 // exclude useless self-reference for generated Error objects
942 if ( /qunit.js$/.test( e.sourceURL ) ) {
943 return;
944 }
945 // for actual exceptions, this is useful
946 return e.sourceURL + ":" + e.line;
947 }
948 }
949 function sourceFromStacktrace(offset) {
950 try {
951 throw new Error();
952 } catch ( e ) {
953 return extractStacktrace( e, offset );
954 }
955 }
956
957 function escapeInnerText(s) {
958 if (!s) {
959 return "";
960 }
961 s = s + "";
962 return s.replace(/[\&<>]/g, function(s) {
963 switch(s) {
964 case "&": return "&amp;";
965 case "<": return "&lt;";
966 case ">": return "&gt;";
967 default: return s;
968 }
969 });
970 }
971
972 function synchronize( callback, last ) {
973 config.queue.push( callback );
974
975 if ( config.autorun && !config.blocking ) {
976 process(last);
977 }
978 }
979
980 function process( last ) {
981 function next() {
982 process( last );
983 }
984 var start = new Date().getTime();
985 config.depth = config.depth ? config.depth + 1 : 1;
986
987 while ( config.queue.length && !config.blocking ) {
988 if ( !defined.setTimeout || config.updateRate <= 0 || ( ( new Date().getTime() - start ) < config.updateRate ) ) {
989 config.queue.shift()();
990 } else {
991 window.setTimeout( next, 13 );
992 break;
993 }
994 }
995 config.depth--;
996 if ( last && !config.blocking && !config.queue.length && config.depth === 0 ) {
997 done();
998 }
999 }
1000
1001 function saveGlobal() {
1002 config.pollution = [];
1003
1004 if ( config.noglobals ) {
1005 for ( var key in window ) {
1006 if ( !hasOwn.call( window, key ) ) {
1007 continue;
1008 }
1009 config.pollution.push( key );
1010 }
1011 }
1012 }
1013
1014 function checkPollution( name ) {
1015 var old = config.pollution;
1016 saveGlobal();
1017
1018 var newGlobals = diff( config.pollution, old );
1019 if ( newGlobals.length > 0 ) {
1020 QUnit.pushFailure( "Introduced global variable(s): " + newGlobals.join(", ") );
1021 }
1022
1023 var deletedGlobals = diff( old, config.pollution );
1024 if ( deletedGlobals.length > 0 ) {
1025 QUnit.pushFailure( "Deleted global variable(s): " + deletedGlobals.join(", ") );
1026 }
1027 }
1028
1029 // returns a new Array with the elements that are in a but not in b
1030 function diff( a, b ) {
1031 var result = a.slice();
1032 for ( var i = 0; i < result.length; i++ ) {
1033 for ( var j = 0; j < b.length; j++ ) {
1034 if ( result[i] === b[j] ) {
1035 result.splice(i, 1);
1036 i--;
1037 break;
1038 }
1039 }
1040 }
1041 return result;
1042 }
1043
1044 function extend(a, b) {
1045 for ( var prop in b ) {
1046 if ( b[prop] === undefined ) {
1047 delete a[prop];
1048
1049 // Avoid "Member not found" error in IE8 caused by setting window.constructor
1050 } else if ( prop !== "constructor" || a !== window ) {
1051 a[prop] = b[prop];
1052 }
1053 }
1054
1055 return a;
1056 }
1057
1058 function addEvent(elem, type, fn) {
1059 if ( elem.addEventListener ) {
1060 elem.addEventListener( type, fn, false );
1061 } else if ( elem.attachEvent ) {
1062 elem.attachEvent( "on" + type, fn );
1063 } else {
1064 fn();
1065 }
1066 }
1067
1068 function id(name) {
1069 return !!(typeof document !== "undefined" && document && document.getElementById) &&
1070 document.getElementById( name );
1071 }
1072
1073 function registerLoggingCallback(key){
1074 return function(callback){
1075 config[key].push( callback );
1076 };
1077 }
1078
1079 // Supports deprecated method of completely overwriting logging callbacks
1080 function runLoggingCallbacks(key, scope, args) {
1081 //debugger;
1082 var callbacks;
1083 if ( QUnit.hasOwnProperty(key) ) {
1084 QUnit[key].call(scope, args);
1085 } else {
1086 callbacks = config[key];
1087 for( var i = 0; i < callbacks.length; i++ ) {
1088 callbacks[i].call( scope, args );
1089 }
1090 }
1091 }
1092
1093 // Test for equality any JavaScript type.
1094 // Author: Philippe Rathé <prathe@gmail.com>
1095 QUnit.equiv = (function() {
1096
1097 var innerEquiv; // the real equiv function
1098 var callers = []; // stack to decide between skip/abort functions
1099 var parents = []; // stack to avoiding loops from circular referencing
1100
1101 // Call the o related callback with the given arguments.
1102 function bindCallbacks(o, callbacks, args) {
1103 var prop = QUnit.objectType(o);
1104 if (prop) {
1105 if (QUnit.objectType(callbacks[prop]) === "function") {
1106 return callbacks[prop].apply(callbacks, args);
1107 } else {
1108 return callbacks[prop]; // or undefined
1109 }
1110 }
1111 }
1112
1113 var getProto = Object.getPrototypeOf || function (obj) {
1114 return obj.__proto__;
1115 };
1116
1117 var callbacks = (function () {
1118
1119 // for string, boolean, number and null
1120 function useStrictEquality(b, a) {
1121 if (b instanceof a.constructor || a instanceof b.constructor) {
1122 // to catch short annotaion VS 'new' annotation of a
1123 // declaration
1124 // e.g. var i = 1;
1125 // var j = new Number(1);
1126 return a == b;
1127 } else {
1128 return a === b;
1129 }
1130 }
1131
1132 return {
1133 "string" : useStrictEquality,
1134 "boolean" : useStrictEquality,
1135 "number" : useStrictEquality,
1136 "null" : useStrictEquality,
1137 "undefined" : useStrictEquality,
1138
1139 "nan" : function(b) {
1140 return isNaN(b);
1141 },
1142
1143 "date" : function(b, a) {
1144 return QUnit.objectType(b) === "date" && a.valueOf() === b.valueOf();
1145 },
1146
1147 "regexp" : function(b, a) {
1148 return QUnit.objectType(b) === "regexp" &&
1149 // the regex itself
1150 a.source === b.source &&
1151 // and its modifers
1152 a.global === b.global &&
1153 // (gmi) ...
1154 a.ignoreCase === b.ignoreCase &&
1155 a.multiline === b.multiline;
1156 },
1157
1158 // - skip when the property is a method of an instance (OOP)
1159 // - abort otherwise,
1160 // initial === would have catch identical references anyway
1161 "function" : function() {
1162 var caller = callers[callers.length - 1];
1163 return caller !== Object && typeof caller !== "undefined";
1164 },
1165
1166 "array" : function(b, a) {
1167 var i, j, loop;
1168 var len;
1169
1170 // b could be an object literal here
1171 if (QUnit.objectType(b) !== "array") {
1172 return false;
1173 }
1174
1175 len = a.length;
1176 if (len !== b.length) { // safe and faster
1177 return false;
1178 }
1179
1180 // track reference to avoid circular references
1181 parents.push(a);
1182 for (i = 0; i < len; i++) {
1183 loop = false;
1184 for (j = 0; j < parents.length; j++) {
1185 if (parents[j] === a[i]) {
1186 loop = true;// dont rewalk array
1187 }
1188 }
1189 if (!loop && !innerEquiv(a[i], b[i])) {
1190 parents.pop();
1191 return false;
1192 }
1193 }
1194 parents.pop();
1195 return true;
1196 },
1197
1198 "object" : function(b, a) {
1199 var i, j, loop;
1200 var eq = true; // unless we can proove it
1201 var aProperties = [], bProperties = []; // collection of
1202 // strings
1203
1204 // comparing constructors is more strict than using
1205 // instanceof
1206 if (a.constructor !== b.constructor) {
1207 // Allow objects with no prototype to be equivalent to
1208 // objects with Object as their constructor.
1209 if (!((getProto(a) === null && getProto(b) === Object.prototype) ||
1210 (getProto(b) === null && getProto(a) === Object.prototype)))
1211 {
1212 return false;
1213 }
1214 }
1215
1216 // stack constructor before traversing properties
1217 callers.push(a.constructor);
1218 // track reference to avoid circular references
1219 parents.push(a);
1220
1221 for (i in a) { // be strict: don't ensures hasOwnProperty
1222 // and go deep
1223 loop = false;
1224 for (j = 0; j < parents.length; j++) {
1225 if (parents[j] === a[i]) {
1226 // don't go down the same path twice
1227 loop = true;
1228 }
1229 }
1230 aProperties.push(i); // collect a's properties
1231
1232 if (!loop && !innerEquiv(a[i], b[i])) {
1233 eq = false;
1234 break;
1235 }
1236 }
1237
1238 callers.pop(); // unstack, we are done
1239 parents.pop();
1240
1241 for (i in b) {
1242 bProperties.push(i); // collect b's properties
1243 }
1244
1245 // Ensures identical properties name
1246 return eq && innerEquiv(aProperties.sort(), bProperties.sort());
1247 }
1248 };
1249 }());
1250
1251 innerEquiv = function() { // can take multiple arguments
1252 var args = Array.prototype.slice.apply(arguments);
1253 if (args.length < 2) {
1254 return true; // end transition
1255 }
1256
1257 return (function(a, b) {
1258 if (a === b) {
1259 return true; // catch the most you can
1260 } else if (a === null || b === null || typeof a === "undefined" ||
1261 typeof b === "undefined" ||
1262 QUnit.objectType(a) !== QUnit.objectType(b)) {
1263 return false; // don't lose time with error prone cases
1264 } else {
1265 return bindCallbacks(a, callbacks, [ b, a ]);
1266 }
1267
1268 // apply transition with (1..n) arguments
1269 }(args[0], args[1]) && arguments.callee.apply(this, args.splice(1, args.length - 1)));
1270 };
1271
1272 return innerEquiv;
1273
1274 }());
1275
1276 /**
1277 * jsDump Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com |
1278 * http://flesler.blogspot.com Licensed under BSD
1279 * (http://www.opensource.org/licenses/bsd-license.php) Date: 5/15/2008
1280 *
1281 * @projectDescription Advanced and extensible data dumping for Javascript.
1282 * @version 1.0.0
1283 * @author Ariel Flesler
1284 * @link {http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html}
1285 */
1286 QUnit.jsDump = (function() {
1287 function quote( str ) {
1288 return '"' + str.toString().replace(/"/g, '\\"') + '"';
1289 }
1290 function literal( o ) {
1291 return o + '';
1292 }
1293 function join( pre, arr, post ) {
1294 var s = jsDump.separator(),
1295 base = jsDump.indent(),
1296 inner = jsDump.indent(1);
1297 if ( arr.join ) {
1298 arr = arr.join( ',' + s + inner );
1299 }
1300 if ( !arr ) {
1301 return pre + post;
1302 }
1303 return [ pre, inner + arr, base + post ].join(s);
1304 }
1305 function array( arr, stack ) {
1306 var i = arr.length, ret = new Array(i);
1307 this.up();
1308 while ( i-- ) {
1309 ret[i] = this.parse( arr[i] , undefined , stack);
1310 }
1311 this.down();
1312 return join( '[', ret, ']' );
1313 }
1314
1315 var reName = /^function (\w+)/;
1316
1317 var jsDump = {
1318 parse: function( obj, type, stack ) { //type is used mostly internally, you can fix a (custom)type in advance
1319 stack = stack || [ ];
1320 var parser = this.parsers[ type || this.typeOf(obj) ];
1321 type = typeof parser;
1322 var inStack = inArray(obj, stack);
1323 if (inStack != -1) {
1324 return 'recursion('+(inStack - stack.length)+')';
1325 }
1326 //else
1327 if (type == 'function') {
1328 stack.push(obj);
1329 var res = parser.call( this, obj, stack );
1330 stack.pop();
1331 return res;
1332 }
1333 // else
1334 return (type == 'string') ? parser : this.parsers.error;
1335 },
1336 typeOf: function( obj ) {
1337 var type;
1338 if ( obj === null ) {
1339 type = "null";
1340 } else if (typeof obj === "undefined") {
1341 type = "undefined";
1342 } else if (QUnit.is("RegExp", obj)) {
1343 type = "regexp";
1344 } else if (QUnit.is("Date", obj)) {
1345 type = "date";
1346 } else if (QUnit.is("Function", obj)) {
1347 type = "function";
1348 } else if (typeof obj.setInterval !== undefined && typeof obj.document !== "undefined" && typeof obj.nodeType === "undefined") {
1349 type = "window";
1350 } else if (obj.nodeType === 9) {
1351 type = "document";
1352 } else if (obj.nodeType) {
1353 type = "node";
1354 } else if (
1355 // native arrays
1356 toString.call( obj ) === "[object Array]" ||
1357 // NodeList objects
1358 ( typeof obj.length === "number" && typeof obj.item !== "undefined" && ( obj.length ? obj.item(0) === obj[0] : ( obj.item( 0 ) === null && typeof obj[0] === "undefined" ) ) )
1359 ) {
1360 type = "array";
1361 } else {
1362 type = typeof obj;
1363 }
1364 return type;
1365 },
1366 separator: function() {
1367 return this.multiline ? this.HTML ? '<br />' : '\n' : this.HTML ? '&nbsp;' : ' ';
1368 },
1369 indent: function( extra ) {// extra can be a number, shortcut for increasing-calling-decreasing
1370 if ( !this.multiline ) {
1371 return '';
1372 }
1373 var chr = this.indentChar;
1374 if ( this.HTML ) {
1375 chr = chr.replace(/\t/g,' ').replace(/ /g,'&nbsp;');
1376 }
1377 return new Array( this._depth_ + (extra||0) ).join(chr);
1378 },
1379 up: function( a ) {
1380 this._depth_ += a || 1;
1381 },
1382 down: function( a ) {
1383 this._depth_ -= a || 1;
1384 },
1385 setParser: function( name, parser ) {
1386 this.parsers[name] = parser;
1387 },
1388 // The next 3 are exposed so you can use them
1389 quote: quote,
1390 literal: literal,
1391 join: join,
1392 //
1393 _depth_: 1,
1394 // This is the list of parsers, to modify them, use jsDump.setParser
1395 parsers: {
1396 window: '[Window]',
1397 document: '[Document]',
1398 error: '[ERROR]', //when no parser is found, shouldn't happen
1399 unknown: '[Unknown]',
1400 'null': 'null',
1401 'undefined': 'undefined',
1402 'function': function( fn ) {
1403 var ret = 'function',
1404 name = 'name' in fn ? fn.name : (reName.exec(fn)||[])[1];//functions never have name in IE
1405 if ( name ) {
1406 ret += ' ' + name;
1407 }
1408 ret += '(';
1409
1410 ret = [ ret, QUnit.jsDump.parse( fn, 'functionArgs' ), '){'].join('');
1411 return join( ret, QUnit.jsDump.parse(fn,'functionCode'), '}' );
1412 },
1413 array: array,
1414 nodelist: array,
1415 'arguments': array,
1416 object: function( map, stack ) {
1417 var ret = [ ], keys, key, val, i;
1418 QUnit.jsDump.up();
1419 if (Object.keys) {
1420 keys = Object.keys( map );
1421 } else {
1422 keys = [];
1423 for (key in map) { keys.push( key ); }
1424 }
1425 keys.sort();
1426 for (i = 0; i < keys.length; i++) {
1427 key = keys[ i ];
1428 val = map[ key ];
1429 ret.push( QUnit.jsDump.parse( key, 'key' ) + ': ' + QUnit.jsDump.parse( val, undefined, stack ) );
1430 }
1431 QUnit.jsDump.down();
1432 return join( '{', ret, '}' );
1433 },
1434 node: function( node ) {
1435 var open = QUnit.jsDump.HTML ? '&lt;' : '<',
1436 close = QUnit.jsDump.HTML ? '&gt;' : '>';
1437
1438 var tag = node.nodeName.toLowerCase(),
1439 ret = open + tag;
1440
1441 for ( var a in QUnit.jsDump.DOMAttrs ) {
1442 var val = node[QUnit.jsDump.DOMAttrs[a]];
1443 if ( val ) {
1444 ret += ' ' + a + '=' + QUnit.jsDump.parse( val, 'attribute' );
1445 }
1446 }
1447 return ret + close + open + '/' + tag + close;
1448 },
1449 functionArgs: function( fn ) {//function calls it internally, it's the arguments part of the function
1450 var l = fn.length;
1451 if ( !l ) {
1452 return '';
1453 }
1454
1455 var args = new Array(l);
1456 while ( l-- ) {
1457 args[l] = String.fromCharCode(97+l);//97 is 'a'
1458 }
1459 return ' ' + args.join(', ') + ' ';
1460 },
1461 key: quote, //object calls it internally, the key part of an item in a map
1462 functionCode: '[code]', //function calls it internally, it's the content of the function
1463 attribute: quote, //node calls it internally, it's an html attribute value
1464 string: quote,
1465 date: quote,
1466 regexp: literal, //regex
1467 number: literal,
1468 'boolean': literal
1469 },
1470 DOMAttrs:{//attributes to dump from nodes, name=>realName
1471 id:'id',
1472 name:'name',
1473 'class':'className'
1474 },
1475 HTML:false,//if true, entities are escaped ( <, >, \t, space and \n )
1476 indentChar:' ',//indentation unit
1477 multiline:true //if true, items in a collection, are separated by a \n, else just a space.
1478 };
1479
1480 return jsDump;
1481 }());
1482
1483 // from Sizzle.js
1484 function getText( elems ) {
1485 var ret = "", elem;
1486
1487 for ( var i = 0; elems[i]; i++ ) {
1488 elem = elems[i];
1489
1490 // Get the text from text nodes and CDATA nodes
1491 if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
1492 ret += elem.nodeValue;
1493
1494 // Traverse everything else, except comment nodes
1495 } else if ( elem.nodeType !== 8 ) {
1496 ret += getText( elem.childNodes );
1497 }
1498 }
1499
1500 return ret;
1501 }
1502
1503 //from jquery.js
1504 function inArray( elem, array ) {
1505 if ( array.indexOf ) {
1506 return array.indexOf( elem );
1507 }
1508
1509 for ( var i = 0, length = array.length; i < length; i++ ) {
1510 if ( array[ i ] === elem ) {
1511 return i;
1512 }
1513 }
1514
1515 return -1;
1516 }
1517
1518 /*
1519 * Javascript Diff Algorithm
1520 * By John Resig (http://ejohn.org/)
1521 * Modified by Chu Alan "sprite"
1522 *
1523 * Released under the MIT license.
1524 *
1525 * More Info:
1526 * http://ejohn.org/projects/javascript-diff-algorithm/
1527 *
1528 * Usage: QUnit.diff(expected, actual)
1529 *
1530 * QUnit.diff("the quick brown fox jumped over", "the quick fox jumps over") == "the quick <del>brown </del> fox <del>jumped </del><ins>jumps </ins> over"
1531 */
1532 QUnit.diff = (function() {
1533 function diff(o, n) {
1534 var ns = {};
1535 var os = {};
1536 var i;
1537
1538 for (i = 0; i < n.length; i++) {
1539 if (ns[n[i]] == null) {
1540 ns[n[i]] = {
1541 rows: [],
1542 o: null
1543 };
1544 }
1545 ns[n[i]].rows.push(i);
1546 }
1547
1548 for (i = 0; i < o.length; i++) {
1549 if (os[o[i]] == null) {
1550 os[o[i]] = {
1551 rows: [],
1552 n: null
1553 };
1554 }
1555 os[o[i]].rows.push(i);
1556 }
1557
1558 for (i in ns) {
1559 if ( !hasOwn.call( ns, i ) ) {
1560 continue;
1561 }
1562 if (ns[i].rows.length == 1 && typeof(os[i]) != "undefined" && os[i].rows.length == 1) {
1563 n[ns[i].rows[0]] = {
1564 text: n[ns[i].rows[0]],
1565 row: os[i].rows[0]
1566 };
1567 o[os[i].rows[0]] = {
1568 text: o[os[i].rows[0]],
1569 row: ns[i].rows[0]
1570 };
1571 }
1572 }
1573
1574 for (i = 0; i < n.length - 1; i++) {
1575 if (n[i].text != null && n[i + 1].text == null && n[i].row + 1 < o.length && o[n[i].row + 1].text == null &&
1576 n[i + 1] == o[n[i].row + 1]) {
1577 n[i + 1] = {
1578 text: n[i + 1],
1579 row: n[i].row + 1
1580 };
1581 o[n[i].row + 1] = {
1582 text: o[n[i].row + 1],
1583 row: i + 1
1584 };
1585 }
1586 }
1587
1588 for (i = n.length - 1; i > 0; i--) {
1589 if (n[i].text != null && n[i - 1].text == null && n[i].row > 0 && o[n[i].row - 1].text == null &&
1590 n[i - 1] == o[n[i].row - 1]) {
1591 n[i - 1] = {
1592 text: n[i - 1],
1593 row: n[i].row - 1
1594 };
1595 o[n[i].row - 1] = {
1596 text: o[n[i].row - 1],
1597 row: i - 1
1598 };
1599 }
1600 }
1601
1602 return {
1603 o: o,
1604 n: n
1605 };
1606 }
1607
1608 return function(o, n) {
1609 o = o.replace(/\s+$/, '');
1610 n = n.replace(/\s+$/, '');
1611 var out = diff(o === "" ? [] : o.split(/\s+/), n === "" ? [] : n.split(/\s+/));
1612
1613 var str = "";
1614 var i;
1615
1616 var oSpace = o.match(/\s+/g);
1617 if (oSpace == null) {
1618 oSpace = [" "];
1619 }
1620 else {
1621 oSpace.push(" ");
1622 }
1623 var nSpace = n.match(/\s+/g);
1624 if (nSpace == null) {
1625 nSpace = [" "];
1626 }
1627 else {
1628 nSpace.push(" ");
1629 }
1630
1631 if (out.n.length === 0) {
1632 for (i = 0; i < out.o.length; i++) {
1633 str += '<del>' + out.o[i] + oSpace[i] + "</del>";
1634 }
1635 }
1636 else {
1637 if (out.n[0].text == null) {
1638 for (n = 0; n < out.o.length && out.o[n].text == null; n++) {
1639 str += '<del>' + out.o[n] + oSpace[n] + "</del>";
1640 }
1641 }
1642
1643 for (i = 0; i < out.n.length; i++) {
1644 if (out.n[i].text == null) {
1645 str += '<ins>' + out.n[i] + nSpace[i] + "</ins>";
1646 }
1647 else {
1648 var pre = "";
1649
1650 for (n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++) {
1651 pre += '<del>' + out.o[n] + oSpace[n] + "</del>";
1652 }
1653 str += " " + out.n[i].text + nSpace[i] + pre;
1654 }
1655 }
1656 }
1657
1658 return str;
1659 };
1660 }());
1661
1662 // for CommonJS enviroments, export everything
1663 if ( typeof exports !== "undefined" || typeof require !== "undefined" ) {
1664 extend(exports, QUnit);
1665 }
1666
1667 // get at whatever the global object is, like window in browsers
1668 }( (function() {return this;}.call()) ));
33 # speed and size. Makes sense to use only on PEG.js Git repository checkout.
44
55 set -e
6 export LC_ALL=C
67
78 # Measurement
89
910 prepare() {
1011 git checkout --quiet "$1"
11 make build
1212 }
1313
1414 run_benchmark() {
6060
6161 echo
6262
63 echo "(Measured by /tools/impact with Node.js $(node --version) on $(uname --operating-system --machine).)"
63 echo "(Measured by /tools/impact with Node.js $(node --version) on $(uname -mrs).)"
6464 }
6565
6666 print_usage() {
100100
101101 cd_to_root
102102
103 echo -n "Measuring commit $commit_before..."
103 printf "Measuring commit %s..." "$commit_before"
104104 prepare "$commit_before"
105105 speed1=$(measure_speed)
106106 size1=$(measure_size)
107107 echo " OK"
108108
109 echo -n "Measuring commit $commit_after..."
109 printf "Measuring commit %s..." "$commit_after"
110110 prepare "$commit_after"
111111 speed2=$(measure_speed)
112112 size2=$(measure_size)