UNPKG

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