16 Commits (7aa4d519db75bf0d6f66f252454005140146325f)

Author SHA1 Message Date
David Majda 2263a30034 Update version to 0.8.0 11 years ago
David Majda fe1ca481ab Code generator rewrite
This is a complete rewrite of the PEG.js code generator. Its goals are:

  1. Allow optimizing the generated parser code for code size as well as
     for parsing speed.

  2. Prepare ground for future optimizations and big features (like
     incremental parsing).

  2. Replace the old template-based code-generation system with
     something more lightweight and flexible.

  4. General code cleanup (structure, style, variable names, ...).

New Architecture
----------------

The new code generator consists of two steps:

  * Bytecode generator -- produces bytecode for an abstract virtual
    machine

  * JavaScript generator -- produces JavaScript code based on the
    bytecode

The abstract virtual machine is stack-based. Originally I wanted to make
it register-based, but it turned out that all the code related to it
would be more complex and the bytecode itself would be longer (because
of explicit register specifications in instructions). The only downsides
of the stack-based approach seem to be few small inefficiencies (see
e.g. the |NIP| instruction), which seem to be insignificant.

The new generator allows optimizing for parsing speed or code size (you
can choose using the |optimize| option of the |PEG.buildParser| method
or the --optimize/-o option on the command-line).

When optimizing for size, the JavaScript generator emits the bytecode
together with its constant table and a generic bytecode interpreter.
Because the interpreter is small and the bytecode and constant table
grow only slowly with size of the grammar, the resulting parser is also
small.

When optimizing for speed, the JavaScript generator just compiles the
bytecode into JavaScript. The generated code is relatively efficient, so
the resulting parser is fast.

Internal Identifiers
--------------------

As a small bonus, all internal identifiers visible to user code in the
initializer, actions and predicates are prefixed by |peg$|. This lowers
the chance that identifiers in user code will conflict with the ones
from PEG.js. It also makes using any internals in user code ugly, which
is a good thing. This solves GH-92.

Performance
-----------

The new code generator improved parsing speed and parser code size
significantly. The generated parsers are now:

  * 39% faster when optimizing for speed

  * 69% smaller when optimizing for size (without minification)

  * 31% smaller when optimizing for size (with minification)

(Parsing speed was measured using the |benchmark/run| script. Code size
was measured by generating parsers for examples in the |examples|
directory and adding up the file sizes. Minification was done by |uglify
--ascii| in version 1.3.4.)

Final Note
----------

This is just a beginning! The new code generator lays a foundation upon
which many optimizations and improvements can (and will) be made.

Stay tuned :-)
12 years ago
David Majda 3333cdd18d Position tracking: Kill the |trackLineAndColumn| option
Getting rid of the |trackLineAndColumn| simplifies the code generator
(by unifying two paths in the code).

The |line| and |column| functions currently always compute all the
position info from scratch, which is horribly ineffective. This will be
improved in later commit(s).
12 years ago
David Majda 0519d7e3ce Git repo npmization: Make the repo a npm package
Includes:

  * Moving the source code from /src to /lib.
  * Adding an explicit file list to package.json
  * Updating the Makefile.
  * Updating the spec and benchmark suites and their READMEs.

Part of a fix for GH-32.
12 years ago
David Majda 6f78df19d4 Make benchmark suite support the |cache| option
Both the browser and the command-line version of the benchmark suite
runner now allow users to specify a value of the |cache| option.
13 years ago
David Majda 0865e9e51a Make benchmark suite support |trackLineAndColumn| option
Both the browser and the command-line version of the benchmark suite
runner now allow users to specify a value of the |trackLineAndColumn|
option. In case of the command-line version this required a minor CLI
redesign.
13 years ago
David Majda 11a44948ab Extract JavaScript and CSS from benchmark/index.html into separate files
JavaScript is extracted to make it JSHintable, CSS is just for symmetry.
13 years ago
David Majda a091cb2ffd Factor out parts of benchmarks unrelated to running in the browser 14 years ago
David Majda 5ab36f8018 Split the vendor directory
There are now three vendor directories. The goal is to have test- and
benchmark-specific stuff is its own directories and not in the main one.

  vendor
  test/vendor
  benchmark/vendor
14 years ago
David Majda e59f3ba338 Split the source code into several files, introduce build system
The source code is now in the src directory. The library needs to be
built using "rake", which creates the lib/peg.js file by combining the
source files.
14 years ago
David Majda c3b5c2131a Benchmark: Factor benchmark into several functions run using |setTimeout|
We do this for two reasons:

  1. To avoid bowser mechanism for interrupting long-running scripts to
     kick-in (or at least to not kick-in that often).

  2. To ensure progressive rendering of results in the browser (some
     browsers do not render at all when running JavaScript code).

This does not change the benchmark suite execution speed statistically
significantly on V8.

Detailed results (benchmark suite totals):

---------------------------------
 Test #     Before       After
---------------------------------
      1   31.04 kB/s   31.18 kB/s
      2   31.26 kB/s   30.89 kB/s
      3   31.15 kB/s   31.19 kB/s
      4   30.52 kB/s   31.21 kB/s
      5   31.00 kB/s   30.73 kB/s
---------------------------------
Average   30.99 kB/s   31.04 kB/s
---------------------------------

Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/533.4 (KHTML, like Gecko) Chrome/5.0.375.99 Safari/533.4
14 years ago
David Majda 647e7be1fd Benchmark: Users can specify the number of runs 15 years ago
David Majda 4cae3f9b48 Benchmark: Make results table fixed-width, center everything 15 years ago
David Majda 28459236aa Removed trailing comma that caused error in IE. 15 years ago
David Majda e63f64a3d5 Make the generated parsers standalone (no runtime is required).
This and also speeds up the benchmark suite execution by 7.83 % on V8.

Detailed results (benchmark suite totals):

---------------------------------
 Test #     Before       After
---------------------------------
      1   26.17 kB/s   28.16 kB/s
      2   26.05 kB/s   28.16 kB/s
      3   25.99 kB/s   28.10 kB/s
      4   26.13 kB/s   28.11 kB/s
      5   26.14 kB/s   28.07 kB/s
---------------------------------
Average   26.10 kB/s   28.14 kB/s
---------------------------------

Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.7 Safari/533.2
15 years ago
David Majda cfd46b622a Added a benchmark suite. 15 years ago