Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

pegjs-util

Package Overview
Dependencies
Maintainers
1
Versions
48
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

pegjs-util - npm Package Compare versions

Comparing version 0.9.5 to 0.9.6

2

bower.json
{
"name": "pegjs-util",
"version": "0.9.5",
"version": "0.9.6",
"description": "Utility Class for PEG.js",

@@ -5,0 +5,0 @@ "main": "PEGUtil.js",

{
"name": "pegjs-util",
"version": "0.9.5",
"version": "0.9.6",
"description": "Utility Class for PEG.js",

@@ -28,4 +28,7 @@ "keywords": [ "pegjs", "parser", "AST", "unroll" ],

"grunt-eslint": "~2.1.0",
"pegjs": "~0.8.0"
"pegjs": "~0.8.0",
"asty": "~0.9.0"
},
"dependencies": {
}
}

@@ -45,210 +45,13 @@ /*

/* Abstract Syntax Tree (AST) */
PEGUtil.AST = function () {
if (!(this instanceof PEGUtil.AST)) {
var self = new PEGUtil.AST("");
return self.init.apply(self, arguments);
}
return this.init.apply(this, arguments);
/* helper function for generating a function to generate an AST node */
PEGUtil.makeAST = function makeAST (line, column, offset) {
if (makeAST._cb === null)
throw new Error("makeAST: no callback set: you have to provide it via PEGUtil.makeAST.cb() first");
return function () {
return makeAST._cb.call(PEGUtil, line(), column(), offset(), arguments);
};
};
PEGUtil.AST.prototype = {
/* constructor helper: AST node initialization */
init: function (T) {
if (typeof T === "undefined")
throw new Error("init: invalid argument");
this.T = T;
this.A = {};
this.C = [];
this.P = { L: 0, C: 0, O: 0 };
return this;
},
PEGUtil.makeAST.cb = function (cb) { this._cb = cb; };
PEGUtil.makeAST._cb = null;
/* merge attributes and childs of an AST node */
merge: function (node, takePos, attrMap) {
if (typeof node !== "object")
throw new Error("merge: invalid AST node argument");
if (typeof takePos === "undefined")
takePos = false;
if (typeof attrMap === "undefined")
attrMap = {};
var self = this;
if (takePos) {
var pos = node.pos();
self.pos(pos.L, pos.C, pos.O);
}
node.attrs().forEach(function (attrSource) {
var attrTarget = (typeof attrMap[attrSource] !== "undefined" ?
attrMap[attrSource] : attrSource);
if (attrTarget !== null)
self.set(attrTarget, node.get(attrSource));
});
node.childs().forEach(function (child) {
self.add(child);
});
return this;
},
/* check the type of an AST node */
type: function (T) {
if (arguments.length === 0)
return this.T;
else if (arguments.length === 1) {
this.T = T;
return this;
}
else
throw new Error("type: invalid number of arguments");
},
/* set the parsing position */
pos: function (L, C, O) {
if (arguments.length === 0)
return this.P;
else if (arguments.length <= 3) {
this.P.L = L || 0;
this.P.C = C || 0;
this.P.O = O || 0;
return this;
}
else
throw new Error("pos: invalid number of arguments");
},
/* set AST node attributes */
set: function () {
if (arguments.length === 1 && typeof arguments[0] === "object") {
var self = this;
var args = arguments;
Object.keys(args[0]).forEach(function (key) { self.A[key] = args[0][key]; });
}
else if (arguments.length === 2)
this.A[arguments[0]] = arguments[1];
else
throw new Error("set: invalid arguments");
return this;
},
/* get AST node attributes */
get: function (key) {
if (arguments.length !== 1)
throw new Error("get: invalid number of arguments");
if (typeof key !== "string")
throw new Error("get: invalid argument");
return this.A[key];
},
/* get names of all AST node attributes */
attrs: function () {
return Object.keys(this.A);
},
/* add child AST node(s) */
add: function () {
if (arguments.length === 0)
throw new Error("add: missing argument(s)");
var _add = function (C, node) {
if (!((typeof node === "object") &&
(typeof node.T === "string") &&
(typeof node.P === "object") &&
(typeof node.A === "object") &&
(typeof node.C === "object" && node.C instanceof Array)))
throw new Error("add: invalid AST node: " + JSON.stringify(node));
C.push(node);
};
var self = this;
Array.prototype.slice.call(arguments, 0).forEach(function (arg) {
if (typeof arg === "object" && arg instanceof Array)
arg.forEach(function (child) { _add(self.C, child); });
else if (arg !== null)
_add(self.C, arg);
});
return this;
},
/* delete child AST node(s) */
del: function () {
if (arguments.length === 0)
throw new Error("del: invalid argument");
var self = this;
Array.prototype.slice.call(arguments, 0).forEach(function (arg) {
var found = false;
for (var j = 0; j < self.C.length; j++) {
if (self.C[j] === arg) {
self.C.splice(j, 1);
found = true;
break;
}
}
if (!found)
throw new Error("del: child not found");
});
return this;
},
/* get child AST nodes */
childs: function () {
return this.C;
},
/* walk the AST recursively */
walk: function (cb, when) {
if (typeof when === "undefined")
when = "before";
var _walk = function (node, depth) {
if (when === "before" || when === "both")
cb.call(null, node, depth, "before");
node.C.forEach(function (child) { _walk(child, depth + 1); });
if (when === "after" || when === "both")
cb.call(null, node, depth, "after");
};
_walk(this, 0);
return this;
},
/* dump the AST recursively */
dump: function () {
var out = "";
this.walk(function (node, depth /*, when */) {
for (var i = 0; i < depth; i++)
out += " ";
out += node.T + " ";
var keys = Object.keys(node.A);
if (keys.length > 0) {
out += "(";
var first = true;
keys.forEach(function (key) {
if (!first)
out += ", ";
else
first = false;
out += key + ": ";
var value = node.A[key];
switch (typeof value) {
case "string":
out += "\"" + value.replace(/\n/, "\\n").replace(/"/, "\\\"") + "\"";
break;
case "object":
if (value instanceof RegExp)
out += "/" +
value.toString()
.replace(/^\//, "")
.replace(/\/$/, "")
.replace(/\//g, "\\/") +
"/";
else
out += JSON.stringify(value);
break;
default:
out += JSON.stringify(value);
break;
}
});
out += ") ";
}
out += "[" + node.P.L + "/" + node.P.C + "]\n";
}, "before");
return out;
}
};
/* helper function for generating a function to unroll the parse stack */

@@ -259,3 +62,3 @@ PEGUtil.makeUnroll = function (line, column, offset, SyntaxError) {

|| !(list instanceof Array))
throw new SyntaxError("invalid list argument for unrolling",
throw new SyntaxError("unroll: invalid list argument for unrolling",
(typeof list), "Array", offset(), line(), column());

@@ -282,9 +85,2 @@ if (typeof take !== "undefined") {

/* helper function for generating a function to generate an AST node */
PEGUtil.makeAST = function (line, column, offset) {
return function (T, A, C) {
return new PEGUtil.AST(T, A, C).pos(line(), column(), offset());
};
};
/* utility function: create a source excerpt */

@@ -291,0 +87,0 @@ var excerpt = function (txt, o) {

@@ -75,5 +75,9 @@

var fs = require("fs")
var ASTY = require("asty")
var PEG = require("pegjs")
var PEGUtil = require("pegjs-util")
PEGUtil.makeAST.cb(function (line, column, offset, args) {
return ASTY.apply(null, args).pos(line, column, offset)
})
var parser = PEG.buildParser(fs.readFileSync("sample.pegjs", "utf8"))

@@ -108,4 +112,4 @@ var result = PEGUtil.parse(parser, fs.readFileSync(process.argv[2], "utf8"), "start")

ERROR: Parsing Failure:
ERROR: line 2 (col 16): */\nfoo, bar, quux baz\n
ERROR: --------------------------------------^
ERROR: line 2 (column 16): */\nfoo, bar, quux baz\n
ERROR: -----------------------------------------^
ERROR: Expected "," or end of input but "b" found.

@@ -166,3 +170,3 @@ ```

be the generation of an Abstract Syntax Tree (AST) node.
For this PEGUtil provides you a simple AST implementation.
For this libraries like e.g. [ASTy](http://github.com/rse/asty) can be used.

@@ -188,62 +192,22 @@ ```

The `options.util` above again points to the PEGUtil API and is made available
automatically by using `PEGUtil.parse` instead of PEG.js's standard
parser method `parse`.
Additionally, before performing the parsing step, your
application has to tell PEGUtil how to map this call
onto the underlying AST implementation. For [ASTy](http://github.com/rse/asty) you
can use:
The `ast` function has the following signature:
```js
PEGUtil.makeAST.cb(function (line, column, offset, args) {
return ASTY.apply(null, args).pos(line, column, offset)
})
```
ast(type: String): Node
```
Each AST Node has the following methods:
The `args` argument is an array containing all arguments
you supply to the generated `ast()` function. For
[ASTy](http://github.com/rse/asty) this would be
at least the type of the AST node.
- `Node#merge(node: Node, takePos?: Boolean, attrMap?: ([from: String]: [to: (String|null)])): Node`:<br/>
Merge attributes, childs and optionally the position of a node.
The attributes can be renamed or skipped (if mapped onto `null`).
The `options.util` above again points to the PEGUtil API and is made available
automatically by using `PEGUtil.parse` instead of PEG.js's standard
parser method `parse`.
- `Node#type(type: String): Boolean`:<br/>
`Node#type(): String`:<br/>
Set or get type of node.
- `Node#pos(line: Number, column: Number, offset: Number): Node`:<br/>
`Node#pos(): Object`:<br/>
Set or get the position for the node. This is done automatically
in the function which is generated by `PEGUtil.makeAST`.
- `Node#set(name: String, value: Object): Node`:<br/>
Set a single attribute `name` to `value`.
- `Node#set({ [name: String]: [value: Object] }): Node`:<br/>
Set multiple attributes, each consisting of name and value pairs.
- `Node#get(name: String): Object`:<br/>
Get value of attribute `name`.
- `Node#attrs(): String[]:<br/>
Get names of all node attributes.
- `Node#add(childs: Node[]): Node`:<br/>
Add one or more childs to a node. The array `childs`
can either contain `Node` objects or even arrays
of `Node` objects.
- `Node#del(childs: Node[]): Node`:<br/>
Delete one or more childs from a node.
- `Node#childs(): Node[]`:<br/>
Get a nodes list of childs.
- `Node#walk(callback: (node: Node, depth: Number, whenNow: String) => Void, when?: String): Node`:<br/>
Recursively walk the AST starting at this node (at depth 0). For each
visited node the `callback` function is called with the current node
and the tree depth. By default (and if `when` is either `before` or
`both`), the callback is called before(!) all child nodes are visited
and with `whenNow` set to `before`. If `when` is set to `after` or
`both`, the callback is called after(!) all child nodes are visited
ande with `whenNow` set to `after`.
- `Node#dump(): String`:<br/>
Returns a textual dump of the AST starting at the current node.
### Cooked Error Reporting

@@ -250,0 +214,0 @@

var fs = require("fs")
var ASTY = require("asty")
var PEG = require("pegjs")
var PEGUtil = require("./PEGUtil")
PEGUtil.makeAST.cb(function (line, column, offset, args) {
return ASTY.apply(null, args).pos(line, column, offset)
})
var parser = PEG.buildParser(fs.readFileSync("sample.pegjs", "utf8"))

@@ -6,0 +10,0 @@ var result = PEGUtil.parse(parser, fs.readFileSync(process.argv[2], "utf8"), "start")

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc