120 Commits (2a7dcdcfbe774dc346c355094d37df3a263147d5)

Author SHA1 Message Date
felix cb3c5f4473 Improve error message for unbalanced brace. (#534)
Currently, an open brace without a corresponding brace will emit this confusing error message:

> Expected "!", "$", "&", "(", "*", "+", ".", "/", "/*", "//", ";", "?", character class, code block, comment, end of line, identifier, literal, or whitespace but "{" found.

This change adds an error case to the grammar to make it clear what the problem is.
7 years ago
Futago-za Ryuu 57bb28414e Merge pull request #509 from Mingun/simplify-bc
Simplify bytecode: remove unnecessary opcode.
7 years ago
Mingun c98fee1629 Add location information to group AST node 7 years ago
Mingun 575db38d1f Simplify bytecode: remove unnecessary opcode.
Now generated sources looks little better :)
7 years ago
David Majda 266f17d11c Adapt to using HTTPS on PEG.js website
PEG.js website is now served exclusively using HTTPS. Change protocol in
all links to it to avoid redirects.
8 years ago
David Majda f4df9ddde1 Code style: Fix some ESLint errors in generated code
Running ESLint on generated code with the configuration used on PEG.js
itself produces a lot of errors. This commit fixes some unnecessary ones
caught by these rules:

  - max-len
  - new-cap
  - newline-before-return
  - no-unused-vars

See also 5dd8e797f7.

Follow-up to #407.
8 years ago
David Majda 5dd8e797f7 Code style: Do not lint lib/parser.js
The idea behind linting lib/parser.js was that it would improve quality
of code generated by PEG.js in general. However, there is a couple of
problems with it:

  1. Code in lib/parser.js is ES5 while the rest of the code is ES2015.
     This would mean a separate ESLint configuration and a separate set
     of code style rules just for lib/parser.js once code style checks
     are added.

  2. Code in lib/parser.js is generated. This means that even today it
     violates checks like "no-unused-var", which have to be disabled.
     This would get worse once code style checks are added, again
     requiring a separate ESLint configuration just for lib/parser.js.

  3. Linting lib/parser.js checks only small portion of possible code
     generator output. For example, code generated when optimizing for
     size or when tracing is not checked at all. Thus, linting
     lib/parser.js gives a false sense of security.

Because of these problems I decided not to lint lib/parser.js at all and
rely on ad-hoc linting of parser files produced by PEG.js with ignoring
false-positives. I consider this more of a pragmatic cost vs. benefits
decision than a principial one.

Part of #407.
8 years ago
David Majda 7495e6e03f Add missing semicolons 8 years ago
David Majda b81afb1471 Do not quote the "class" key
Quoting reserved words in property names is not needed since dropping
support of IE < 9.
8 years ago
David Majda 7ca229a432 Improve indentation of variable declarations
Before this commit, continuation lines of multi-line values in variable
declaration initializers were aligned with the variable name:

  let foo = {
        a: 5,
        b: 6
      };

This was highly irregular, maintenance intensive, and made declarations
look different from assignments.

This commit changes the indentation to be more regular and similar to
assignments:

  let foo = {
    a: 5,
    b: 6
  };
8 years ago
David Majda e29d62558d Do not prepend the "eslint-env" directive to lib/parser.js
The lib/parser.js file is a CommonJS module like all the other files in
lib/, so setting the environment explicitly is not needed. Besides, the
environment set by "eslint-env" was wrong (since transitioning from the
AMD format).
8 years ago
David Majda 9648ca53d7 Use the "eslint-disable" directive instead of "eslint"
The "eslint-disable" directive is more specific.
8 years ago
David Majda ff7193776e Avoid aligning "="
The only exception left are instances where aligning "=" helps to
express symmetry between lines.

See #443.
8 years ago
David Majda 400a3cfa3c Avoid aligning object keys
The only exception left are objects representing a mapping with simple
keys and values -- essentially tables written as object literals.

See #443.
8 years ago
David Majda 12112310f2 Use only double quotes for strings
See #443
8 years ago
David Majda 6294bb5b13 Use only "//" comments
See #443.
8 years ago
David Majda 516023546d Use one var/let/const per variable (for initialized variables)
Use one var/let/const per variable, but only for initialized variables.
Uninitialized variables are still grouped into one var/let/const
declaration as I don't see any value in separating them. This approach
reflects the fact that initialized and uninitialized var/let/const
declarations are really two different things.

See #443.
8 years ago
David Majda 6fa8ad63f9 Replace some functions with arrow functions
Because arrow functions work rather differently than normal functions (a
bad design mistake if you ask me), I decided to be conservative with the
conversion.

I converted:

  * event handlers
  * callbacks
  * arguments to Array.prototype.map & co.
  * small standalone lambda functions

I didn't convert:

  * functions assigned to object literal properties (the new shorthand
    syntax would be better here)
  * functions passed to "describe", "it", etc. in specs (because Jasmine
    relies on dynamic "this")

See #442.
8 years ago
David Majda bdf91b5941 Replace "var" with "let" & "const"
This is purely a mechanical change, not taking advantage of block scope
of "let" and "const". Minimizing variable scope will come in the next
commit.

In general, "var" is converted into "let" and "const" is used only for
immutable variables of permanent character (generally spelled in
ALL_CAPS). Using it for any immutable variable regardless on its
permanence would feel confusing.

Any code which is not transpiled and needs to run in ES6 environment
(examples, code in grammars embedded in specs, ...) is kept unchanged.
This is also true for code generated by PEG.js.

See #442.
8 years ago
David Majda 9c04c94c85 Escape vertical tab as "\v", not "\x0B"
See #441.
8 years ago
David Majda f36a667376 Remove "undefined" redefinition protection
See #441.
8 years ago
David Majda fad4ab74d1 Replace suitable for loops with Array methods (in /lib)
See #441.
8 years ago
David Majda 3e8bcbea73 Replace suitable for loops with Array methods (in /src)
See #441.
8 years ago
David Majda 1c3fbf6cb0 Replace "... instanceof Array" with "Array.isArray(...)"
See #441.
8 years ago
David Majda 671166bbe8 Update version to 0.10.0 8 years ago
David Majda b77d33ca05 generate-js.js: Quote the "class" key in DESCRIBE_EXPECTATION_FNS
"class" is a reserved word. Having it as a key unquoted broke IE 8 (both
in standards and quirks mode) and IE 9 (in quirks mode).
8 years ago
David Majda e9cb23608d Split peg$buildException into two separate functions
This change reflects the fact that PEG.js-generated parsers really
produce two kinds of syntax errors:

  Structured errors

    Caused by match failures, trailing input, or calls of the "expected"
    function in parser code. Their messages have fixed format ("Expected
    ... but ... found.").

  Simple errors

    Caused by calls of the "error" function in parser code. Their
    messages don't have any fixed format.

Each kind of error now has a separate helper function which builds its
instances.
8 years ago
David Majda e03d92488a Set the "found" property of syntax errors produced by "error" to null
The property doesn't correspond to anything in the error's message.
8 years ago
David Majda 6ca546a44e Regenerate lib/parser.js 8 years ago
David Majda e546af5543 Regenerate lib/parser.js 8 years ago
David Majda 5a4d04fa90 Construct expectations using functions
Until now, expectations were constructed using object literals. This
commit changes the construction to use factory functions.

This change makes generated parsers slightly smaller because property
names don't have to be repeated many times and factory function calls
are more amenable to minifying.

Some numbers based on the aggregate size of parsers generated from
examples/*.pegjs:

  Optimization   Minified?   Size before   Size after   Saving
  ------------------------------------------------------------
  speed          no               719066       716063    0.42%
  speed          yes              188998       180202    4.65%
  size           no               194810       197813    1.52%
  size           yes              108782        99947    8.12%

(Minification was done using "uglify --mangle --compress" with
uglify-js 2.4.24.)
9 years ago
David Majda e7d03825e0 AST: Remove the "rawText" property from "class" nodes
It isn't used anymore.
9 years ago
David Majda 35c8280743 Expectation refactoring 7/7: Regenerate lib/parser.js 9 years ago
David Majda d48983dd6a Don't use the "i" suffix for case-insensitive class descriptions
If the described class is case-sensitive, nothing changes.

If the described class is case-insensitive, its description doesn't
indicate that anymore. The indication was awkward and it was meaningful
only for parser users familiar with PEG.js grammar syntax (typically a
minority). For cases where case insensitivity indication is vital, named
rules can be used to customize the reporting.

Note that literal descriptions already ignore the case-sensitivity flag;
this commit only makes things consistent.
9 years ago
David Majda d73a5208a0 Simplify various escaping functions
Simplify regexps that specify ranges of characters to escape with "\xXX"
and "\uXXXX" in various escaping functions. Until now, these regexps
were (mostly) mutually exclusive with more selective regexps applied
before them, but this became a maintenance headache. I decided to
abandon the exclusivity, which allowed to simplify these regexps (at the
cost of introducing an ordering dependency).
9 years ago
David Majda 75cedcb7d8 Harmonize found string escaping with expectation escaping
Change how found strings are escaped when building syntax error
messages:

  * Do not escape non-ASCII characters (U+0100-U+FFFF). They are
    typically more readable in their raw form.

  * Escape DEL (U+007F). It is a control character.

  * Escape NUL (U+0000) as "\0", not "\x00".

  * Do not use less known shortcut escape sequences ("\b", "\f"), only the
    well-known ones ("\0", "\t", "\n", "\r").

These changes mirror expectation escaping changes done in
4fe682794d.

Part of work on #428.
9 years ago
David Majda 6b60896216 Revert "Remove info about found string from syntax errors"
This reverts commit 25ab98027d.

Part of work on #428.
9 years ago
David Majda 4fe682794d Improve expression descriptions in error messages
Before this commit, descriptions of literals used in error messages were
built by applying JavaScript string escaping to their values, making the
descriptions look like JavaScript strings. Descriptions of character
classes were built using their raw text. These approaches were mutually
inconsistent and lead to descriptions which were over-escaped and not
necessarily human-friendly (in case of literals) or coupled with details
of the grammar (in case of character classes).

This commit changes description building code in both cases and unifies
it. The intent is to generate human-friendly descriptions of matched
expressions which are clean, unambiguous, and which don't escape too
many characters, while handling special characters such as newlines
well.

Fixes #127.
9 years ago
David Majda 2fd77b96fc Revert "Use literal raw text in error messages"
I no longer think that using raw literal texts in error messages is the
right thing to do. The main reason is that it couples error messages
with details of the grammar such as use of single or double quotes in
literals. A better solution is coming in the next commit.

This reverts commit 69a0f769fc.
9 years ago
David Majda 057a93fbc7 Move the "Generated by ..." comment out of wrapping functions
The wrapping functions are also generated by PEG.js, so the comment
should be above them to mark them as such. This shouldn't cause any
problems technically.
9 years ago
David Majda fe6ce38d08 UMD parsers: Regenerate lib/parser.js
Part of work on #362.
9 years ago
David Majda ce44c62f14 Support passing custom location info to "error" and "expected"
Based on a pull request by Konstantin (@YemSalat):

  https://github.com/pegjs/pegjs/pull/391

Resolves #390.
9 years ago
David Majda da2378d887 Rewrite handling of optional parameters
Instead of testing arguments.length to see whether an optional parameter
was passed to a function, compare its value to "undefined". This
approach has two advantages:

  * It is in line with handling of default parameters in ES6.

  * Optional parameters are actually spelled out in the parameter
    list.

There is also one important disadvantage, namely that it's impossible to
pass "undefined" as an optional parameter value. This required a small
change in two tests.

Additional notes:

  * Default parameter values are set in assignments immediately
    after the function header. This reflects the fact that these
    assignments really belong to the parameter list (which is where they
    are in ES6).

  * Parameter values are checked against "void 0" in places where
    "undefined" can potentially be redefiend.
9 years ago
David Majda 0c39f1cf86 Fix labels leaking to outer scope
Labels in expressions like "(a:"a")" or "(a:"a" b:"b" c:"c")" were
visible to the outside despite being wrapped in parens. This commit
makes them invisible, as they should be.

Note this required introduction of a new "group" AST node, whose purpose
is purely to provide label scope isolation. This was necessary because
"label" and "sequence" nodes don't (and can't!) provide this isolation
themselves.

Part of a fix of #396.
9 years ago
David Majda 88f1d1369b Detect newlines using charCodeAt instead of charCode
In generated parsers, detect newlines using charCodeAt instead of
charCode. This should be slightly faster.
9 years ago
David Majda 18d266be67 Remove support for newlines other than "\n" and "\r\n"
Before this commit, generated parsers considered the following character
sequences as newlines:

  Sequence   Description
  ------------------------------
  "\n"       Unix
  "\r"       Old Mac
  "\r\n"     Windows
  "\u2028"   line separator
  "\u2029"   paragraph separator

This commit limits the sequences only to "\n" and "\r\n". The reason is
that nobody uses Unicode newlines or "\r" in practice.

A positive side effect of the change is that newline-handling code
became simpler (and likely faster).
9 years ago
David Majda ddd4ac3787 Fix ESLint errors in lib/parser.js
Fix the following errors:

    31:9   error  "parser" is defined but never used    no-unused-vars
   406:14  error  "expected" is defined but never used  no-unused-vars
  1304:15  error  "s1" is defined but never used        no-unused-vars
  1386:15  error  "s1" is defined but never used        no-unused-vars
  1442:15  error  "s1" is defined but never used        no-unused-vars
9 years ago
David Majda d34faba59e Speed up deduplication of expectations
The expectation deduplication algorithm called |Array.prototype.splice|
to eliminate each individual duplication, which was slow. This caused
problems with grammar/input combinations that generated a lot of
expecations (see #377 for an example).

This commit replaces the algorithm with much faster one, eliminating the
problem.
9 years ago
David Majda a4a66a2e5b Switch from first/rest to head/tail in the PEG.js grammar
In the past year I worked on various grammars where first/rest or
head/tail were used as labels for parts of lists. I found I associate
head/tail with a list immediately, while in case of first/rest I have to
"parse" grammar rules for a while before understanding their structure.

Moreover, I tend to assume that rest is a list of the same thigs as
first, but I don't have such assumption in case of head/tail. This
assumption was in conflict with the grammar structure.

I'm not sure how much these observations are applicable to others, but I
decided to act on them and switch from first/rest to head/tail.
9 years ago
David Majda 69a0f769fc Use literal raw text in error messages
Fixes #127.
9 years ago