From 2691644664c60daa7cbf10de30bb4a9f4722750f Mon Sep 17 00:00:00 2001 From: Cameron McHenry Date: Thu, 7 Jul 2022 13:37:16 -0400 Subject: [PATCH 01/12] Add base layout --- docs/_includes/base-layout.html | 61 + docs/css/documentation.css | 19 + docs/development/benchmark.html | 107 +- docs/development/index.html | 111 +- docs/documentation.html | 1840 +++++++++++++++---------------- docs/index.html | 159 +-- 6 files changed, 1082 insertions(+), 1215 deletions(-) create mode 100644 docs/_includes/base-layout.html create mode 100644 docs/css/documentation.css diff --git a/docs/_includes/base-layout.html b/docs/_includes/base-layout.html new file mode 100644 index 00000000..01181498 --- /dev/null +++ b/docs/_includes/base-layout.html @@ -0,0 +1,61 @@ + + + + + + + + Peggy – Parser Generator for JavaScript + + + + + + {% if scripts %} + {% for script in scripts %} + + {% endfor %} + {% endif %} + {% if stylesheets %} + {% for stylesheet in stylesheets %} + + {% endfor %} + {% endif %} + + +
+ + + + +
{{content}}
+ + +
+ + diff --git a/docs/css/documentation.css b/docs/css/documentation.css new file mode 100644 index 00000000..275a2a2d --- /dev/null +++ b/docs/css/documentation.css @@ -0,0 +1,19 @@ +.example { + background-color: #f0f0f0; + display: flex; + flex-direction: row; + padding: 0.25em 0.5em; + margin: 0.5em; + border-radius: 0.5em; +} +.example .result { + font-family: monospace; + white-space: pre-wrap; + margin-left: 5px; +} +.example .try { + margin-left: 30px; +} +.error { + color: red; +} diff --git a/docs/development/benchmark.html b/docs/development/benchmark.html index a624e7a6..ee6a5836 100644 --- a/docs/development/benchmark.html +++ b/docs/development/benchmark.html @@ -1,82 +1,31 @@ --- -permalink: '/development/benchmark.html' +permalink: "/development/benchmark.html" +layout: base-layout +stylesheets: ["../css/benchmark.css"] +scripts: + [ + "https://unpkg.com/jquery@1.12.4/dist/jquery.min.js", + "https://unpkg.com/jquery.scrollto@2.1.2/jquery.scrollTo.min.js", + "../js/benchmark-bundle.min.js", + ] --- - - - - - - - - - Benchmark » Peggy – Parser Generator for JavaScript - - - - - - - - - -
- - - - -
- - - - - -
- - times - - - -
- - - - - - - - - - - -
TestInput SizeAverage Parse TimeAverage Parse Speed
No results available yet.
- - - - -
- - -
- - - +
+ + times + + + +
+ + + + + + + + + + + +
TestInput SizeAverage Parse TimeAverage Parse Speed
No results available yet.
diff --git a/docs/development/index.html b/docs/development/index.html index b0ab2342..51f191de 100644 --- a/docs/development/index.html +++ b/docs/development/index.html @@ -1,86 +1,33 @@ --- permalink: '/development/index.html' +layout: base-layout --- - - - - - - - - - Development » Peggy – Parser Generator for JavaScript - - - - - - - - - -
- - - - -
- - - -

Development

- - - -

Starting in April 2021, Peggy has been maintained by - Joe Hildebrand - (@hildjj). It was previously - known as PEG.js, but had - fallen into limbo - before a community-desired fork.

- -

Since its inception - in 2010, PEG.js was maintained by David Majda - (@dmajda), - until May 2017 - when Futago-za Ryuu took over.

- -

You are welcome to contribute code. Unless your contribution is really - trivial you should get in touch with us - first — this can prevent wasted effort on both sides.

- -
- - -
- - - +

Development

+ + + +

Starting in April 2021, Peggy has been maintained by +Joe Hildebrand +(@hildjj). It was previously +known as PEG.js, but had +fallen into limbo +before a community-desired fork.

+ +

Since its inception +in 2010, PEG.js was maintained by David Majda +(@dmajda), +until May 2017 +when Futago-za Ryuu took over.

+ +

You are welcome to contribute code. Unless your contribution is really +trivial you should get in touch with us +first — this can prevent wasted effort on both sides.

\ No newline at end of file diff --git a/docs/documentation.html b/docs/documentation.html index c5a23010..6e069091 100644 --- a/docs/documentation.html +++ b/docs/documentation.html @@ -1,110 +1,52 @@ --- permalink: '/documentation.html' +layout: base-layout +scripts: ["js/examples.js?2022-06-03T00:53:11Z"] +stylesheets: ["css/documentation.css"] --- - - - - - - - - - Documentation » Peggy – Parser Generator for JavaScript - - - - - - - - - - -
- - - - -
- -

Documentation

+

Documentation

Table of Contents

Installation

@@ -137,8 +79,8 @@

Browser

information:

When your document is done loading, there will be a global peggy object.

@@ -171,88 +113,88 @@

Command Line

You can tweak the generated parser with several options:

-
--allowed-start-rules <rules>
-
Comma-separated list of rules the parser will be allowed to start parsing - from (default: only the first rule in the grammar).
- -
--ast
-
Outputting an internal AST representation of the grammar after - all optimizations instead of the parser source code. Useful for plugin authors - to see how their plugin changes the AST. This option cannot be mixed with the - -t/--test, -T/--test-file and -m/--source-map - options.
- -
--cache
-
Makes the parser cache results, avoiding exponential parsing time in - pathological cases but making the parser slower.
- -
-d, --dependency <[name:]module>
-
Makes the parser require a specified dependency (can be specified - multiple times). A variable name for the import/require/etc. may be given, - followed by a colon. If no name is given, the module name will also be used - for the variable name.
- -
-D, --dependencies <json>
-
Dependencies, in JSON object format with variable:module pairs. (Can be - specified multiple times).
- -
-e, --export-var <variable>
-
Name of a global variable into which the parser object is assigned to when - no module loader is detected.
- -
--extra-options <options>
-
Additional options (in JSON format, as an object) to pass to - peg.generate.
- -
-c, --extra-options-file <file>
-
File with additional options (in JSON format, as an object) to pass to - peg.generate.
- -
--format <format>
-
Format of the generated parser: amd, commonjs, - globals, umd, es (default: commonjs).
- -
-o, --output <file>
-
File to send output to. Defaults to input file name with - extension changed to .js, or stdout if no input file is given.
- -
--plugin
-
Makes Peggy use a specified plugin (can be specified multiple - times).
- -
-m, --source-map <file>
-
Generate a source map. If name is not specified, the source map will be - named "<input_file>.map" if input is a file and "source.map" if input - is a standard input. If the special filename inline is given, - the sourcemap will be embedded in the output file as a data URI. If the - filename is prefixed with hidden:, no mapping URL will be - included so that the mapping can be specified with an HTTP SourceMap: - header. This option conflicts with the -t/--test and - -T/--test-file options unless -o/--output is also - specified
- -
-S, --start-rule <rule>
-
When testing, use this rule as the start rule. Automatically added to - the allowedStartRules.
- -
-t, --test <text>
-
Test the parser with the given text, outputting the result of running - the parser against this input. - If the input to be tested is not parsed, the CLI will exit with code 2.
- -
-T, --test-file <text>
-
Test the parser with the contents of the given file, outputting the - result of running the parser against this input. - If the input to be tested is not parsed, the CLI will exit with code 2.
- -
--trace
-
Makes the parser trace its progress.
- -
-v, --version
-
Output the version number.
- -
-h, --help
-
Display help for the command.
+
--allowed-start-rules <rules>
+
Comma-separated list of rules the parser will be allowed to start parsing +from (default: only the first rule in the grammar).
+ +
--ast
+
Outputting an internal AST representation of the grammar after +all optimizations instead of the parser source code. Useful for plugin authors +to see how their plugin changes the AST. This option cannot be mixed with the +-t/--test, -T/--test-file and -m/--source-map +options.
+ +
--cache
+
Makes the parser cache results, avoiding exponential parsing time in +pathological cases but making the parser slower.
+ +
-d, --dependency <[name:]module>
+
Makes the parser require a specified dependency (can be specified +multiple times). A variable name for the import/require/etc. may be given, +followed by a colon. If no name is given, the module name will also be used +for the variable name.
+ +
-D, --dependencies <json>
+
Dependencies, in JSON object format with variable:module pairs. (Can be +specified multiple times).
+ +
-e, --export-var <variable>
+
Name of a global variable into which the parser object is assigned to when +no module loader is detected.
+ +
--extra-options <options>
+
Additional options (in JSON format, as an object) to pass to +peg.generate.
+ +
-c, --extra-options-file <file>
+
File with additional options (in JSON format, as an object) to pass to +peg.generate.
+ +
--format <format>
+
Format of the generated parser: amd, commonjs, +globals, umd, es (default: commonjs).
+ +
-o, --output <file>
+
File to send output to. Defaults to input file name with +extension changed to .js, or stdout if no input file is given.
+ +
--plugin
+
Makes Peggy use a specified plugin (can be specified multiple +times).
+ +
-m, --source-map <file>
+
Generate a source map. If name is not specified, the source map will be +named "<input_file>.map" if input is a file and "source.map" if input +is a standard input. If the special filename inline is given, +the sourcemap will be embedded in the output file as a data URI. If the +filename is prefixed with hidden:, no mapping URL will be +included so that the mapping can be specified with an HTTP SourceMap: +header. This option conflicts with the -t/--test and +-T/--test-file options unless -o/--output is also +specified
+ +
-S, --start-rule <rule>
+
When testing, use this rule as the start rule. Automatically added to +the allowedStartRules.
+ +
-t, --test <text>
+
Test the parser with the given text, outputting the result of running +the parser against this input. +If the input to be tested is not parsed, the CLI will exit with code 2.
+ +
-T, --test-file <text>
+
Test the parser with the contents of the given file, outputting the +result of running the parser against this input. +If the input to be tested is not parsed, the CLI will exit with code 2.
+ +
--trace
+
Makes the parser trace its progress.
+ +
-v, --version
+
Output the version number.
+ +
-h, --help
+
Display help for the command.
@@ -268,13 +210,13 @@

Command Line

// config.js or config.cjs
 module.exports = {
-  allowedStartRules = ["foo", "bar"],
-  format: "umd",
-  exportVar: "foo",
-  input: "fooGrammar.peggy",
-  plugins: [require("./plugin.js")],
-  testFile: "myTestInput.foo",
-  trace: true
+allowedStartRules = ["foo", "bar"],
+format: "umd",
+exportVar: "foo",
+input: "fooGrammar.peggy",
+plugins: [require("./plugin.js")],
+testFile: "myTestInput.foo",
+trace: true
 };
 
@@ -287,10 +229,10 @@

Command Line

The CLI will exit with the code:

    -
  • 0 if all was success
  • -
  • 1 if you supply incorrect or conflicting parameters
  • -
  • 2 if all parameters is correct, you specify the -t/--test or -T/--test-file option - and specified input does not parsed with the specified grammar
  • +
  • 0 if all was success
  • +
  • 1 if you supply incorrect or conflicting parameters
  • +
  • 2 if all parameters is correct, you specify the -t/--test or -T/--test-file option +and specified input does not parsed with the specified grammar

Examples:

@@ -356,97 +298,97 @@

JavaScript API

supported:

-
allowedStartRules
-
Rules the parser will be allowed to start parsing from (default: the - first rule in the grammar). If any of the rules specified is "*", any of - the rules in the grammar can be used as start rules.
- -
cache
-
If true, makes the parser cache results, avoiding exponential - parsing time in pathological cases but making the parser slower (default: - false).
- -
dependencies
-
Parser dependencies, the value is an object which maps variables used to - access the dependencies in the parser to module IDs used to load them; valid - only when format is set to "amd", - "commonjs", "es", or "umd". - Dependencies variables will be available in both the global - initializer and the per-parse initializer. Unless the parser is - to be generated in different formats, it is recommended to rather import - dependencies from within the global initializer (default: - {}).
- -
error
-
Callback for errors. See Error Reporting
- -
exportVar
-
Name of a global variable into which the parser object is assigned to when - no module loader is detected; valid only when format is set to - "globals" or "umd" (default: - null).
- -
format
-
- Format of the generated parser ("amd", "bare", - "commonjs", "es", "globals", or - "umd"); valid only when output is set to - "source", "source-and-map", or - "source-with-inline-map". (default: "bare"). -
- -
grammarSource
-
any object that represent origin of the input grammar. The CLI will set - it to a string with the path to the file; parsers in network applications - might use the socket and so on. The supplied object will be available at key - source in the location objects, that returned by the - location() API function (default: undefined).
- -
info
-
Callback for informational messages. See Error Reporting
- -
output
-

A string, one of:

-
    -
  • "parser" - return generated parser object.
  • -
  • "source" - return parser source code as a string.
  • -
  • "source-and-map" - return a - SourceNode - object; you can get source code by calling toString() - method or source code and mapping by calling - toStringWithSourceMap() method, see the - SourceNode - documentation. -
  • -
  • "source-with-inline-map" - return the parser source along - with an embedded source map as a data: URI. This option - leads to a larger output string, but is the easiest to integrate with - developer tooling.
  • -
  • "ast" - return the internal AST of the grammar as a JSON - string. Useful for plugin authors to explore internals of Peggy and - for automation.
  • -
-

(default: "parser")

-
-

Note: You should also set grammarSource - to a not-empty string if you set this value to - "source-and-map" or - "source-with-inline-map". The path should be relative to - the location where the generated parser code will be stored. For - example, if you are generating lib/parser.js from - src/parser.peggy, then your options should be: - { grammarSource: "../src/parser.peggy" }

-
-
- -
plugins
-
Plugins to use. See the Plugins API section.
- -
trace
-
Makes the parser trace its progress (default: false).
- -
warning
-
Callback for warnings. See Error Reporting
+
allowedStartRules
+
Rules the parser will be allowed to start parsing from (default: the +first rule in the grammar). If any of the rules specified is "*", any of +the rules in the grammar can be used as start rules.
+ +
cache
+
If true, makes the parser cache results, avoiding exponential +parsing time in pathological cases but making the parser slower (default: +false).
+ +
dependencies
+
Parser dependencies, the value is an object which maps variables used to +access the dependencies in the parser to module IDs used to load them; valid +only when format is set to "amd", +"commonjs", "es", or "umd". +Dependencies variables will be available in both the global +initializer and the per-parse initializer. Unless the parser is +to be generated in different formats, it is recommended to rather import +dependencies from within the global initializer (default: +{}).
+ +
error
+
Callback for errors. See Error Reporting
+ +
exportVar
+
Name of a global variable into which the parser object is assigned to when +no module loader is detected; valid only when format is set to +"globals" or "umd" (default: +null).
+ +
format
+
+Format of the generated parser ("amd", "bare", +"commonjs", "es", "globals", or +"umd"); valid only when output is set to +"source", "source-and-map", or +"source-with-inline-map". (default: "bare"). +
+ +
grammarSource
+
any object that represent origin of the input grammar. The CLI will set +it to a string with the path to the file; parsers in network applications +might use the socket and so on. The supplied object will be available at key +source in the location objects, that returned by the +location() API function (default: undefined).
+ +
info
+
Callback for informational messages. See Error Reporting
+ +
output
+

A string, one of:

+
    +
  • "parser" - return generated parser object.
  • +
  • "source" - return parser source code as a string.
  • +
  • "source-and-map" - return a +SourceNode +object; you can get source code by calling toString() +method or source code and mapping by calling +toStringWithSourceMap() method, see the +SourceNode +documentation. +
  • +
  • "source-with-inline-map" - return the parser source along +with an embedded source map as a data: URI. This option +leads to a larger output string, but is the easiest to integrate with +developer tooling.
  • +
  • "ast" - return the internal AST of the grammar as a JSON + string. Useful for plugin authors to explore internals of Peggy and + for automation.
  • +
+

(default: "parser")

+
+

Note: You should also set grammarSource +to a not-empty string if you set this value to +"source-and-map" or +"source-with-inline-map". The path should be relative to +the location where the generated parser code will be stored. For +example, if you are generating lib/parser.js from +src/parser.peggy, then your options should be: +{ grammarSource: "../src/parser.peggy" }

+
+
+ +
plugins
+
Plugins to use. See the Plugins API section.
+ +
trace
+
Makes the parser trace its progress (default: false).
+ +
warning
+
Callback for warnings. See Error Reporting

Error Reporting

@@ -458,9 +400,9 @@

Error Reporting

register one or more of these callbacks:

    -
  • error(stage: Stage, message: string, location?: LocationRange, notes?: DiagnosticNote[]): void
  • -
  • warning(stage: Stage, message: string, location?: LocationRange, notes?: DiagnosticNote[]): void
  • -
  • info(stage: Stage, message: string, location?: LocationRange, notes?: DiagnosticNote[]): void
  • +
  • error(stage: Stage, message: string, location?: LocationRange, notes?: DiagnosticNote[]): void
  • +
  • warning(stage: Stage, message: string, location?: LocationRange, notes?: DiagnosticNote[]): void
  • +
  • info(stage: Stage, message: string, location?: LocationRange, notes?: DiagnosticNote[]): void

All parameters are the same as the parameters of the reporting API except the first. @@ -468,9 +410,9 @@

Error Reporting

This is a string enumeration, that currently has one of three values:

    -
  • check
  • -
  • transform
  • -
  • generate
  • +
  • check
  • +
  • transform
  • +
  • generate

Using the Parser

@@ -494,29 +436,29 @@

Using the Parser

supported:

-
startRule
-
Name of the rule to start parsing from.
+
startRule
+
Name of the rule to start parsing from.
-
tracer
-
Tracer to use.
+
tracer
+
Tracer to use.
-
... (any others)
-
Made available in the options variable
+
... (any others)
+
Made available in the options variable

As you can see above, parsers can also support their own custom options. For example:

const parser = peggy.generate(`
 {
-  // options are available in the per-parse initializer
-  console.log(options.validWords);  // outputs "[ 'boo', 'baz', 'boop' ]"
+// options are available in the per-parse initializer
+console.log(options.validWords);  // outputs "[ 'boo', 'baz', 'boop' ]"
 }
 
 validWord = @word:$[a-z]+ &{ return options.validWords.includes(word) }
 `);
 
 const result = parser.parse("boo", {
-  validWords: [ "boo", "baz", "boop" ]
+validWords: [ "boo", "baz", "boop" ]
 });
 
 console.log(result);  // outputs "boo"
@@ -533,22 +475,22 @@ 

Grammar Syntax and Semantics

values.

start
-  = additive
+= additive
 
 additive
-  = left:multiplicative "+" right:additive { return left + right; }
-  / multiplicative
+= left:multiplicative "+" right:additive { return left + right; }
+/ multiplicative
 
 multiplicative
-  = left:primary "*" right:multiplicative { return left * right; }
-  / primary
+= left:primary "*" right:multiplicative { return left * right; }
+/ primary
 
 primary
-  = integer
-  / "(" additive:additive ")" { return additive; }
+= integer
+/ "(" additive:additive ")" { return additive; }
 
 integer "integer"
-  = digits:[0-9]+ { return parseInt(digits.join(""), 10); }
+= digits:[0-9]+ { return parseInt(digits.join(""), 10); }

On the top level, the grammar consists of rules (in our example, there are five of them). Each rule has a name (e.g. @@ -589,34 +531,34 @@

Grammar Syntax and Semantics

initializer and a per-parse initializer:

{{'{{'}}
-  function makeInteger(o) {
-    return parseInt(o.join(""), 10);
-  }
+function makeInteger(o) {
+return parseInt(o.join(""), 10);
+}
 }}
 
 {
-  if (options.multiplier) {
-    input = "(" + input + ")*(" + options.multiplier + ")";
-  }
+if (options.multiplier) {
+input = "(" + input + ")*(" + options.multiplier + ")";
+}
 }
 
 start
-  = additive
+= additive
 
 additive
-  = left:multiplicative "+" right:additive { return left + right; }
-  / multiplicative
+= left:multiplicative "+" right:additive { return left + right; }
+/ multiplicative
 
 multiplicative
-  = left:primary "*" right:multiplicative { return left * right; }
-  / primary
+= left:primary "*" right:multiplicative { return left * right; }
+/ primary
 
 primary
-  = integer
-  / "(" additive:additive ")" { return additive; }
+= integer
+/ "(" additive:additive ")" { return additive; }
 
 integer "integer"
-  = digits:[0-9]+ { return makeInteger(digits); }
+= digits:[0-9]+ { return makeInteger(digits); }

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 @@ -630,11 +572,11 @@

Grammar Syntax and Semantics

value. For example:

    -
  • An expression matching a literal string produces a JavaScript string - containing matched text.
  • +
  • An expression matching a literal string produces a JavaScript string +containing matched text.
  • -
  • An expression matching repeated occurrence of some subexpression produces - a JavaScript array with all the matches.
  • +
  • An expression matching repeated occurrence of some subexpression produces +a JavaScript array with all the matches.

The match results propagate through the rules when the rule names are used in @@ -663,467 +605,467 @@

Parsing Expressio rest is any remaining input after the match.

-
"literal"
'literal'
- -
-

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.

- -
-
-
Example: literal = "foo"
-
Matches: "foo"
-
Does not match: "Foo", "fOo", "bar", "fo"
-
-
- Try it: - -
-
-
- -
-
-
Example: literal_i = "foo"i
-
Matches: "foo", "Foo", "fOo"
-
Does not match: "bar", "fo"
-
-
- Try it: - -
-
-
-
- -
. (U+002E: FULL STOP, or "period")
- -
-

Match exactly one character and return it as a string.

-
-
-
Example: any = .
-
Matches: "f", ".", " "
-
Does not match: ""
-
-
- Try it: - -
-
-
-
- -
[characters]
- -
-

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 literal makes - the match case-insensitive.

- -
-
-
Example: class = [a-z]
-
Matches: "f"
-
Does not match: "A", "-", ""
-
-
- Try it: - -
-
-
- -
-
-
Example: class_i = [^a-z]i
-
Matches: "=", " "
-
Does not match: "F", "f", ""
-
-
- Try it: - -
-
-
-
- -
rule
- -
-

Match a parsing expression of a rule recursively and return its match - result.

- -
-
-
Example: rule = child; child = "foo"
-
Matches: "foo"
-
Does not match: "Foo", "fOo", "bar", "fo"
-
-
- Try it: - -
-
-
-
- -
( expression )
- -
-

Match a subexpression and return its match result.

- -
-
-
Example: paren = ("1" { return 2; })+
-
Matches: "11"
-
Does not match: "2", ""
-
-
- Try it: - -
-
-
-
- -
expression *
- -
-

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. Unlike in regular expressions, - there is no backtracking.

- -
-
-
Example: star = "a"*
-
Matches: "a", "aaa"
-
Does not match: (always matches)
-
-
- Try it: - -
-
-
-
- -
expression +
- -
-

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. Unlike in regular expressions, - there is no backtracking.

- -
-
-
Example: plus = "a"+
-
Matches: "a", "aaa"
-
Does not match: "b", ""
-
-
- Try it: - -
-
-
-
- -
expression ?
- -
-

Try to match the expression. If the match succeeds, return its match - result, otherwise return null. Unlike in regular expressions, - there is no backtracking.

- -
-
-
Example: maybe = "a"?
-
Matches: "a", ""
-
Does not match: (always matches)
-
-
- Try it: - -
-
-
- -
- -
& expression
- -
-

This is a positive assertion. No input is consumed.

-

Try to match the expression. If the match succeeds, just return - undefined and do not consume any input, otherwise consider the - match failed.

- -
-
-
Example: posAssertion = "a" &"b"
-
Matches: "ab"
-
Does not match: "ac", "a", ""
-
-
- Try it: - -
-
-
-
- -
! expression
- -
-

This is a negative assertion. No input is consumed.

- -

Try to match the expression. If the match does - not succeed, just return undefined and do not consume any - input, otherwise consider the match failed.

- -
-
-
Example: negAssertion = "a" !"b"
-
Matches: "a", "ac"
-
Does not match: "ab", ""
-
-
- Try it: - -
-
-
-
- -
& { predicate }
- -
-

This is a positive assertion. No input is consumed.

- -

The predicate should be JavaScript code, and it's executed as a - function. Curly braces in the predicate must be balanced.

- -

The predicate should return a boolean value. If the result - is truthy, it's match result is undefined, otherwise the - match is considered failed. Failure to include the return - keyword is a common mistake.

- -

The predicate has access to all variables and functions in the - Action Execution Environment.

- -
-
-
Example:
posPredicate = [0-9]+ &{return parseInt(match, 10) < 100}
-
Matches: "0", "99"
-
Does not match: "100", "-1", ""
-
-
- Try it: - -
-
-
-
- -
! { predicate }
- -
-

This is a negative assertion. No input is consumed.

- -

The predicate should be JavaScript code, and it's executed as a - function. Curly braces in the predicate must be balanced.

- -

The predicate should return a boolean value. If the result is - falsy, it's match result is undefined, otherwise the match is - considered failed.

- -

The predicate has access to all variables and functions in the - Action Execution Environment.

- -
-
-
Example:
negPredicate = $[0-9]+ !{ return parseInt(match, 10) < 100 }
-
Matches: "100", "156"
-
Does not match: "56", "-1", ""
-
-
- Try it: - -
-
-
-
- -
$ expression
- -
-

Try to match the expression. If the match succeeds, return the matched - text instead of the match result.

- -

If you need to return the matched text in an action, use the - text() function.

- -
-
-
Example: dollar = $"a"+
-
Matches: "a", "aa"
-
Does not match: "b", ""
-
-
- Try it: - -
-
-
-
- -
label : expression
- -
-

Match the expression and remember its match result under given label. - The label must be a JavaScript identifier, but not in the list of reserved words. - By default this is a list of JavaScript reserved words, - but plugins can change it.

- -

Labeled expressions are useful together with actions, where saved match - results can be accessed by action's JavaScript code.

- -
-
-
Example: label = foo:"bar"i { return {foo}; }
-
Matches: "bar", "BAR"
-
Does not match: "b", ""
-
-
- Try it: - -
-
-
-
- -
@ ( label : )? expression
- -
-

Match the expression and if the label exists, remember its match result - under given label. The label must be a JavaScript identifier if it - exists, but not in the list of reserved words. - By default this is a list of JavaScript reserved words, - but plugins can change it.

- -

Return the value of this expression from the rule, or "pluck" it. You - may not have an action for this rule. The expression must not be a - semantic predicate (&{ predicate } or - !{ predicate }). There may be multiple - pluck expressions in a given rule, in which case an array of the plucked - expressions is returned from the rule.

- -

Pluck expressions are useful for writing terse grammars, or returning - parts of an expression that is wrapped in parentheses.

- -
-
-
Example: pluck_1 = @$"a"+ " "+ @$"b"+
-
Matches: "aaa ", "a "
-
Does not match: "b", " "
-
-
- Try it: - -
-
-
- -
-
-
Example: pluck_2 = @$"a"+ " "+ @two:$"b"+
-
Matches: "aaa b", "a bbb"
-
Does not match: "b", " "
-
-
- Try it: - -
-
-
-
- -
expression1 expression2 ... expressionn
- -
-

Match a sequence of expressions and return their match results in an array.

- -
-
-
Example: sequence = "a" "b" "c"
-
Matches: "abc"
-
Does not match: "b", " "
-
-
- Try it: - -
-
-
-
- -
expression { action }
- -
-

If the expression matches successfully, run the action, otherwise - consider the match failed.

- -

The action should be JavaScript code, and it's executed as a - function. Curly braces in the action must be balanced.

- -

The action should return some value, which will be used as the - match result of the expression.

- -

The action has access to all variables and functions in the - Action Execution Environment.

- -
-
-
Example: action = " "+ "a" { return location(); }
-
Matches: " a"
-
Does not match: "a", " "
-
-
- Try it: - -
-
-
-
- -
expression1 / expression2 / ... / expressionn
- -
-

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.

- -
-
-
Example: alt = "a" / "b" / "c"
-
Matches: "a", "b", "c"
-
Does not match: "d", ""
-
-
- Try it: - -
-
-
-
+
"literal"
'literal'
+ +
+

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.

+ +
+
+
Example: literal = "foo"
+
Matches: "foo"
+
Does not match: "Foo", "fOo", "bar", "fo"
+
+
+Try it: + +
+
+
+ +
+
+
Example: literal_i = "foo"i
+
Matches: "foo", "Foo", "fOo"
+
Does not match: "bar", "fo"
+
+
+Try it: + +
+
+
+
+ +
. (U+002E: FULL STOP, or "period")
+ +
+

Match exactly one character and return it as a string.

+
+
+
Example: any = .
+
Matches: "f", ".", " "
+
Does not match: ""
+
+
+Try it: + +
+
+
+
+ +
[characters]
+ +
+

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 literal makes +the match case-insensitive.

+ +
+
+
Example: class = [a-z]
+
Matches: "f"
+
Does not match: "A", "-", ""
+
+
+Try it: + +
+
+
+ +
+
+
Example: class_i = [^a-z]i
+
Matches: "=", " "
+
Does not match: "F", "f", ""
+
+
+Try it: + +
+
+
+
+ +
rule
+ +
+

Match a parsing expression of a rule recursively and return its match +result.

+ +
+
+
Example: rule = child; child = "foo"
+
Matches: "foo"
+
Does not match: "Foo", "fOo", "bar", "fo"
+
+
+Try it: + +
+
+
+
+ +
( expression )
+ +
+

Match a subexpression and return its match result.

+ +
+
+
Example: paren = ("1" { return 2; })+
+
Matches: "11"
+
Does not match: "2", ""
+
+
+Try it: + +
+
+
+
+ +
expression *
+ +
+

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. Unlike in regular expressions, +there is no backtracking.

+ +
+
+
Example: star = "a"*
+
Matches: "a", "aaa"
+
Does not match: (always matches)
+
+
+Try it: + +
+
+
+
+ +
expression +
+ +
+

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. Unlike in regular expressions, +there is no backtracking.

+ +
+
+
Example: plus = "a"+
+
Matches: "a", "aaa"
+
Does not match: "b", ""
+
+
+Try it: + +
+
+
+
+ +
expression ?
+ +
+

Try to match the expression. If the match succeeds, return its match +result, otherwise return null. Unlike in regular expressions, +there is no backtracking.

+ +
+
+
Example: maybe = "a"?
+
Matches: "a", ""
+
Does not match: (always matches)
+
+
+Try it: + +
+
+
+ +
+ +
& expression
+ +
+

This is a positive assertion. No input is consumed.

+

Try to match the expression. If the match succeeds, just return +undefined and do not consume any input, otherwise consider the +match failed.

+ +
+
+
Example: posAssertion = "a" &"b"
+
Matches: "ab"
+
Does not match: "ac", "a", ""
+
+
+Try it: + +
+
+
+
+ +
! expression
+ +
+

This is a negative assertion. No input is consumed.

+ +

Try to match the expression. If the match does +not succeed, just return undefined and do not consume any +input, otherwise consider the match failed.

+ +
+
+
Example: negAssertion = "a" !"b"
+
Matches: "a", "ac"
+
Does not match: "ab", ""
+
+
+Try it: + +
+
+
+
+ +
& { predicate }
+ +
+

This is a positive assertion. No input is consumed.

+ +

The predicate should be JavaScript code, and it's executed as a +function. Curly braces in the predicate must be balanced.

+ +

The predicate should return a boolean value. If the result +is truthy, it's match result is undefined, otherwise the +match is considered failed. Failure to include the return +keyword is a common mistake.

+ +

The predicate has access to all variables and functions in the +Action Execution Environment.

+ +
+
+
Example:
posPredicate = [0-9]+ &{return parseInt(match, 10) < 100}
+
Matches: "0", "99"
+
Does not match: "100", "-1", ""
+
+
+Try it: + +
+
+
+
+ +
! { predicate }
+ +
+

This is a negative assertion. No input is consumed.

+ +

The predicate should be JavaScript code, and it's executed as a +function. Curly braces in the predicate must be balanced.

+ +

The predicate should return a boolean value. If the result is +falsy, it's match result is undefined, otherwise the match is +considered failed.

+ +

The predicate has access to all variables and functions in the +Action Execution Environment.

+ +
+
+
Example:
negPredicate = $[0-9]+ !{ return parseInt(match, 10) < 100 }
+
Matches: "100", "156"
+
Does not match: "56", "-1", ""
+
+
+Try it: + +
+
+
+
+ +
$ expression
+ +
+

Try to match the expression. If the match succeeds, return the matched +text instead of the match result.

+ +

If you need to return the matched text in an action, use the +text() function.

+ +
+
+
Example: dollar = $"a"+
+
Matches: "a", "aa"
+
Does not match: "b", ""
+
+
+Try it: + +
+
+
+
+ +
label : expression
+ +
+

Match the expression and remember its match result under given label. +The label must be a JavaScript identifier, but not in the list of reserved words. +By default this is a list of JavaScript reserved words, +but plugins can change it.

+ +

Labeled expressions are useful together with actions, where saved match +results can be accessed by action's JavaScript code.

+ +
+
+
Example: label = foo:"bar"i { return {foo}; }
+
Matches: "bar", "BAR"
+
Does not match: "b", ""
+
+
+Try it: + +
+
+
+
+ +
@ ( label : )? expression
+ +
+

Match the expression and if the label exists, remember its match result +under given label. The label must be a JavaScript identifier if it +exists, but not in the list of reserved words. +By default this is a list of JavaScript reserved words, +but plugins can change it.

+ +

Return the value of this expression from the rule, or "pluck" it. You +may not have an action for this rule. The expression must not be a +semantic predicate (&{ predicate } or +!{ predicate }). There may be multiple +pluck expressions in a given rule, in which case an array of the plucked +expressions is returned from the rule.

+ +

Pluck expressions are useful for writing terse grammars, or returning +parts of an expression that is wrapped in parentheses.

+ +
+
+
Example: pluck_1 = @$"a"+ " "+ @$"b"+
+
Matches: "aaa ", "a "
+
Does not match: "b", " "
+
+
+Try it: + +
+
+
+ +
+
+
Example: pluck_2 = @$"a"+ " "+ @two:$"b"+
+
Matches: "aaa b", "a bbb"
+
Does not match: "b", " "
+
+
+Try it: + +
+
+
+
+ +
expression1 expression2 ... expressionn
+ +
+

Match a sequence of expressions and return their match results in an array.

+ +
+
+
Example: sequence = "a" "b" "c"
+
Matches: "abc"
+
Does not match: "b", " "
+
+
+Try it: + +
+
+
+
+ +
expression { action }
+ +
+

If the expression matches successfully, run the action, otherwise +consider the match failed.

+ +

The action should be JavaScript code, and it's executed as a +function. Curly braces in the action must be balanced.

+ +

The action should return some value, which will be used as the +match result of the expression.

+ +

The action has access to all variables and functions in the +Action Execution Environment.

+ +
+
+
Example: action = " "+ "a" { return location(); }
+
Matches: " a"
+
Does not match: "a", " "
+
+
+Try it: + +
+
+
+
+ +
expression1 / expression2 / ... / expressionn
+ +
+

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.

+ +
+
+
Example: alt = "a" / "b" / "c"
+
Matches: "a", "b", "c"
+
Does not match: "d", ""
+
+
+Try it: + +
+
+
+

Action Execution Environment

@@ -1132,47 +1074,47 @@

Action Execution Environment

available to them.

    -
  • All variables and functions defined in the initializer or the top-level - initializer at the beginning of the grammar are available.

    -
  • -
  • Note, that all functions and variables, described below, are unavailable - in the global initializer.

    -
  • -
  • Labels from preceding expressions are available as local variables, - which will have the match result of the labelled expressions.

    -

    A label is only available after its labelled expression is matched:

    -
    rule = A:('a' B:'b' { /* B is available, A is not */ } )
    -

    A label in a sub-expression is only valid within the - sub-expression:

    -
    rule = A:'a' (B:'b') (C:'b' { /* A and C are available, B is not */ })
    -
  • -
  • input is a parsed string that was passed to the parse() method.

    -
  • -
  • options is a variable that contains the parser options. - That is the same object that was passed to the parse() method.

    -
  • -
  • error(message, where) will report an error and throw an exception. - where is optional; the default is the value of location().

    -
  • -
  • expected(message, where) is similar to error, but reports

    -
    -

    Expected message but "other" found.

    -
    -

    where other is, by default, the character in the location().start.offset position.

    -
  • -
  • location() returns an object with the information about the parse position. - Refer to the corresponding section for the details.

    -
  • -
  • range() is similar to location(), but returns an object with offsets only. - Refer to the "Locations" section for the details.

    -
  • -
  • offset() returns only the start offset, i.e. location().start.offset. - Refer to the "Locations" section for the details.

    -
  • -
  • text() returns the source text between start and end (which will be "" for - predicates). Instead of using that function as a return value for the rule consider - using the $ operator.

    -
  • +
  • All variables and functions defined in the initializer or the top-level +initializer at the beginning of the grammar are available.

    +
  • +
  • Note, that all functions and variables, described below, are unavailable +in the global initializer.

    +
  • +
  • Labels from preceding expressions are available as local variables, +which will have the match result of the labelled expressions.

    +

    A label is only available after its labelled expression is matched:

    +
    rule = A:('a' B:'b' { /* B is available, A is not */ } )
    +

    A label in a sub-expression is only valid within the +sub-expression:

    +
    rule = A:'a' (B:'b') (C:'b' { /* A and C are available, B is not */ })
    +
  • +
  • input is a parsed string that was passed to the parse() method.

    +
  • +
  • options is a variable that contains the parser options. +That is the same object that was passed to the parse() method.

    +
  • +
  • error(message, where) will report an error and throw an exception. +where is optional; the default is the value of location().

    +
  • +
  • expected(message, where) is similar to error, but reports

    +
    +

    Expected message but "other" found.

    +
    +

    where other is, by default, the character in the location().start.offset position.

    +
  • +
  • location() returns an object with the information about the parse position. +Refer to the corresponding section for the details.

    +
  • +
  • range() is similar to location(), but returns an object with offsets only. +Refer to the "Locations" section for the details.

    +
  • +
  • offset() returns only the start offset, i.e. location().start.offset. +Refer to the "Locations" section for the details.

    +
  • +
  • text() returns the source text between start and end (which will be "" for +predicates). Instead of using that function as a return value for the rule consider +using the $ operator.

    +

Parsing Lists

@@ -1191,7 +1133,7 @@

Error Messages

As described above, you can annotate your grammar rules with human-readable names that will be used in error messages. For example, this production:

integer "integer"
-  = digits:[0-9]+
+= digits:[0-9]+

will produce an error message like:

Expected integer but "a" found.
@@ -1205,7 +1147,7 @@

Error Messages

For example, for this rule matching a comma-separated list of integers:

seq
-  = integer ("," integer)*
+= integer ("," integer)*

an input like 1,2,a produces this error message:

Expected integer but "a" found.
@@ -1213,7 +1155,7 @@

Error Messages

But if we add a human-readable name to the seq production:

seq "list of numbers"
-  = integer ("," integer)*
+= integer ("," integer)*

then Peggy prefers an error message that implies a smaller attempted parse tree:

Expected end of input but "," found.
@@ -1221,50 +1163,50 @@

Error Messages

There are two classes of errors in Peggy:

    -
  • SyntaxError: Syntax errors, found during parsing the input. This kind of errors can be thrown both during grammar parsing and during input parsing. Although name is the same, errors of each generated parser (including Peggy parser itself) has its own unique class.
  • -
  • GrammarError: Grammar errors, found during construction of the parser. These errors can be thrown only in the parser generation phase. This error signals a logical mistake in the grammar, such as having two rules with the same name in one grammar, etc.
  • +
  • SyntaxError: Syntax errors, found during parsing the input. This kind of errors can be thrown both during grammar parsing and during input parsing. Although name is the same, errors of each generated parser (including Peggy parser itself) has its own unique class.
  • +
  • GrammarError: Grammar errors, found during construction of the parser. These errors can be thrown only in the parser generation phase. This error signals a logical mistake in the grammar, such as having two rules with the same name in one grammar, etc.

Both of these errors have the format() method that takes an array of mappings from source to grammar text:

let source = ...;
 try {
-  peggy.generate(text, { grammarSource: source, ... }); // throws SyntaxError or GrammarError
-  parser.parse(input, { grammarSource: source2, ... }); // throws SyntaxError
+peggy.generate(text, { grammarSource: source, ... }); // throws SyntaxError or GrammarError
+parser.parse(input, { grammarSource: source2, ... }); // throws SyntaxError
 } catch (e) {
-  if (typeof e.format === "function") {
-    console.log(e.format([
-      { source, text },
-      { source: source2, text: input },
-      ...
-    ]));
-  } else {
-    throw e;
-  }
+if (typeof e.format === "function") {
+console.log(e.format([
+{ source, text },
+{ source: source2, text: input },
+...
+]));
+} else {
+throw e;
+}
 }

Messages generated by format() look like this

Error: Possible infinite loop when parsing (left recursion: start -> proxy -> end -> start)
- --> .\recursion.pegjs:1:1
-  |
+--> .\recursion.pegjs:1:1
+|
 1 | start = proxy;
-  | ^^^^^
+| ^^^^^
 note: Step 1: call of the rule "proxy" without input consumption
- --> .\recursion.pegjs:1:9
-  |
+--> .\recursion.pegjs:1:9
+|
 1 | start = proxy;
-  |         ^^^^^
+|         ^^^^^
 note: Step 2: call of the rule "end" without input consumption
- --> .\recursion.pegjs:2:11
-  |
+--> .\recursion.pegjs:2:11
+|
 2 | proxy = a:end { return a; };
-  |           ^^^
+|           ^^^
 note: Step 3: call itself without input consumption - left recursion
- --> .\recursion.pegjs:3:8
-  |
+--> .\recursion.pegjs:3:8
+|
 3 | end = !start
-  |        ^^^^^
+| ^^^^^

A plugin may register additional passes that can generate GrammarErrors to report about problems, but they shouldn't do that by throwing an instance of GrammarError. They should @@ -1277,9 +1219,9 @@

Locations

information by calling location() function, which returns you the following object:

{
-  source: options.grammarSource,
-  start: { offset: 23, line: 5, column: 6 },
-  end: { offset: 25, line: 5, column: 8 }
+source: options.grammarSource,
+start: { offset: 23, line: 5, column: 6 },
+end: { offset: 25, line: 5, column: 8 }
 }
 
@@ -1303,9 +1245,9 @@

Locations

For the per-parse initializer, the location is the start of the input, i.e.

{
-  source: options.grammarSource,
-  start: { offset: 0, line: 1, column: 1 },
-  end: { offset: 0, line: 1, column: 1 }
+source: options.grammarSource,
+start: { offset: 0, line: 1, column: 1 },
+end: { offset: 0, line: 1, column: 1 }
 }
 
@@ -1313,7 +1255,7 @@

Locations

line and column are 1-based indices.

The line number is incremented each time the parser finds an end of line sequence in - the input.

+the input.

Line and column are somewhat expensive to compute, so if you just need the offset, there's also a function offset() that returns just the start offset, @@ -1321,9 +1263,9 @@

Locations


 {
-  source: options.grammarSource,
-  start: 23,
-  end: 25
+source: options.grammarSource,
+start: 23,
+end: 25
 }
 
@@ -1353,45 +1295,45 @@

config

Object with the following properties:

-
parser
-
Parser object, by default the peggy.parser instance. That object - will be used to parse the grammar. Plugin can replace this object
- -
passes
-
-

Mapping { [stage: string]: Pass[] } that represents compilation - stages that would applied to the AST, returned by the parser object. That - mapping will contain at least the following keys:

- -
    -
  • check — passes that check AST for correctness. They shouldn't change the AST
  • -
  • transform — passes that performs various optimizations. They can change - the AST, add or remove nodes or their properties
  • -
  • generate — passes used for actual code generating
  • -
- -

A plugin that implement a pass usually should push it to the end of the correct - array. Pass is a simple function with signature pass(ast, options, session):

- -
    -
  • ast — the AST created by the config.parser.parse() method
  • -
  • options — compilation options passed to the peggy.compiler.compile() method. - If parser generation is started because generate() function was called that - is also an options, passed to the generate() method
  • -
  • session — a Session object that allows raising errors, - warnings and informational messages
  • -
-
- -
reservedWords
-
-

String array with a list of words that shouldn't be used as - label names. This list can be modified by plugins. That property is not required - to be sorted or not contain duplicates, but it is recommend to remove duplicates.

- -

Default list contains JavaScript reserved words, and can be found - in the peggy.RESERVED_WORDS property.

-
+
parser
+
Parser object, by default the peggy.parser instance. That object +will be used to parse the grammar. Plugin can replace this object
+ +
passes
+
+

Mapping { [stage: string]: Pass[] } that represents compilation +stages that would applied to the AST, returned by the parser object. That +mapping will contain at least the following keys:

+ +
    +
  • check — passes that check AST for correctness. They shouldn't change the AST
  • +
  • transform — passes that performs various optimizations. They can change +the AST, add or remove nodes or their properties
  • +
  • generate — passes used for actual code generating
  • +
+ +

A plugin that implement a pass usually should push it to the end of the correct +array. Pass is a simple function with signature pass(ast, options, session):

+ +
    +
  • ast — the AST created by the config.parser.parse() method
  • +
  • options — compilation options passed to the peggy.compiler.compile() method. +If parser generation is started because generate() function was called that +is also an options, passed to the generate() method
  • +
  • session — a Session object that allows raising errors, +warnings and informational messages
  • +
+
+ +
reservedWords
+
+

String array with a list of words that shouldn't be used as +label names. This list can be modified by plugins. That property is not required +to be sorted or not contain duplicates, but it is recommend to remove duplicates.

+ +

Default list contains JavaScript reserved words, and can be found +in the peggy.RESERVED_WORDS property.

+

options

@@ -1415,41 +1357,41 @@

Session API

    -
  • message: a main diagnostic message
  • -
  • location: an optional location information if diagnostic is related to the grammar - source code
  • -
  • notes: an array with additional details about diagnostic, pointing to the - different places in the grammar. For example, each note could be a location of - a duplicated rule definition
  • +
  • message: a main diagnostic message
  • +
  • location: an optional location information if diagnostic is related to the grammar +source code
  • +
  • notes: an array with additional details about diagnostic, pointing to the +different places in the grammar. For example, each note could be a location of +a duplicated rule definition
-
error(...)
-
-

Reports an error. Compilation process is subdivided into pieces called stages and - each stage consist of one or more passes. Within the one stage all errors, reported - by different passes, are collected without interrupting the parsing process.

- -

When all passes in the stage are completed, the stage is checked for errors. If one - was registered, a GrammarError with all found problems in the problems property - is thrown. If there are no errors, then the next stage is processed.

- -

After processing all three stages (check, transform and generate) the compilation - process is finished.

- -

The process, described above, means that passes should be careful about what they do. - For example, if you place your pass into the check stage there is no guarantee that - all rules exists, because checking for existing rules is also performed during the - check stage. On the contrary, passes in the transform and generate stages can be - sure that all rules exists, because that precondition was checked on the check stage.

-
- -
warning(...)
-
Reports a warning. Warnings are similar to errors, but they do not interrupt a compilation.
- -
info(...)
-
Report an informational message. This method can be used to inform user about - significant changes in the grammar, for example, replacing proxy rules.
+
error(...)
+
+

Reports an error. Compilation process is subdivided into pieces called stages and +each stage consist of one or more passes. Within the one stage all errors, reported +by different passes, are collected without interrupting the parsing process.

+ +

When all passes in the stage are completed, the stage is checked for errors. If one +was registered, a GrammarError with all found problems in the problems property +is thrown. If there are no errors, then the next stage is processed.

+ +

After processing all three stages (check, transform and generate) the compilation +process is finished.

+ +

The process, described above, means that passes should be careful about what they do. +For example, if you place your pass into the check stage there is no guarantee that +all rules exists, because checking for existing rules is also performed during the +check stage. On the contrary, passes in the transform and generate stages can be +sure that all rules exists, because that precondition was checked on the check stage.

+
+ +
warning(...)
+
Reports a warning. Warnings are similar to errors, but they do not interrupt a compilation.
+ +
info(...)
+
Report an informational message. This method can be used to inform user about +significant changes in the grammar, for example, replacing proxy rules.

Compatibility

@@ -1458,25 +1400,16 @@

Compatibility

following environments:

    -
  • Node.js 12+
  • -
  • Internet Explorer 9+
  • -
  • Edge
  • -
  • Firefox
  • -
  • Chrome
  • -
  • Safari
  • -
  • Opera
  • +
  • Node.js 12+
  • +
  • Internet Explorer 9+
  • +
  • Edge
  • +
  • Firefox
  • +
  • Chrome
  • +
  • Safari
  • +
  • Opera
-
- - -
- - diff --git a/docs/index.html b/docs/index.html index 061f942b..cf97a51f 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,106 +1,65 @@ --- -permalink: '/index.html' +permalink: "/index.html" +layout: base-layout --- - - + - - - - - - Peggy – Parser Generator for JavaScript - - - - - +
+

+ Peggy 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. +

- +

Features

- -
- - - - -
- - - -
-

- Peggy 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. -

- -

Features

- -
    -
  • Simple and expressive grammar syntax
  • -
  • Integrates both lexical and syntactical analysis
  • -
  • Parsers have excellent error reporting out of the box
  • -
  • - Based on parsing - expression grammar formalism — more powerful than traditional LL(k) - and LR(k) parsers -
  • -
  • - Usable from your browser, from the command - line, or via JavaScript API -
  • -
  • - Source map - support. -
  • -
-
-
- - -
- - - + +
From 9bb624fd1b30a98a32ec500f90432d46ccae9a2c Mon Sep 17 00:00:00 2001 From: Cameron McHenry Date: Thu, 7 Jul 2022 14:10:45 -0400 Subject: [PATCH 02/12] Load scripts after body --- docs/_includes/base-layout.html | 10 +++++----- docs/development/benchmark.html | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/_includes/base-layout.html b/docs/_includes/base-layout.html index 01181498..71b12d93 100644 --- a/docs/_includes/base-layout.html +++ b/docs/_includes/base-layout.html @@ -21,11 +21,6 @@ } - {% if scripts %} - {% for script in scripts %} - - {% endfor %} - {% endif %} {% if stylesheets %} {% for stylesheet in stylesheets %} @@ -57,5 +52,10 @@

Parser Generator for JavaScript

Source code + {% if scripts %} + {% for script in scripts %} + + {% endfor %} + {% endif %} diff --git a/docs/development/benchmark.html b/docs/development/benchmark.html index ee6a5836..0602edb5 100644 --- a/docs/development/benchmark.html +++ b/docs/development/benchmark.html @@ -1,12 +1,12 @@ --- permalink: "/development/benchmark.html" layout: base-layout -stylesheets: ["../css/benchmark.css"] +stylesheets: ["/css/benchmark.css"] scripts: [ "https://unpkg.com/jquery@1.12.4/dist/jquery.min.js", "https://unpkg.com/jquery.scrollto@2.1.2/jquery.scrollTo.min.js", - "../js/benchmark-bundle.min.js", + "/js/benchmark-bundle.min.js", ] --- From 6281dec5cd744c30acf19ef6e79e30189ea03764 Mon Sep 17 00:00:00 2001 From: Cameron McHenry Date: Thu, 7 Jul 2022 15:40:07 -0400 Subject: [PATCH 03/12] Add base layout to test file --- docs/development/test.html | 92 +++++++++++--------------------------- 1 file changed, 27 insertions(+), 65 deletions(-) diff --git a/docs/development/test.html b/docs/development/test.html index 5a9440ad..d6de0861 100644 --- a/docs/development/test.html +++ b/docs/development/test.html @@ -1,80 +1,42 @@ --- -permalink: '/development/test.html' +permalink: "/development/test.html" +layout: base-layout --- - - - - - - - - - Test » Peggy – Parser Generator for JavaScript - - - - - - - - - - - + + + + + - + - - - -
- - - - -
-
-
+ +
- -
- - From 0efd83f01459fc8c2fc57dc3ad215d0d545dd4b2 Mon Sep 17 00:00:00 2001 From: Cameron McHenry Date: Thu, 7 Jul 2022 15:42:46 -0400 Subject: [PATCH 04/12] Fix documentation examples JS not working --- docs/documentation.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/documentation.html b/docs/documentation.html index 6e069091..1103f6e6 100644 --- a/docs/documentation.html +++ b/docs/documentation.html @@ -1,10 +1,11 @@ --- permalink: '/documentation.html' layout: base-layout -scripts: ["js/examples.js?2022-06-03T00:53:11Z"] stylesheets: ["css/documentation.css"] --- + +

Documentation

Table of Contents

From 5befd44c71c9554ff8206060151051ea51d92b8f Mon Sep 17 00:00:00 2001 From: Cameron McHenry Date: Thu, 7 Jul 2022 15:48:34 -0400 Subject: [PATCH 05/12] Load scripts in head, keep some scripts inline for compatibility --- docs/_includes/base-layout.html | 10 +++++----- docs/development/benchmark.html | 3 ++- docs/development/test.html | 16 +++++++--------- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/docs/_includes/base-layout.html b/docs/_includes/base-layout.html index 71b12d93..16ba1e22 100644 --- a/docs/_includes/base-layout.html +++ b/docs/_includes/base-layout.html @@ -26,6 +26,11 @@ {% endfor %} {% endif %} + {% if scripts %} + {% for script in scripts %} + + {% endfor %} + {% endif %}
@@ -52,10 +57,5 @@

Parser Generator for JavaScript

Source code
- {% if scripts %} - {% for script in scripts %} - - {% endfor %} - {% endif %} diff --git a/docs/development/benchmark.html b/docs/development/benchmark.html index 0602edb5..06a18ffb 100644 --- a/docs/development/benchmark.html +++ b/docs/development/benchmark.html @@ -6,10 +6,11 @@ [ "https://unpkg.com/jquery@1.12.4/dist/jquery.min.js", "https://unpkg.com/jquery.scrollto@2.1.2/jquery.scrollTo.min.js", - "/js/benchmark-bundle.min.js", ] --- + +
times diff --git a/docs/development/test.html b/docs/development/test.html index d6de0861..08f0015e 100644 --- a/docs/development/test.html +++ b/docs/development/test.html @@ -1,17 +1,15 @@ --- permalink: "/development/test.html" layout: base-layout +stylesheets: ["https://cdnjs.cloudflare.com/ajax/libs/mocha/8.3.2/mocha.css"] +scripts: + [ + "https://cdnjs.cloudflare.com/ajax/libs/mocha/8.3.2/mocha.min.js", + "https://cdnjs.cloudflare.com/ajax/libs/chai/4.3.4/chai.min.js", + "https://jsdom.github.io/whatwg-url/whatwg-url.js", + ] --- - - - - - - From ffeab47fd5be9a5cff773dd459f680fcc30f34db Mon Sep 17 00:00:00 2001 From: Cameron McHenry Date: Thu, 7 Jul 2022 16:37:19 -0400 Subject: [PATCH 06/12] Add dynamic title --- docs/_includes/base-layout.html | 2 +- docs/development/benchmark.html | 1 + docs/development/index.html | 1 + docs/development/test.html | 1 + docs/documentation.html | 1 + 5 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/_includes/base-layout.html b/docs/_includes/base-layout.html index 16ba1e22..3d3c7294 100644 --- a/docs/_includes/base-layout.html +++ b/docs/_includes/base-layout.html @@ -8,7 +8,7 @@ name="description" content="Peggy is a parser generator for JavaScript based on the parsing expression grammar formalism." /> - Peggy – Parser Generator for JavaScript + {% if title %}{{ title }} » {% endif %}Peggy – Parser Generator for JavaScript diff --git a/docs/development/benchmark.html b/docs/development/benchmark.html index 06a18ffb..ba464842 100644 --- a/docs/development/benchmark.html +++ b/docs/development/benchmark.html @@ -1,4 +1,5 @@ --- +title: 'Benchmark' permalink: "/development/benchmark.html" layout: base-layout stylesheets: ["/css/benchmark.css"] diff --git a/docs/development/index.html b/docs/development/index.html index 51f191de..2489a882 100644 --- a/docs/development/index.html +++ b/docs/development/index.html @@ -1,4 +1,5 @@ --- +title: 'Development' permalink: '/development/index.html' layout: base-layout --- diff --git a/docs/development/test.html b/docs/development/test.html index 08f0015e..58915dde 100644 --- a/docs/development/test.html +++ b/docs/development/test.html @@ -1,4 +1,5 @@ --- +title: 'Test' permalink: "/development/test.html" layout: base-layout stylesheets: ["https://cdnjs.cloudflare.com/ajax/libs/mocha/8.3.2/mocha.css"] diff --git a/docs/documentation.html b/docs/documentation.html index 1103f6e6..1a256ee8 100644 --- a/docs/documentation.html +++ b/docs/documentation.html @@ -1,4 +1,5 @@ --- +title: 'Documentation' permalink: '/documentation.html' layout: base-layout stylesheets: ["css/documentation.css"] From 950a54faa7c9994251efeb327f4b497f37ff08cb Mon Sep 17 00:00:00 2001 From: Cameron McHenry Date: Fri, 8 Jul 2022 10:46:14 -0400 Subject: [PATCH 07/12] Add a main layout and extract base layout --- docs/_includes/base-layout.html | 25 +------------------------ docs/_includes/components/footer.html | 8 ++++++++ docs/_includes/components/header.html | 11 +++++++++++ docs/_includes/main-layout.html | 10 ++++++++++ docs/development/benchmark.html | 2 +- docs/development/index.html | 2 +- docs/development/test.html | 2 +- docs/documentation.html | 2 +- docs/index.html | 2 +- docs/online.html | 1 + 10 files changed, 36 insertions(+), 29 deletions(-) create mode 100644 docs/_includes/components/footer.html create mode 100644 docs/_includes/components/header.html create mode 100644 docs/_includes/main-layout.html diff --git a/docs/_includes/base-layout.html b/docs/_includes/base-layout.html index 3d3c7294..b3ff0dc6 100644 --- a/docs/_includes/base-layout.html +++ b/docs/_includes/base-layout.html @@ -33,29 +33,6 @@ {% endif %} -
- - - - -
{{content}}
- - -
+ {{content}} diff --git a/docs/_includes/components/footer.html b/docs/_includes/components/footer.html new file mode 100644 index 00000000..af79c390 --- /dev/null +++ b/docs/_includes/components/footer.html @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/docs/_includes/components/header.html b/docs/_includes/components/header.html new file mode 100644 index 00000000..d9117d3b --- /dev/null +++ b/docs/_includes/components/header.html @@ -0,0 +1,11 @@ + + + \ No newline at end of file diff --git a/docs/_includes/main-layout.html b/docs/_includes/main-layout.html new file mode 100644 index 00000000..a1a080e0 --- /dev/null +++ b/docs/_includes/main-layout.html @@ -0,0 +1,10 @@ +--- +layout: base-layout +--- +
+ {% include 'components/header.html' %} + +
{{content}}
+ + {% include 'components/footer.html' %} +
diff --git a/docs/development/benchmark.html b/docs/development/benchmark.html index ba464842..4069d82d 100644 --- a/docs/development/benchmark.html +++ b/docs/development/benchmark.html @@ -1,7 +1,7 @@ --- title: 'Benchmark' permalink: "/development/benchmark.html" -layout: base-layout +layout: main-layout stylesheets: ["/css/benchmark.css"] scripts: [ diff --git a/docs/development/index.html b/docs/development/index.html index 2489a882..486932f6 100644 --- a/docs/development/index.html +++ b/docs/development/index.html @@ -1,7 +1,7 @@ --- title: 'Development' permalink: '/development/index.html' -layout: base-layout +layout: main-layout ---

Development

diff --git a/docs/development/test.html b/docs/development/test.html index 58915dde..7d92bcb9 100644 --- a/docs/development/test.html +++ b/docs/development/test.html @@ -1,7 +1,7 @@ --- title: 'Test' permalink: "/development/test.html" -layout: base-layout +layout: main-layout stylesheets: ["https://cdnjs.cloudflare.com/ajax/libs/mocha/8.3.2/mocha.css"] scripts: [ diff --git a/docs/documentation.html b/docs/documentation.html index 0d5cb603..cef6b0a9 100644 --- a/docs/documentation.html +++ b/docs/documentation.html @@ -1,7 +1,7 @@ --- title: 'Documentation' permalink: '/documentation.html' -layout: base-layout +layout: main-layout stylesheets: ["css/documentation.css"] --- diff --git a/docs/index.html b/docs/index.html index cf97a51f..9c7ee4fc 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,6 +1,6 @@ --- permalink: "/index.html" -layout: base-layout +layout: main-layout ---