pddl-workspace
Version:
198 lines • 10.3 kB
JavaScript
;
/* --------------------------------------------------------------------------------------------
* Copyright (c) Jan Dolejsi. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
Object.defineProperty(exports, "__esModule", { value: true });
exports.PddlProblemParser = void 0;
/* eslint-disable @typescript-eslint/no-non-null-assertion */
const ProblemParserPreProcessor_1 = require("../ProblemParserPreProcessor");
const path_1 = require("path");
const DocumentPositionResolver_1 = require("../DocumentPositionResolver");
const PddlSyntaxTree_1 = require("./PddlSyntaxTree");
const FileInfo_1 = require("../FileInfo");
const PreProcessors_1 = require("../PreProcessors");
const ProblemInfo_1 = require("../ProblemInfo");
const PddlDomainParser_1 = require("./PddlDomainParser");
const PddlTokenizer_1 = require("./PddlTokenizer");
const PddlInheritanceParser_1 = require("./PddlInheritanceParser");
const PddlConstraintsParser_1 = require("./PddlConstraintsParser");
const PddlSyntaxTreeBuilder_1 = require("./PddlSyntaxTreeBuilder");
const PddlFileParser_1 = require("./PddlFileParser");
const vscode_uri_1 = require("vscode-uri");
const MetricParser_1 = require("./MetricParser");
/**
* Planning Problem parser.
*/
class PddlProblemParser extends PddlFileParser_1.PddlFileParser {
constructor(context) {
super();
this.problemPattern = /^\s*\(define\s*\(problem\s+(\S+)\s*\)\s*\(:domain\s+([^\r\n\t\f\v \)]+)\s*\)/gi;
if (context) {
this.problemPreParser = new ProblemParserPreProcessor_1.ProblemParserPreProcessor(context);
}
}
static async parseText(problemText, fileNameOrIdentifier = vscode_uri_1.URI.parse('file:///noname'), version = -1) {
const parser = new PddlSyntaxTreeBuilder_1.PddlSyntaxTreeBuilder(problemText);
const syntaxTree = parser.getTree();
const positionResolver = new DocumentPositionResolver_1.SimpleDocumentPositionResolver(problemText);
return await new PddlProblemParser()
.tryParse(fileNameOrIdentifier, version, problemText, syntaxTree, positionResolver);
}
async tryParse(fileUri, fileVersion, fileText, syntaxTree, positionResolver) {
var _a;
let preProcessor;
if (this.problemPreParser) {
try {
preProcessor = this.problemPreParser.createPreProcessor(fileText);
const filePath = fileUri.fsPath;
const workingDirectory = (0, path_1.dirname)(filePath);
fileText = await this.problemPreParser.process(preProcessor, fileText, workingDirectory);
}
catch (ex) {
const problemInfo = new ProblemInfo_1.ProblemInfo(fileUri, fileVersion, "unknown", "unknown", PddlSyntaxTree_1.PddlSyntaxTree.EMPTY, positionResolver);
problemInfo.setText(fileText);
if (ex instanceof PreProcessors_1.PreProcessingError) {
const parsingError = ex;
problemInfo.addProblems([new FileInfo_1.ParsingProblem(parsingError.message, "error", DocumentPositionResolver_1.PddlRange.createSingleCharacterRange({ line: parsingError.line, character: parsingError.column }))]);
}
else if (ex instanceof Error) {
const line = positionResolver.resolveToPosition((preProcessor === null || preProcessor === void 0 ? void 0 : preProcessor.metaDataLineOffset) || 0).line;
problemInfo.addProblems([new FileInfo_1.ParsingProblem((_a = ex.message) !== null && _a !== void 0 ? _a : ex, "error", DocumentPositionResolver_1.PddlRange.createFullLineRange(line))]);
}
if (preProcessor) {
problemInfo.setPreParsingPreProcessor(preProcessor);
}
return problemInfo;
}
}
const pddlText = (0, FileInfo_1.stripComments)(fileText);
this.problemPattern.lastIndex = 0;
const matchGroups = this.problemPattern.exec(pddlText);
if (matchGroups) {
const problemName = matchGroups[1];
const domainName = matchGroups[2];
const problemInfo = new ProblemInfo_1.ProblemInfo(fileUri, fileVersion, problemName, domainName, syntaxTree, positionResolver);
problemInfo.setText(fileText);
this.getProblemStructure(problemInfo);
if (preProcessor) {
problemInfo.setPreParsingPreProcessor(preProcessor);
}
return problemInfo;
}
else {
return undefined;
}
}
getProblemStructure(problemInfo) {
const defineNode = problemInfo.syntaxTree.getDefineNodeOrThrow();
PddlDomainParser_1.PddlDomainParser.parseRequirements(defineNode, problemInfo);
const objectsNode = defineNode.getFirstOpenBracket(':objects');
if (objectsNode) {
const objectsText = objectsNode.getNestedNonCommentText();
problemInfo.setObjects(PddlInheritanceParser_1.PddlInheritanceParser.toTypeObjects(PddlInheritanceParser_1.PddlInheritanceParser.parseInheritance(objectsText)));
}
const initNode = defineNode.getFirstOpenBracket(':init');
if (initNode) {
const [values, supplyDemands] = this.parseInitSection(initNode);
problemInfo.setInits(values);
problemInfo.setSupplyDemands(supplyDemands);
}
const constraintsNode = defineNode.getFirstOpenBracket(':constraints');
if (constraintsNode) {
const constraints = new PddlConstraintsParser_1.PddlConstraintsParser().parseConstraints(constraintsNode);
problemInfo.setConstraints(constraints);
}
const metrics = this.parseMetrics(defineNode, problemInfo.getDocumentPositionResolver());
problemInfo.setMetrics(metrics);
}
/**
* Parses problem :init section.
* @param initNode init syntax node
*/
parseInitSection(initNode) {
const timedVariableValues = initNode.getChildren()
.filter(node => (0, PddlTokenizer_1.isOpenBracket)(node.getToken()))
.filter(node => node.getToken().tokenText.match(/\(\s*supply-demand/i) === null)
.map(bracket => this.parseInit(bracket))
.filter(init => !!init).map(init => init);
const supplyDemands = initNode.getChildrenOfType(PddlTokenizer_1.PddlTokenType.OpenBracketOperator, /\(\s*supply-demand/i)
.map(bracket => this.parseSupplyDemand(bracket))
.filter(sd => !!sd).map(sd => sd);
return [timedVariableValues, supplyDemands];
}
parseInit(bracket) {
if (bracket.getToken().tokenText === '(at') {
const tokens = bracket.getNonWhitespaceChildren()
.filter(n => n.isNotType(PddlTokenizer_1.PddlTokenType.Comment));
if (tokens.length > 1) {
const time = parseFloat(tokens[0].getText());
if (!Number.isNaN(time)) {
const variableValue = this.parseVariableValue(tokens[1]);
if (variableValue) {
return ProblemInfo_1.TimedVariableValue.from(time, variableValue);
}
}
}
}
const variableValue = this.parseVariableValue(bracket);
if (variableValue) {
return ProblemInfo_1.TimedVariableValue.from(0, variableValue);
}
return undefined;
}
parseVariableValue(node) {
var _a, _b;
if (node === undefined) {
return undefined;
}
else if (node.getToken().tokenText === '(=') {
const tokens = node.getNonWhitespaceChildren()
.filter(n => n.isNotType(PddlTokenizer_1.PddlTokenType.Comment));
if (tokens.length > 1) {
if (tokens[0].isType(PddlTokenizer_1.PddlTokenType.OpenBracket) && tokens[1].isType(PddlTokenizer_1.PddlTokenType.Other)) {
const variableName = tokens[0].getNestedText();
const value = parseFloat(tokens[1].getText());
return new ProblemInfo_1.VariableValue(variableName, value);
}
}
return undefined;
}
else if (node.getToken().tokenText === '(not') {
const nested = (_a = node.getFirstChild(PddlTokenizer_1.PddlTokenType.OpenBracket, /.*/)) !== null && _a !== void 0 ? _a : node.getFirstChild(PddlTokenizer_1.PddlTokenType.OpenBracketOperator, /.*/);
if (!nested) {
return undefined;
}
else {
return (_b = this.parseVariableValue(nested)) === null || _b === void 0 ? void 0 : _b.negate();
}
}
else if (['(forall', '(assign', '(increase', '(decrease'].includes(node.getToken().tokenText)) {
return new ProblemInfo_1.UnsupportedVariableValue(node.getText());
}
else {
if (node.getChildren().some(child => (0, PddlTokenizer_1.isOpenBracket)(child.getToken()))) {
return undefined;
}
const variableName = node.getToken().tokenText.substr(1) + node.getNestedText();
return new ProblemInfo_1.VariableValue(variableName, true);
}
}
parseSupplyDemand(node) {
const tokens = node.getNonWhitespaceChildren();
if (tokens.length > 0 && tokens[0].isType(PddlTokenizer_1.PddlTokenType.Other)) {
return new ProblemInfo_1.SupplyDemand(tokens[0].getText());
}
else {
return undefined;
}
}
parseMetrics(defineNode, positionResolver) {
return defineNode.getChildrenOfType(PddlTokenizer_1.PddlTokenType.OpenBracketOperator, new RegExp("\\(\\s*:metric$"))
.map(metricNode => new MetricParser_1.MetricParser(metricNode, positionResolver).getMetric())
.filter(metric => !!metric)
.map(metric => metric);
}
}
exports.PddlProblemParser = PddlProblemParser;
//# sourceMappingURL=PddlProblemParser.js.map