UNPKG

univac

Version:

Generate AST of lots of common programming languages using antlr4. JavaScript API and CLI tool.

184 lines 9.31 kB
"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result["default"] = mod; return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); var antlr4 = __importStar(require("antlr4")); var misc_utils_of_mine_generic_1 = require("misc-utils-of-mine-generic"); var web_tree_sitter_1 = __importDefault(require("web-tree-sitter")); var parserImpl_1 = require("./parserImpl"); var visitor_1 = require("./visitor"); var visitorTreeSitter_1 = require("./visitorTreeSitter"); function parseAstOrThrow(options) { return __awaiter(this, void 0, void 0, function () { var r; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, parseAst(options)]; case 1: r = _a.sent(); if (!r) { throw new Error('Expected to parse AST'); } return [2 /*return*/, r]; } }); }); } exports.parseAstOrThrow = parseAstOrThrow; var wasmLoaded = {}; function parseAst(options) { return __awaiter(this, void 0, void 0, function () { var input, info, ast, parseT0, postProcessingT0, parseTime, postProcessingTime, chars, lexer, tokens, filter, parser, tree, visitor, parser_1, Lang, tree_1, normalizer; return __generator(this, function (_a) { switch (_a.label) { case 0: options.debug && console.log('parseAst options', options); input = options.input; return [4 /*yield*/, parserImpl_1.getParserImpl(options.language)]; case 1: info = _a.sent(); parseT0 = Date.now(); postProcessingT0 = -1, parseTime = -1, postProcessingTime = -1; if (!(info.Parser && info.Lexer)) return [3 /*break*/, 2]; chars = new antlr4.InputStream(input); lexer = new info.Lexer(chars); tokens = new antlr4.CommonTokenStream(lexer); if (info.Filter) { filter = new info.Filter(tokens); //@ts-ignore filter.stream(); tokens.reset(); } parser = new info.Parser(tokens); options.errorListener && parser.addErrorListener(__assign({}, defaultErrorListener, options.errorListener || {})); tree = parser[info.mainRule](); parseTime = Date.now() - parseT0; postProcessingT0 = Date.now(); visitor = new visitor_1.Visitor(); visitor.options = options; tree.accept(visitor); ast = visitor.getAst(); return [3 /*break*/, 7]; case 2: if (!info.treeSitterParser) return [3 /*break*/, 6]; options.basePath = options.basePath || ''; parser_1 = wasmLoaded[options.basePath]; if (!!parser_1) return [3 /*break*/, 5]; return [4 /*yield*/, web_tree_sitter_1.default.init()]; case 3: _a.sent(); options.debug && console.log('Parser.init()'); parser_1 = new web_tree_sitter_1.default(); return [4 /*yield*/, web_tree_sitter_1.default.Language.load(misc_utils_of_mine_generic_1.pathJoin(options.basePath, info.treeSitterParser))]; case 4: Lang = _a.sent(); options.debug && console.log('load'); parser_1.setLanguage(Lang); options.debug && console.log('setLanguage'); wasmLoaded[options.basePath] = parser_1; _a.label = 5; case 5: tree_1 = parser_1.parse(input); parseTime = Date.now() - parseT0; postProcessingT0 = Date.now(); options.debug && console.log(tree_1.rootNode.toString()); normalizer = new visitorTreeSitter_1.TreeSitterVisitor(); normalizer.options = __assign({}, options, { root: tree_1.rootNode }); ast = normalizer.getAst(); return [3 /*break*/, 7]; case 6: throw new Error('Unrecognized ParseImpl returned ' + info); case 7: // common post-processing ast = removeRedundantNode(ast, info); ast = info.mutate ? info.mutate(ast, info) : ast; postProcessingTime = Date.now() - postProcessingT0; options.debug && console.log({ parseTime: parseTime, postProcessingTime: postProcessingTime }); return [2 /*return*/, ast]; } }); }); } exports.parseAst = parseAst; function removeRedundantNode(node, info) { do { } while (removeRedundantNode_(node, info) > 0); return node; } function removeRedundantNode_(node, info, parent, count) { var _a; if (count === void 0) { count = { n: 0 }; } if (parent && info.redundantTypes && info.redundantTypes(node, parent)) { var i = parent.children.findIndex(function (c) { return c === node; }); if (i !== -1) { count.n++; (_a = parent.children).splice.apply(_a, [i, 1].concat(node.children)); } } node.children.forEach(function (c) { return removeRedundantNode_(c, info, node, count); }); return count.n; } var defaultErrorListener = { syntaxError: function (recognizer, offendingSymbol, line, column, msg, e) { }, reportAmbiguity: function (recognizer, dfa, startIndex, stopIndex, exact, ambigAlts, configs) { }, reportAttemptingFullContext: function (recognizer, dfa, startIndex, stopIndex, conflictingAlts, configs) { }, reportContextSensitivity: function (recognizer, dfa, startIndex, stopIndex, conflictingAlts, configs) { } }; //# sourceMappingURL=parseAst.js.map