49 Commits (9446e07f6acba905481e2e71c0a37774e479be70)

Author SHA1 Message Date
David Majda bf9d9561c4 Tighten "try ... catch" clauses in spec helpers
They wrapped too much code.
8 years ago
David Majda 67d85f2de8 Align names of compiler passes that detect infinite loops
Rename compiler passes as follows:

  reportLeftRecursion -> reportInfiniteRecursion
  reportInfiniteLoops -> reportInfiniteRepetition

This reflects the fact that both passes detect different ways of causing
the same problem (possible infinite loop when parsing).
8 years ago
David Majda 9717dc3417 Talk about "undefined rules" instead of "missing rules" internally
The new terminology is more precise and in line with commonly used
programming languages.

The change involves mainly renaming related compiler pass and files
associated with it.
8 years ago
David Majda 65550965c6 Remove extraneous "with" from an error message 8 years ago
David Majda ec8ede5bbe Grammar error messages 3/3: Improve the left recursion message
New wording is more explanatory.

Part of #371.
8 years ago
David Majda f5e43f842c Grammar error messages 2/3: Improve the infinite loop message
New wording is more explanatory.

Part of #371.
8 years ago
David Majda 85fb8aaa0e Grammar error messages 1/3: Improve the missing rule message
New wording is more similar to wording used in various programming
languages and it is in line with the duplicate rule message.

Part of #371.
8 years ago
David Majda eb67cbedb4 Report duplicate labels as errors
Resolves #270.
9 years ago
David Majda 2a889535bd Add location to the "Rule ... is already defined" error message
See this discussion:

  eb5875bc6a (commitcomment-17970220)
9 years ago
David Majda eb5875bc6a Report duplicate rule definitions as errors
Based on a pull request by Futago-za Ryuu (@futagoza):

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

Resolves #318.
9 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 319931876d Expectation refactoring 4/7: Generate descriptions dynamically
Instead of pre-generating expectation descriptions when generating
parsers, generate them dynamically from structured information contained
in the expectations.

This change makes descriptions a presentation-only concept. It also
makes generated parsers smaller.
9 years ago
David Majda c6e8c53f1b Expectation refactoring 2/7: Restructure "class" expectations
Changes:

  * Remove the "value" property (it is replaced by other properties).

  * Add the "parts", "inverted", and "ignoreCase" properties (which
    allow more structured access to expectation data).
9 years ago
David Majda eda2a34c7f Expectation refactoring 1/7: Restructure "literal" expectations
Changes:

  * Rename the "value" property to "text" (because it doesn't contain
    the whole value, which also includes the case sensitivity flag).

  * Add the "ignoreCase" property (which was missing).
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 1f7efd57c0 Remove various JSHint-related cruft
We use ESLint now, which is smarter about some things.
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 0847a69643 Rename the "PEG" variable to "peg"
So far, PEG.js was exported in a "PEG" global variable when no module
loader was detected. The same variable name was also conventionally used
when requiring it in Node.js or otherwise referring to it. This was
reflected in various places in the code, documentation, examples, etc.

This commit changes the variable name to "peg" and fixes all relevant
occurrences. The main reason for the change is that in Node.js, modules
are generally referred to by lower-case variable names, so "PEG" was
sticking out when used in Node.js projects.
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 f866712c90 Regularize Jasmine custom matcher signatures
The "toParse" matcher in generated-parser-behavior.spec.js effectively
had these signatures:

  toParse(input)
  toParse(input, expected)
  toParse(input, options, expected)

This commit regularizes them to:

  toParse(input)
  toParse(input, expected)
  toParse(input, expected, options)

Similarly, the "toFailToParse" matcher in
generated-parser-behavior.spec.js effectively had these signatures:

  toFailToParse(input)
  toFailToParse(input, details)
  toFailToParse(input, options, details)

This commit regularizes them to:

  toFailToParse(input)
  toFailToParse(input, details)
  toFailToParse(input, details, options)

Finally, the "toChangeAST" matcher in helpers.js effectively had these
signatures:

  toChangeAST(grammar, details)
  toChangeAST(grammar, options, details)

This commit regularizes them to:

  toChangeAST(grammar, details)
  toChangeAST(grammar, details, options)

The overall purpose of these changes is to avoid different parameters
appearing at the same position, which is hard to manage without using
"arguments".
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 e61c23c634 ESLint: Set environments better
Instead of setting ESLint environment to "node" globally, set it on
per-directory basis using separate .eslintrc.json files:

  Directory   Environment
  -----------------------
  bin         node
  lib         commonjs
  spec        jasmine

It was impossible to use this approach for the "benchmark" directory
which contains a mix of files used in various environments. For
benchmark/run, the environment is set inline. For the other files, as
well as spec/helpers.js, the globals are declared manually (it is
impossible to express how these files are used just by a list of
environments).

Fixes #408.
9 years ago
David Majda 768ece28e6 Use ESLint instead of JSHint
Implement the swap and change various directives in the source code. The
"make hint" target becomes "make lint".

The change leads to quite some errors being reported by ESLint. These
will be fixed in subsequent commits.

Note the configuration enables just the recommended rules. Later I plan
to enable more rules to enforce the coding standard. The configuration
also sets the environment to "node", which is far from ideal as the
codebase contains a mix of CommonJS, Node.js and browser code. I hope to
clean this up at some point.
9 years ago
David Majda 69a0f769fc Use literal raw text in error messages
Fixes #127.
9 years ago
David Majda 36eb7b81b5 Use single quotes for |rawText| in parser specs
PEG.js convention is to use single quotes for code and |rawText| *is* a
piece of code (originally).
9 years ago
David Majda bbb4f006cd Report full rule chain in recursive rule errors
The idea came from a PR by @Mingun:

  https://github.com/pegjs/pegjs/pull/307
9 years ago
David Majda 491106c347 Report left recursion and infinite loops only as "possible"
A semantic predicate can prevent the parser to actually enter infinite
recursion or loop. This is undetectable at compile-time.
9 years ago
David Majda ebf5d969b2 s/alwaysAdvancesOnSuccess/alwaysConsumesOnSuccess/
Matches terminology change from the previous commit.
9 years ago
David Majda 60ebd9e695 Simplify JSHint directives 9 years ago
David Majda a4772376fb Renumber bytecode instructions sequentially 9 years ago
David Majda ad27a300a8 Fix left recursion detection in sequences
Report left recursion also in cases where the recursive rule invocation
is not a direct element of a sequence, but is wrapped inside an
expression.

Fixes #359.
9 years ago
David Majda 703a352985 Change few testcase descriptions
Reaction to changes in 130cbcfaa3.
9 years ago
David Majda d7d7e87874 Make infinite loop and left recursion detectors work with named rules
Add missing |named| case to the visitor in lib/compiler/asts.js, which
makes the infinite loop and left recursion detectors work correctly with
named rules.

The missing case caused |make parser| to fail with:

  140:34: Infinite loop detected.
  make: *** [parser] Error 1
9 years ago
David Majda 317059760a Fix incorrect pass name in a spec description 9 years ago
David Majda 373f48c10f Fix small error in two testcases
Pointed out by @Mingun:

  6ce97457bf (commitcomment-10548605)
9 years ago
Arlo Breault 12c169e7b5 Convert PEG.js code to strict mode
* Issues #323
10 years ago
David Majda eaca5f0acf Add location information to |GrammarError|
This means all errors thrown by |PEG.buildParser| now have associated
location information.
10 years ago
David Majda 89146915ce Add location information to AST nodes
This will allow to add location information to |GrammarError| exceptions
thrown in various passes.
10 years ago
David Majda b1ad2a1f61 Rename |reportedPos| to |savedPos|
Preform the following renames:

  * |reportedPos| -> |savedPos| (abstract machine variable)
  * |peg$reportedPos| -> |peg$savedPos| (variable in generated code)
  * |REPORT_SAVED_POS| -> |LOAD_SAVED_POS| (instruction)
  * |REPORT_CURR_POS| -> |UPDATE_SAVED_POS| (instruction)

The idea is that the name |reportedPos| is no longer accurate after the
|location| change (seea the previous commit) because now both
|reportedPos| and |currPos| are reported to user code. Renaming to
|savedPos| resolves this inaccuracy.

There is probably some better name for the concept than quite generic
|savedPos|, but it doesn't come to me.
10 years ago
David Majda 3473c6cb64 Remove extra whitespace 10 years ago
David Majda fb320c4c59 Fix small errors in Jasmine matcher messages 10 years ago
David Majda d7fc0b5c3b Implement infinite loop detection
Fixes #26.
10 years ago
David Majda 6ce97457bf Fix left recursion detection
So far, left recursion detector assumed that left recursion occurs only
when the recursive rule is at the very left-hand side of rule's
expression:

  start = start

This didn't catch cases like this:

  start = "a"? start

In general, if a rule reference can be reached without consuming any
input, it can lead to left recursion. This commit fixes the detector to
consider that.

Fixes #190.
10 years ago
David Majda 5a2ca2abc7 Add two missing blank lines 11 years ago
David Majda 5ce5f7a612 Specs cleanup: Use raw node types in |generateBytecode| specs
Use raw node types instead of humanized node names in |generateBytecode|
specs. This corresponds more closely to the level the specs are written
at.
11 years ago
David Majda 0977dd37a3 Reordering in visitors and their specs
Reorder visiting functions and their specs to more closely match
ordering used in the PEG.js grammar.
11 years ago
David Majda 850ddf5889 Specs cleanup: Simplify compiler passes specs
After 898a7b5a2d the specs mostly tested
the visitor implementation, not actual code in the passes.
11 years ago
David Majda 3d637173ee Specs cleanup: Split specs into unit and API specs
Unit specs are unit tests of internal stuff. API specs are tests of the
user-visible APIs and behavior.

I think it makes sense to make this distinction because then the public
API line is more clearly visible e.g. when using the specs as
documentation.
11 years ago