This code provides a utility for selecting and manipulating code structures based on a grammar and a selection descriptor, likely used in a larger code analysis or transformation tool. It parses code, allows for querying specific parts using a descriptor, and converts the selected code into a string representation.
npm run import -- "select jison tree"
var fs = require('fs');
var jison = require('jison');
var importer = require('../Core')
var {
selectDom,
evaluateDom,
treeToHtml,
htmlToTree
} = importer.import("select tree",
"tree to html",
"html to tree")
function getParser(jisonFile) {
var bnf
if(fs.existsSync(jisonFile)) {
bnf = fs.readFileSync(jisonFile, 'utf8')
} else {
bnf = importer.interpret(jisonFile).code
}
var parser = new jison.Parser(bnf)
return parser
}
function toString(ctx, subctx) {
var ast = (subctx || ctx)
if(typeof ast.ownerDocument !== 'undefined') {
ast = htmlToTree(ast)
}
//escodegen.attachComments(ast, ast.comments, ast.tokens, ast.whitespace)
return escodegen.generate(ast, {
comment: true,
tokens: true,
whitespace: true,
format: {indent: {style: ' '}, quotes: 'single'}
})
}
function selectCode(descriptor, code, language) {
if(typeof code === 'function') {
code = code.toString()
}
if(typeof code === 'string') {
if(fs.existsSync(code)) {
code = fs.readFileSync(code)
if(typeof language === 'undefined') {
language =
}
}
var parser = getParser(language)
try {
code = esprima.parse(code, {range: true, tokens: true,
comment: true, whitespace: true})
} catch(e) {
console.log(e)
throw new Error('Could not parse \n' + code)
}
}
// TODO: move this conversion to selectDom for all objects?
// No more selectTree because jsel and friends are inconsistent.
if(typeof code.evaluate === 'undefined'
&& typeof code.ownerDocument === 'undefined') {
code = selectDom('//Program', treeToHtml(code))
code.ownerDocument.toString = toString.bind(code, code)
}
return selectDom(descriptor, code)
}
module.exports = {
selectCode
}
const fs = require('fs');
const jison = require('jison');
const escodegen = require('escodegen');
const {
selectDom,
evaluateDom,
treeToHtml,
htmlToTree
} = require('../Core');
/**
* Generates a Jison parser from a given BNF file.
*
* If the BNF file exists, it reads the contents. Otherwise, it interprets the code.
*
* @param {string} jisonFile Path to the BNF file or the code to interpret.
* @returns {jison.Parser} The generated parser.
*/
function getParser(jisonFile) {
try {
const bnf = fs.existsSync(jisonFile)? fs.readFileSync(jisonFile, 'utf8') : importer.interpret(jisonFile).code;
return new jison.Parser(bnf);
} catch (e) {
throw new Error(`Failed to generate parser: ${e.message}`);
}
}
/**
* Converts an AST to a string representation.
*
* If the AST is an HTML element, it converts it to a tree first.
*
* @param {Object} ast The AST to convert.
* @param {Object} [subctx] The sub-context AST.
* @returns {string} The string representation of the AST.
*/
function toString(ctx, subctx) {
const ast = subctx || ctx;
return ast.ownerDocument? treeToHtml(ast) : escodegen.generate(ast, {
comment: true,
tokens: true,
whitespace: true,
format: { indent: { style:' '}, quotes:'single' }
});
}
/**
* Selects code based on a descriptor and a given code or function.
*
* If the code is a function, it converts it to a string. If it's a file, it reads the contents.
*
* It then parses the code using a Jison parser.
*
* If the parsed code is not an AST, it converts it to one using the `selectDom` function.
*
* @param {string} descriptor The selector for the code.
* @param {Function|string} code The code to select or a function to execute.
* @param {string} [language] The language of the code.
* @returns {Object} The selected code.
*/
function selectCode(descriptor, code, language) {
if (typeof code === 'function') {
code = code.toString();
}
if (typeof code ==='string') {
try {
const parser = getParser(language || code);
code = esprima.parse(code, { range: true, tokens: true, comment: true, whitespace: true });
return selectDom(descriptor, code);
} catch (e) {
if (e instanceof SyntaxError) {
const fileCode = fs.readFileSync(code);
return selectCode(descriptor, fileCode, code);
} else {
throw new Error(`Failed to parse code: ${e.message}`);
}
}
}
if (typeof code.evaluate === 'undefined' && typeof code.ownerDocument === 'undefined') {
return selectDom(descriptor, selectDom('//Program', treeToHtml(code)));
}
return selectDom(descriptor, code);
}
module.exports = { selectCode };
This code defines a utility for selecting and manipulating code structures, likely within a larger code analysis or transformation system.
Here's a breakdown:
Dependencies: It relies on several libraries: fs
for file system operations, jison
for parsing grammars, and importer
for accessing other functionalities.
getParser(jisonFile)
: This function takes a Jison grammar file (either a path or a string) and returns a Jison parser instance. It handles both file-based and interpreted grammars.
toString(ctx, subctx)
: This function converts an abstract syntax tree (AST) into a string representation using escodegen
. It supports comments, tokens, and whitespace formatting.
selectCode(descriptor, code, language)
: This is the core function. It takes a code snippet (string or function), a language specification, and a descriptor (likely a JSEL-like query) to select a specific part of the code.
code
, including functions, strings, and file paths.language
.selectDom
to select the desired part of the parsed code based on the descriptor
.toString
.Exports: The module exports the selectCode
function, making it available for use in other parts of the system.
In essence, this code provides a way to query and extract specific parts of code based on a grammar and a selection descriptor.