UNPKG

@informalsystems/quint

Version:

Core tool for the Quint specification language

121 lines 4.87 kB
"use strict"; /* ---------------------------------------------------------------------------------- * Copyright 2022 Informal Systems * Licensed under the Apache License, Version 2.0. * See LICENSE in the project root for license information. * --------------------------------------------------------------------------------- */ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.parseRowOrThrow = exports.parseTypeOrThrow = exports.parseType = void 0; /** * Parsing for types. To be used internally for the moment. * * @author Gabriela Moreira * * @module */ const QuintLexer_1 = require("../generated/QuintLexer"); const p = __importStar(require("../generated/QuintParser")); const ToIrListener_1 = require("../parsing/ToIrListener"); const ParseTreeWalker_1 = require("antlr4ts/tree/ParseTreeWalker"); const antlr4ts_1 = require("antlr4ts"); const idGenerator_1 = require("../idGenerator"); const either_1 = require("@sweet-monads/either"); /** * Parses a type represented as a string into an Type * * @param typeString the string to be parsed * * @returns the parsed type when the string is a valid type. * Otherwise, a list of parsing errors. */ function parseType(typeString) { const errorMessages = []; // error listener to report lexical and syntax errors const errorListener = { syntaxError: (_, offendingSymbol, line, charPositionInLine, msg) => { const len = offendingSymbol ? offendingSymbol.stopIndex - offendingSymbol.startIndex : 0; const index = offendingSymbol ? offendingSymbol.startIndex : 0; const start = { line: line - 1, col: charPositionInLine, index }; const end = { line: line - 1, col: charPositionInLine + len, index: index + len }; errorMessages.push({ explanation: msg, locs: [{ start, end }] }); }, }; // Create the lexer and parser const inputStream = antlr4ts_1.CharStreams.fromString(typeString); const lexer = new QuintLexer_1.QuintLexer(inputStream); // remove the console listener and add our listener lexer.removeErrorListeners(); lexer.addErrorListener(errorListener); const tokenStream = new antlr4ts_1.CommonTokenStream(lexer); const parser = new p.QuintParser(tokenStream); // remove the console listener and add our listener parser.removeErrorListeners(); parser.addErrorListener(errorListener); // run the parser const tree = parser.type(); if (errorMessages.length > 0) { // report the errors return (0, either_1.left)(errorMessages); } else { // walk through the AST and construct the IR const listener = new ToIrListener_1.ToIrListener('', (0, idGenerator_1.newIdGenerator)()); ParseTreeWalker_1.ParseTreeWalker.DEFAULT.walk(listener, tree); const rootType = listener.typeStack[listener.typeStack.length - 1]; if (listener.errors.length > 0) { return (0, either_1.left)(listener.errors); } else if (rootType) { return (0, either_1.right)(rootType); } else { throw new Error(`No type found in ${typeString}`); } } } exports.parseType = parseType; function parseTypeOrThrow(type) { const result = parseType(type); if (result.isRight()) { const { value } = result; return value; } else { throw new Error(`Could not parse type: ${type} `); } } exports.parseTypeOrThrow = parseTypeOrThrow; function parseRowOrThrow(row) { const result = parseType(`{ ${row} }`); if (result.isRight() && result.value.kind === 'rec') { return result.value.fields; } else { throw new Error(`Could not parse row: ${row} `); } } exports.parseRowOrThrow = parseRowOrThrow; //# sourceMappingURL=parser.js.map