@informalsystems/quint
Version:
Core tool for the Quint specification language
121 lines • 4.87 kB
JavaScript
;
/* ----------------------------------------------------------------------------------
* 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