189 Commits (364482dd686fd85ca99170aefd62490748f2f6be)

Author SHA1 Message Date
David Majda 143924357b Setup prototype chain for |PEG.GrammarError| correctly 12 years ago
David Majda 428fe294cf Change |PEG.GrammarError| name
Change the value of the |name| property of |PEG.GrammarError| instances
from "PEG.GrammarError" to just "GrammarError". This better reflects the
fact that PEG.js can get required under different name than "PEG".
12 years ago
David Majda df1ecb1313 Fix typo found by Almad also in the generator 12 years ago
David Majda 710bee256a Merge pull request #113 from Almad/master
Grammar typo
12 years ago
David Majda 406ac0a288 Fix banner typo 12 years ago
Almad 030ac3d6f9 Grammar typo 12 years ago
David Majda 208cc33930 Allowed start rules must be specified explicitly
Before this commit, generated parser were able to start parsing from any
rule. This was nice, but it made rule code inlining impossible.

Since this commit, the list of allowed start rules has to be specified
explicitly using the |allowedStartRules| option of the |PEG.buildParser|
method (or the --allowed-start-rule option on the command-line). These
rules will be excluded from inlining when it's implemented.
12 years ago
David Majda 6a1ec7631f Do not modify |options| passed to |PEG.buildParser|
Modifying |options| can lead to subtle bugs.
12 years ago
David Majda a4df483159 s/Modelled/Modeled/
"modelled" is a British variant, "modeled" an US one. PEG.js officially
uses American English.

Based on pull request by John Gietzen:

  https://github.com/dmajda/pegjs/pull/102
12 years ago
David Majda 98ff2eb83f Allow passing options to the parser
This commit replaces the |startRule| parameter of the |parse| method in
generated parsers with more generic |options| -- an options object. This
options object can be used to pass custom options to the parser because
it is visible as the |options| variable inside parser code.

The start rule can now be specified as the |startRule| option. This
means you have to replace all calls like:

  parser.parse("input", "myStartRule");

with

  parser.parse("input", { startRule: "myStartRule" });

Closes GH-37.
12 years ago
David Majda a3fe36a466 Add missing semicolon 12 years ago
David Majda 7134b09e50 Merge |allocateRegisters| and |computeParams| passes
The purpose of this change is to avoid the need to index register
variables storing match results of sequences whose elements are labeled.
The indexing happened when match results of labeled elements were passed
to action/predicate functions.

In order to avoid indexing, the register allocator needs to ensure that
registers storing match results of any labeled sequence elements are
still "alive" after finishing parsing of the sequence. They should not
be used to store anything else at least until code of all actions and
predicates that can see the labels is executed. This requires that the
|allocateRegisters| pass has the knowledge of scoping. Because that
knowledge was already implicitly embedded in the |coputeParams| pass,
the logical step to prevent duplication was to merge it with the
|allocateRegisters| pass. This is what this commit does.

As a part of the merge the tests of both passes were largely refactored.
This is both to accomodate the merge and to make the tests in sync with
the code again (the tests became a bit out-of-sync during the last few
commits -- they tested more than was needed).

The speed/size impact is slightly positive:

Speed impact
------------
Before:     849.86 kB/s
After:      858.16 kB/s
Difference: 0.97%

Size impact
-----------
Before:     876618 b
After:      875602 b
Difference: -0.12%

(Measured by /tools/impact with Node.js v0.6.18 on x86_64 GNU/Linux.)
12 years ago
David Majda a1fd6acc92 Do not compute |resultIndex| for "rule" nodes
Computing |resultIndex| for their expressions is enough.
12 years ago
David Majda 2d36ebeb59 Mental model change: Variables do not form a stack, they are registers
This commit changes the model underlying parser variables used to store
match results and parse positions. Until now they were treated as a
stack, now they are thought of as registers. The actual behavior does
not change (yet), only the terminology.

More specifically, this commit:

  * Changes parser variable names from |result0|, |result1|, etc. to
    |r0|, |r1|, etc.

  * Changes various internal names and comments to match the new model.

  * Renames the |computeVarIndices| pass to |allocateRegisters|.
12 years ago
David Majda 2f3dd951e9 Do not store result variable indices, just the counts 13 years ago
David Majda 42d4fc6dd4 Get rid of two parser variable stacks
One stack is conceptually simpler, requires less code and will make a
transition to a register-based machine easier.

Note that the stack variables are now named a bit incorrectly
(|result0|, |result1|, etc. even when they store also parse positions).
I didn't bother with renaming because a transition to a register-based
machine will follow soon and the names will change anyway.

The speed/size impact is insignificant.

Speed impact
------------
Before:     839.05 kB/s
After:      839.67 kB/s
Difference: 0.07%

Size impact
-----------
Before:     949783 b
After:      961578 b
Difference: 1.24%

(Measured by /tools/impact with Node.js v0.6.18 on x86_64 GNU/Linux.)
13 years ago
David Majda 890140d73b More responsibility for computing |resultIndex| to node's parent
Before this commit, each node was responsible for computing the value of
its |resultIndex| property in the |computeVarIndices| pass. This was
possible because |resultIndex| was always equal to |index.result|,
meaning that nodes always wrote their match results to the top of the
stack.

This behavior would cause problems in the future where nodes will use
the stack also for storing positions. Parent nodes storing position on
the stack would have to copy their childs' match results from the top of
the stack to some position below where parent's match result would be
expected. There would be no way to tell the children to place their
match result somewhere else than the top of the stack and avoid copying.

This commit fixes the described problem by shifting the responsibility
for setting the value of node's |resultIndex| property to its parent.
This way it can direct its child to place its result wherever it wants
to.
13 years ago
David Majda 2c8b323ade Replace variable name computations by computations of indices
This commit replaces all variable name computations in |computeVarNames|
and |computeParams| passes by computations of indices. The actual names
are computed later in the |generateCode| pass.

This change makes the code generator the only place that deals with the
actual variable names, making them easier to change for example.

The code generator code seems bit more complicated after the change, but
this complexity will pay off (and mostly disappear) later.
13 years ago
David Majda 725927e05f Change ordering of "action" code
Places all code that does something with "action" AST nodes under code
handling "choice" nodes.

This ordering is logical because now all the node handling code matches
the sequence in which various node types usually appear when descending
through the AST tree.
13 years ago
David Majda cdf23e0a49 Change ordering of "literal", "class" and "any" code
Changes all code that does something with "literal", "class" or "any"
AST nodes so that the code deals with these in the follwing order:

  1. literal
  2. class
  3. any

Previously the code used this ordering:

  1. literal
  2. any
  3. class

The new ordering is more logical because the nodes are handled from the
most specific to the most generic.
13 years ago
David Majda eb4badab24 Refactor named rules AST representation
PEG.js grammar rules are represented by |rule| nodes in the AST. Until
now, all such nodes had a |displayName| property which was either |null|
or stored rule's human-readable name. This commit gets rid of the
|displayName| property and starts representing rules with a
human-readable name using a new |named| node (a child of the |rule|
node).

This change simplifies code generation code a bit as tests for
|displayName| can be removed (see changes in generate-code.js). It also
separates different concerns from each other nicely.
13 years ago
David Majda a59516f89b Small reordering of properties when creating |class| nodes
General rule: Least important things/flags go last.
13 years ago
David Majda 7900b66c70 Fix |braced| rule in the PEG.js grammar
This fix does not change the behavior, it just makes the
|nonBraceCharacters| rule un-dead (as originally intended).
13 years ago
David Majda 4f86fca3d7 Make the code emitter a compiler pass
This gives the compiler a more regular structure.
13 years ago
David Majda 44852fa6b4 Pass |options| to compiler passes 13 years ago
David Majda 53f70b9eb9 Move compiler passes and their tests into a subdirectory 13 years ago
David Majda f046e0a838 Move compiler-related source files and tests into a subdirectory 13 years ago
David Majda 6091e4426b Update version to 0.7.0 13 years ago
David Majda 7faf40dc44 Do not use results cache in the PEG.js grammar parser 13 years ago
David Majda 5b3321d302 Implement |cache| option for |PEG.buildParser|
This option enables/disables the results cache in generated parsers.
Until now, it was always enabled, but after this commit it needs to be
enabled explicitly (i.e. the |cache| option default value is |false|).
The reason is that parsing without it is *much* faster according to the
benchmark.

Note that disabling the cache breaks the linear parsing time guarantee,
meaning that with some grammars you can get exponential parsing time
with respect to the input length. This, together with the possibility of
improving the cache performance in the future, is the reason to keep it
as an option.

Speed impact
------------
Before:     214.08 kB/s
After:      827.52 kB/s
Difference: 286.54%

Size impact
-----------
Before:     1045396 b
After:      949783 b
Difference: -9.15%

(Measured by /tools/impact with Node.js v0.6.6 on x86_64 GNU/Linux.)
13 years ago
David Majda 1ee6731b51 Supply default option value only if the option is not specified
The "|| trick" is too brittle in this case -- it wouldn't work e.g. for
options with default value |true| and passed value |false|, enforcing
inconsistent default values handling.
13 years ago
David Majda 2aaa038499 Add a hack to skip last comma in |parseFunctions| 13 years ago
David Majda abf33d3feb Add a note about semantic versioning to |PEG.VERSION| comment 13 years ago
David Majda 7f2dc850e0 Change how the library is exported
This commit makes the library define the |PEG| global variable (for
browser export) and possibly assign it into |module.exports| (for
Node.js export) later. The |module.exports| assignment is done *outside*
the main library |function| statement.

The big idea behind this is to make copy & paste inclusion of the
library into another code easier -- one just needs to strip the last
three lines.
13 years ago
David Majda 8d74248251 Make "Generated by ..." comment match the copyright comment 13 years ago
David Majda 7e02e45831 Improve copyright comment 13 years ago
David Majda 90d164445a Update embedded Codie to version 1.1.0 13 years ago
David Majda 52d7ec2224 Implement |trackLineAndColumn| option for |PEG.buildParser|
This option makes the generated parser track line and column during
parsing. Tracked line and column are made available inside actions and
predicates as |line| and |column| variables.

Note that in actions these variables denote start position of the
action's expression while in predicates they denote the current
position. The slightly different behavior is motivated by expected
usage.
13 years ago
David Majda 9615eb4bb6 Allow passing options to |PEG.buildParser|
These get passed down to the emitter templates.
13 years ago
David Majda f2f88b87ea Make current parse position visible in actions and predicates
The speed/size impact is insignificant.

Speed impact
------------
Before:     214.11 kB/s
After:      214.87 kB/s
Difference: 0.35%

Size impact
-----------
Before:     1042691 b
After:      1046731 b
Difference: 0.38%

(Measured by /tools/impact with Node.js v0.6.6 on x86_64 GNU/Linux.)
13 years ago
David Majda f47da5c682 Fix a bug in param name fixup code for sequences 13 years ago
David Majda 4d5b1d58aa AST: Store rules in an array instead of an object
This simplifies the code a bit and makes the AST more regular (each node
type has a fixed set of properties). The latter may get useful later
when generalizing visitors.
13 years ago
David Majda ed45a1808e Fix |quote| visibility in generated parsers
|quote| is used outside of the |parse| function so it must be defined in
more outer scope.

Fixes a problem (introduced in e9d8dc8eba)
where construction of some error messages could throw an error.
13 years ago
David Majda a2af1fe612 Semantic predicates now have access to preceding labels
Part of a fix for GH-69.
13 years ago
David Majda 4cf50bcf9f Move param computations from the emitter into a separate pass
This has two main benefits:

  1. The knowledge about scoping params in at one designated place,
     making all future adjustments in this area easier.

  2. Action-related code does not handle sequences specially anymore.
     Such knowledge/behavior doesn't belong there.
13 years ago
David Majda efc38eef9b Consolidate all variable name computations into one compiler pass
Before this change, knowledge about variable names was spread between
the |computeStackDepths| pass and the code emitter code. For example,
the fact that the |&...| expression needs one variable to store a
position was represented in both places.

This changes consolidates that knowledge and introduces a new
|computeVarNames| pass. This pass replaces old |computeStackDepths|
pass, does all computations realted to variable names and stores the
results in the AST. Note that some knowledge about variables
(inevitably) remained in emitter code templates.

Beside DRYing things up, this change simplifies the emitter
significantly. By storing variable names in the AST it also allows
introduction of a pass that will identify parameters passed to actions
using proper symbol tables. Right now, this is done in a hackish way
directly in the emitter, which won't work well with changes planned in
GH-69.
13 years ago
David Majda d002cd6ff6 Remove comment about IE in |quoteForRegexpClass|
We escape null for general compatibility (see comment at the top of the
function), not only because of IE.
13 years ago
David Majda 46b2eaf3e3 Add |expected| and |found| properties to exceptions thrown by parsers
Based on a patch by Marcin Stefaniuk (marcin@stefaniuk.info).
13 years ago
David Majda e9d8dc8eba More responsibility for building an error message into |SyntaxError| 13 years ago
David Majda 21c6d9ccd3 Add |offset| property to exceptions thrown by parsers
Based on a patch by Marcin Stefaniuk (marcin@stefaniuk.info).
13 years ago
David Majda 791c495aec Update embedded Codie to version 1.0.1 13 years ago
David Majda 47969a2f61 Replace |for| loop iterating over sequence elements with |each| 13 years ago
David Majda a19ea83ffa Replace |for| loop iterating over compiler passes with |each| 13 years ago
David Majda cd5490dee4 Make pass list customizable via |PEG.compiler.appliedPassNames| property 13 years ago
David Majda 8a0276ffb7 Unify checks and passes
There is no real reason to have them separated.
13 years ago
David Majda 6cd5bdc5e6 Passes now do not return anything (they always modify the AST in-place) 13 years ago
David Majda 3983f46d5d Rename |reportMissingReferencedRules| check to |reportMissingRules|
The new name is shorter, there is no real loss of meaning.
13 years ago
David Majda 64d26e5db2 Make names of compiler checks and passes verbs 13 years ago
David Majda 2a82d863e5 Regenerate src/parser.js (forgot to do it in previous commit) 13 years ago
David Majda 8acea01525 Fix reported error position when part of the input is not consumed
Closes GH-48.
13 years ago
David Majda 211a1116e4 Fix stack depth computations for empty sequences
Part of a fix for GH-53.
13 years ago
David Majda afdcb6fc4f Fix |posStackDepth| computation for rules
Rules by themselves do not need any variable for storing position.

Part of a fix for GH-53.
13 years ago
David Majda 756b6fc473 Fix |resultStackDepth| computation for sequences
The |1 + ...| was wrong -- sequence does not need its own variable since
it reuses the one used by the first item.

Part of a fix for GH-53.
13 years ago
David Majda c639c1fc83 PEG.js grammar: Replace two instances of |string / ""| by |string?| 13 years ago
David Majda c04af99df8 Implament case-insensitive class matching 13 years ago
David Majda b540b2d460 Implement case-insensitive literal matching 13 years ago
David Majda 1c11e4aaa3 Split |literal| rule in the PEG.js grammar to |literal| and |string|
This is just a formality now but it will make sense later when literals
(but not strings) will allow "i" flag for case-insensitive matching.
13 years ago
David Majda da12c2f5d4 Compile Codie templates only once 13 years ago
David Majda a5af9611a2 Introduce |context.delta| function to make creating contexts more DRY 13 years ago
David Majda be3b87ec71 Refactor "grammar" emitter function a bit 13 years ago
David Majda 2b09a7116d Refactor "rule" emitter function a bit 13 years ago
David Majda 131b6dd01f Refactor "sequence" emitter function a bit 13 years ago
David Majda f29ff236b8 Refactor "simple_and" emitter function a bit 13 years ago
David Majda 506d8107a1 Refactor "simple_not" emitter function a bit 13 years ago
David Majda 13ae52b2bf Refactor "semantic_and" emitter function a bit 13 years ago
David Majda 9111020ca2 Refactor "semantic_not" emitter function a bit 13 years ago
David Majda cc3bd4f310 Refactor "zero_or_more" emitter function a bit 13 years ago
David Majda 85c1b010b6 Refactor "one_or_more" emitter function a bit 13 years ago
David Majda b5ca96dd48 Refactor "action" emitter function a bit 13 years ago
David Majda 50a0371e2d Refactor "rule_ref" emitter function a bit 13 years ago
David Majda eaba6b8a9d Refactor "literal" emitter function a bit 13 years ago
David Majda 2120c908c7 Refactor "class" emitter function a bit 13 years ago
David Majda 0748fee1d3 Use Codie for code templates
This will allow moving some code into the templates later.
13 years ago
David Majda 38c25efde0 Use single quotes for code in the emitter
Strings with code should use single quotes so that double quotes (which
I generally prefer) could be used in the code itself without escaping.
13 years ago
David Majda 45c99f8f6b Generate more efficient code for empty literals
Original patch by Wolfgang Kluge:

  797173f676
13 years ago
David Majda 4de3cc1716 Fix comment typos
Original patch by Wolfgang Kluge:

  07e0cfcc02
13 years ago
David Majda eceda8b5e8 Use correct disjunction operator in |computeErrorPosition|
Original patch by Wolfgang Kluge:

  6b793b33df
13 years ago
David Majda cc4910d9b9 src/compiler.js: Fix variable redefinition
Fixes the following JSHint error:

  ./src/compiler.js: line 23, col 16, 'i' is already defined.
13 years ago
David Majda bc4821581c src/emitter.js: Fix variable redefinitions
Fixes the following JSHint errors:

  ./src/emitter.js: line 95, col 21, 'name' is already defined.
  ./src/emitter.js: line 361, col 35, 'setReportFailuresCode' is already defined.
  ./src/emitter.js: line 362, col 39, 'restoreReportFailuresCode' is already defined.
  ./src/emitter.js: line 363, col 31, 'reportFailureCode' is already defined.
  ./src/emitter.js: line 393, col 38, 'setReportFailuresCode' used out of scope.Fixes the following JSHint errors:
  ./src/emitter.js: line 394, col 38, 'restoreReportFailuresCode' used out of scope.
  ./src/emitter.js: line 395, col 38, 'reportFailureCode' used out of scope.
  ./src/emitter.js: line 666, col 26, 'formalParams' is already defined.
  ./src/emitter.js: line 667, col 26, 'actualParams' is already defined.
  ./src/emitter.js: line 669, col 26, 'formalParams' is already defined.
  ./src/emitter.js: line 670, col 26, 'actualParams' is already defined.
  ./src/emitter.js: line 685, col 27, 'formalParams' used out of scope.
  ./src/emitter.js: line 686, col 27, 'actualParams' used out of scope.
  ./src/emitter.js: line 770, col 20, 'regexp' is already defined.
  ./src/emitter.js: line 784, col 22, 'regexp' used out of scope.
13 years ago
David Majda a52522c7c6 src/emitter.js: Remove unnecessary semicolon
Fixes the following JSHint error:

  ./src/emitter.js: line 77, col 4, Unnecessary semicolon.
13 years ago
David Majda d1b83e4ab3 src/emitter.js: Use strict comparison
Fixes the following JSHint error:

  ./src/emitter.js: line 44, col 48, Expected '!==' and instead saw '!='.
13 years ago
David Majda f893d47b98 src/utils.js: Make |quoteForRegexpClass| escape control characters
Fixes the following JSHint errors:

  ./src/parser.js: line 3614, col 16, Mixed spaces and tabs.
  ./src/parser.js: line 3614, col 20, Unsafe character.
13 years ago
David Majda ab49197ef1 src/utils.js: Make |quote| escape control characters
Also change |quote| in src/emitter.js so both are in sync.

Fixes the following JSHint errors:

  ./src/parser.js: line 3613, col 27, Mixed spaces and tabs.
  ./src/parser.js: line 3613, col 31, Unsafe character.
  ./src/parser.js: line 3613, col 38, Control character in string: [     .
  ./src/parser.js: line 3613, col 40, Control character in string: [
13 years ago
David Majda 67afc788ad src/parser.pegjs: Use radix in |parseInt| calls instead of "0x" prefix
Fixes the following JSHint errors:

  ./src/parser.js: line 2878, col 44, Missing radix parameter.
  ./src/parser.js: line 2949, col 44, Missing radix parameter.
13 years ago
David Majda 13c47d6c4f src/parser.pegjs: Replace "\0" with "\x00"
Fixes the following JSHint error:

  ./src/parser.js: line 2820, col 44, Bad escapement.
13 years ago
David Majda b80cd9cb02 src/parser.pegjs: Use strict comparison
Fixes the following JSHint errors:

  ./src/parser.js: line 460, col 50, Expected '!==' and instead saw '!='.
  ./src/parser.js: line 486, col 42, Expected '!==' and instead saw '!='.
13 years ago
David Majda cc416199be src/parser.pegjs: Add missing semicolons
Fixes the following JSHint errors:

  ./src/parser.js: line 193, col 18, Missing semicolon.
  ./src/parser.js: line 407, col 20, Missing semicolon.
  ./src/parser.js: line 2493, col 18, Missing semicolon.
  ./src/parser.js: line 2759, col 40, Missing semicolon.
13 years ago
David Majda 559db3a812 src/emitter.js: Sync |escape| in generated parsers with utils.js
Fixes the following JSHint errors:

  ./src/parser.js: line 102, col 26, 'escapeChar' is already defined.
  ./src/parser.js: line 103, col 22, 'length' is already defined.
  ./src/parser.js: line 106, col 23, 'escapeChar' used out of scope.
  ./src/parser.js: line 106, col 86, 'length' used out of scope.
13 years ago
David Majda e0ef7e1abb src/passes.js: Add missing semicolon
Fixes the following JSHint error:

  ./src/passes.js: line 98, col 8, Missing semicolon.
13 years ago
David Majda 2f671e0022 src/peg.js: Prevent redefinition of |undefined| differently
Fixes the following JSHint error:

  ./src/peg.js: line 5, col 5, Expected an identifier and instead saw 'undefined' (a reserved word).
13 years ago