This JavaScript parser, created using the Jison library, takes an input string and generates an indented Abstract Syntax Tree (AST) from it. The parser defines a grammar and uses a parser instance to parse the input string, resulting in an AST with a specific structure, including a root node hex_strings
and child nodes representing hex strings.
function jisonAST(name, x) { this.name = name; this.x = x; }
// return the indented AST
jisonAST.prototype.get = function(indent){
// create an indentation for level l
function indentString(l) { var r=""; for(var i=0;i<l;i++){r+=" "}; return r }
var r = indentString(indent) + "["+this.name+": ";
var rem = this.x;
if( rem.length == 1 && !(rem[0] instanceof jisonAST) ) r += "'"+rem[0]+"'";
else for( i in rem ){
if( rem[i] instanceof jisonAST ) r += "\n" + rem[i].get(indent+1);
else { r += "\n" + indentString(indent+1); r += "'"+rem[i]+"'"; }
}
return r + "]";
}
function o( s ){
r = "$ = new yy.jisonAST('"+s+"',[";
for( i = 1; i <= s.split(" ").length; i++ ){ r += "$"+i+"," }
r = r.slice(0,-1) + "]);";
return [s,r];
}
var Parser = require("jison").Parser;
// a grammar in JSON
var grammar = {
"lex": {
"rules": [
["\\s+", "/* skip whitespace */"],
["[a-f0-9]+", "return 'HEX';"]
]
},
"bnf": {
// had to add a start/end, see below
"start" : [ [ "hex_strings", "return $1" ] ],
"hex_strings" :[
o("hex_strings HEX"),
o("HEX")
]
}
};
var parser = new Parser(grammar);
// expose the AST object to Jison
parser.yy.jisonAST = jisonAST
console.log( parser.parse("adfe34bc e82a 43af").get(0) );
/*
expects
[hex_strings HEX:
[hex_strings HEX:
[HEX: 'adfe34bc']
'e82a']
'43af']
*/
// Import the required modules
const { Parser } = require("jison");
// Define the jisonAST class
class JisonAST {
/**
* Constructor for the jisonAST class.
* @param {string} name - The name of the AST node.
* @param {array} x - The children of the AST node.
*/
constructor(name, x) {
this.name = name;
this.x = x;
}
// Return the indented AST
get(indent = 0) {
// Create an indentation string for the given level
const indentString = (level) => " ".repeat(level);
let result = indentString(indent) + "[" + this.name + ": ";
// Process the children of the AST node
const processChild = (child) =>
child instanceof JisonAST
? "\n" + child.get(indent + 1)
: "\n" + indentString(indent + 1) + "'" + child + "'";
// Recursively process each child and append the result to the string
result +=
this.x.length === 1 &&!this.x[0] instanceof JisonAST
? "'" + this.x[0] + "'"
: this.x.map(processChild).join("");
return result + "]";
}
}
// Function to generate a string in the format required by Jison
const generateOString = (s) => `$ = new yy.JisonAST('${s}', [${s.split(" ").map((_, i) => `${i + 1}`).join(",")}]));`;
// Define the grammar for the parser
const grammar = {
lex: {
rules: [
["\\s+", "/* skip whitespace */"],
["[a-f0-9]+", "return 'HEX';"],
],
},
bnf: {
start: [["hex_strings", "return $1"]],
hex_strings: [generateOString("hex_strings HEX"), generateOString("HEX")],
},
};
// Create a new parser instance
const parser = new Parser(grammar);
// Expose the AST object to Jison
parser.yy.JisonAST = JisonAST;
// Test the parser
const input = "adfe34bc e82a 43af";
const result = parser.parse(input);
console.log(result.get());
/*
expects
[hex_strings HEX:
[hex_strings HEX:
[HEX: 'adfe34bc']
'e82a']
'43af']
*/
This code defines a JavaScript parser using the Jison library. It creates an Abstract Syntax Tree (AST) from a given input string and outputs the indented AST.
jisonAST
Functionfunction jisonAST(name, x) { this.name = name; this.x = x; }
Creates a new AST object with name
and x
properties.
get
MethodjisonAST.prototype.get = function(indent){
//...
}
Returns the indented AST as a string. It takes an indent
parameter, which specifies the level of indentation.
indentString
Functionfunction indentString(l) { var r=""; for(var i=0;i<l;i++){r+=" "}; return r }
Creates a string with the specified number of indentation levels (represented by spaces).
o
Functionfunction o(s){
//...
}
Generates a JSON object representing an AST node, given a string s
.
Grammar
Objectvar grammar = {
//...
}
Defines a Jison grammar in JSON format, which consists of lexical rules and BNF rules.
Parser
Objectvar parser = new Parser(grammar);
Creates a new parser instance using the grammar
object.
parse
Methodconsole.log( parser.parse("adfe34bc e82a 43af").get(0) );
Parses the input string "adfe34bc e82a 43af" and returns the indented AST as a string.
The resulting AST has the following structure:
hex_strings
(root node)
hex_strings
(child node)
HEX
(child node)e82a
(child node)43af
(child node)