1 |
|
2 | pegjs-otf
|
3 | =========
|
4 |
|
5 | This is a small wrapper class around the [PEG.js](http://pegjs.org/) API and a companion
|
6 | [Browserify](http://browserify.org/) transform for on-the-fly (OTF) compiling [PEG.js](http://pegjs.org/) grammars into
|
7 | parser code under a syntactically identical usage for both [Node](http://nodejs.org/)/NPM and
|
8 | Browser/[Browserify](http://browserify.org/) environments.
|
9 |
|
10 | <p/>
|
11 | <img src="https://nodei.co/npm/pegjs-otf.png?downloads=true&stars=true" alt=""/>
|
12 |
|
13 | <p/>
|
14 | <img src="https://david-dm.org/rse/pegjs-otf.png" alt=""/>
|
15 |
|
16 | Installation
|
17 | ------------
|
18 |
|
19 | ```shell
|
20 | $ npm install pegjs-otf
|
21 | $ npm install browserify
|
22 | ```
|
23 |
|
24 | Usage
|
25 | -----
|
26 |
|
27 | With a sample grammar `sample.pegjs` like this...
|
28 |
|
29 | ```
|
30 | sample
|
31 | = _ "hello" _ who:[A-Za-z]+ _ { return who.join(""); }
|
32 |
|
33 | _ "blank"
|
34 | = (co / ws)*
|
35 |
|
36 | co "comment"
|
37 | = "//" (![\r\n] .)*
|
38 | / "/*" (!"*/" .)* "*/"
|
39 |
|
40 | ws "whitespaces"
|
41 | = [ \t\r\n]+
|
42 | ```
|
43 |
|
44 | ...instead of using a `sample.js` driver...
|
45 |
|
46 | ```js
|
47 | var PEG = require("pegjs-otf");
|
48 | var fs = require("fs");
|
49 | var parser = PEG.generate(
|
50 | fs.readFileSync(__dirname + "/sample.pegjs", "utf8"),
|
51 | { optimize: "size" }
|
52 | );
|
53 | console.log(parser.parse("hello world") === "world" ? "OK" : "FAIL");
|
54 | ```
|
55 |
|
56 | ...now use a `sample.js` driver like this:
|
57 |
|
58 | ```js
|
59 | var PEG = require("pegjs-otf");
|
60 | var parser = PEG.generateFromFile(
|
61 | __dirname + "/sample.pegjs",
|
62 | { optimize: "size" }
|
63 | );
|
64 | console.log(parser.parse("hello world") === "world" ? "OK" : "FAIL");
|
65 | ```
|
66 |
|
67 | Then it will work in both Node (through on-the-fly run-time compilation)...
|
68 |
|
69 | ```shell
|
70 | $ node sample.js
|
71 | OK
|
72 | ```
|
73 |
|
74 | ...and the Browser (with the help of Browserify through on-the-fly compile-time compilation):
|
75 |
|
76 | ```shell
|
77 | $ browserify -t pegjs-otf/transform -o sample.browser.js sample.js
|
78 | $ node sample.browser.js
|
79 | OK
|
80 | ```
|
81 |
|
82 | Intention & How It Works
|
83 | ------------------------
|
84 |
|
85 | The API returned by `require("pegjs-otf")` is really just the PEG.js
|
86 | API with an additional injected method `generateFromFile(filename,
|
87 | options)`. And this `generateFromFile(filename, options)`
|
88 | is actually *not* really some sort of an important
|
89 | convenience function, because it technically is just
|
90 | `require("pegjs").generate(require("fs").readFileSync(filename),
|
91 | options)` and this would not warrant an extra wrapper API, of course.
|
92 | Instead the `pegjs-otf` module and its distinct `generateFromFile`
|
93 | method is actually a *marker*.
|
94 |
|
95 | In a regular [Node](http://nodejs.org/)
|
96 | environment it really just performs its simple
|
97 | `require("pegjs").generate(require("fs").readFileSync(filename),
|
98 | options)` operation. But when the application code is transpiled
|
99 | for a Browser environment with the help of the excellent
|
100 | [Browserify](http://browserify.org/), then the `pegjs-otf/transform`
|
101 | transform can kick in and replaces the `var xx = require("pegjs-otf")`
|
102 | call with nothing and the `xx.generateFromFile(filename, options)`
|
103 | call with the corresponding on-the-fly compiled parser code.
|
104 |
|
105 | This way you need no extra build-time step for neither Node nor Browser
|
106 | environments just because of PEG.js usage. And both Node and Browser
|
107 | environments behave identically without having to alter the source.
|
108 |
|
109 | Rationale
|
110 | ---------
|
111 |
|
112 | There is another Browserify transform named
|
113 | [browserify-pegjs](https://github.com/tyler-johnson/browserify-pegjs)
|
114 | which transpiles `require("sample.pegjs")` calls into the actual
|
115 | on-the-fly compiled parser code. It has two drawbacks compared to
|
116 | pegjs-otf: this is fine for Browser environments, but it fails in
|
117 | regular Node environments and the only way to pass options to PEG.js'
|
118 | `generate` is via external Browserify options.
|
119 |
|
120 | The second of the two above drawbacks cannot be resolved. The first
|
121 | of the two above drawbacks can be circumvented with another module
|
122 | named [pegjs-require](https://github.com/dbalcomb/pegjs-require).
|
123 | Unfortunately, this has the same drawback as `browserify-pegjs`: it also
|
124 | does not allow the passing of options to the underlying `generate`
|
125 | method.
|
126 |
|
127 | For those reasons I've written pegjs-otf, as it supports both Node
|
128 | and Browserify environments and allows the passing of options to
|
129 | `generate`.
|
130 |
|
131 | License
|
132 | -------
|
133 |
|
134 | Copyright (c) 2014-2017 Ralf S. Engelschall (http://engelschall.com/)
|
135 |
|
136 | Permission is hereby granted, free of charge, to any person obtaining
|
137 | a copy of this software and associated documentation files (the
|
138 | "Software"), to deal in the Software without restriction, including
|
139 | without limitation the rights to use, copy, modify, merge, publish,
|
140 | distribute, sublicense, and/or sell copies of the Software, and to
|
141 | permit persons to whom the Software is furnished to do so, subject to
|
142 | the following conditions:
|
143 |
|
144 | The above copyright notice and this permission notice shall be included
|
145 | in all copies or substantial portions of the Software.
|
146 |
|
147 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
148 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
149 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
150 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
151 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
152 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
153 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
154 |
|