From dc8382bad54f99c1e7ce83f70defedc20cc2080e Mon Sep 17 00:00:00 2001 From: ThomasH <thomas.henn@rwth-aachen.de> Date: Wed, 21 Sep 2016 23:40:44 +0200 Subject: [PATCH] add parser for pnpro files Former-commit-id: 5b43a19ba5c4ccaaf3cea98f63736322deb9e077 --- src/parser/GspnParser.cpp | 321 +++++++++++++++++++++++++++++++++++++- src/parser/GspnParser.h | 12 ++ src/storm-gspn.cpp | 1 - 3 files changed, 330 insertions(+), 4 deletions(-) diff --git a/src/parser/GspnParser.cpp b/src/parser/GspnParser.cpp index 82d1bcf98..27000bab6 100644 --- a/src/parser/GspnParser.cpp +++ b/src/parser/GspnParser.cpp @@ -64,9 +64,19 @@ namespace storm { // build gspn by traversing the DOM object parser->getDocument()->normalizeDocument(); xercesc::DOMElement* elementRoot = parser->getDocument()->getDocumentElement(); - // If the top-level node is not a "pnml" node, then throw an exception. - STORM_LOG_THROW(getName(elementRoot).compare("pnml") == 0, storm::exceptions::UnexpectedException, "Failed to identify the root element.\n"); - traversePnmlElement(elementRoot); + + if (getName(elementRoot).compare("pnml") == 0) { + traversePnmlElement(elementRoot); + } else if (getName(elementRoot).compare("project") == 0) { + traverseProjectElement(elementRoot); + } else { + // If the top-level node is not a "pnml" or "" node, then throw an exception. + STORM_LOG_THROW(false, storm::exceptions::UnexpectedException, "Failed to identify the root element.\n"); + } + + + + // clean up delete parser; @@ -568,6 +578,311 @@ namespace storm { delete tmp; return result; } + + void GspnParser::traverseProjectElement(xercesc::DOMNode const* const node) { + // traverse attributes + for (uint_fast64_t i = 0; i < node->getAttributes()->getLength(); ++i) { + auto attr = node->getAttributes()->item(i); + auto name = getName(attr); + + if (name.compare("version") == 0 || + name.compare("name") == 0) { + // ignore node (contains only whitespace) + } else { + // Found node or attribute which is at the moment not handled by this parser. + // Notify the user and continue the parsing. + STORM_PRINT_AND_LOG("unknown attribute (node=" + XMLtoString(node->getNodeName()) + "): " + name + "\n"); + } + } + + // traverse children + for (uint_fast64_t i = 0; i < node->getChildNodes()->getLength(); ++i) { + auto child = node->getChildNodes()->item(i); + auto name = getName(child); + + if (name.compare("gspn") == 0) { + traverseGspnElement(child); + } else if (std::all_of(name.begin(), name.end(), isspace)) { + // ignore node (contains only whitespace) + } else { + // Found node or attribute which is at the moment nod handled by this parser. + // Notify the user and continue the parsing. + STORM_PRINT_AND_LOG("unknown child (node=" + XMLtoString(node->getNodeName()) + "): " + name + "\n"); + } + } + } + + void GspnParser::traverseGspnElement(xercesc::DOMNode const* const node) { + // traverse attributes + for (uint_fast64_t i = 0; i < node->getAttributes()->getLength(); ++i) { + auto attr = node->getAttributes()->item(i); + auto name = getName(attr); + + if (name.compare("name") == 0) { + gspn.setName(XMLtoString(attr->getNodeValue())); + } else if (name.compare("show-color-cmd") == 0 || + name.compare("show-fluid-cmd") == 0) { + // ignore node + } else { + // Found node or attribute which is at the moment not handled by this parser. + // Notify the user and continue the parsing. + STORM_PRINT_AND_LOG( + "unknown attribute (node=" + XMLtoString(node->getNodeName()) + "): " + name + "\n"); + } + } + + // traverse children + for (uint_fast64_t i = 0; i < node->getChildNodes()->getLength(); ++i) { + auto child = node->getChildNodes()->item(i); + auto name = getName(child); + + if (name.compare("nodes") == 0) { + traverseNodesElement(child); + } else if (name.compare("edges") == 0) { + traverseEdgesElement(child); + } else if (std::all_of(name.begin(), name.end(), isspace)) { + // ignore node (contains only whitespace) + } else { + // Found node or attribute which is at the moment nod handled by this parser. + // Notify the user and continue the parsing. + STORM_PRINT_AND_LOG("unknown child (node=" + XMLtoString(node->getNodeName()) + "): " + name + "\n"); + } + } + } + + void GspnParser::traverseNodesElement(xercesc::DOMNode const* const node) { + // traverse attributes + for (uint_fast64_t i = 0; i < node->getAttributes()->getLength(); ++i) { + auto attr = node->getAttributes()->item(i); + auto name = getName(attr); + + // Found node or attribute which is at the moment not handled by this parser. + // Notify the user and continue the parsing. + STORM_PRINT_AND_LOG("unknown attribute (node=" + XMLtoString(node->getNodeName()) + "): " + name + "\n"); + } + + // traverse children + for (uint_fast64_t i = 0; i < node->getChildNodes()->getLength(); ++i) { + auto child = node->getChildNodes()->item(i); + auto name = getName(child); + + if (name.compare("place") == 0) { + traversePlaceElement(child); + } else if(name.compare("transition") == 0) { + traverseTransitionElement(child); + } else if (std::all_of(name.begin(), name.end(), isspace)) { + // ignore node (contains only whitespace) + } else { + // Found node or attribute which is at the moment nod handled by this parser. + // Notify the user and continue the parsing. + STORM_PRINT_AND_LOG("unknown child (node=" + XMLtoString(node->getNodeName()) + "): " + name + "\n"); + } + } + } + + void GspnParser::traverseEdgesElement(xercesc::DOMNode const* const node) { + // traverse attributes + for (uint_fast64_t i = 0; i < node->getAttributes()->getLength(); ++i) { + auto attr = node->getAttributes()->item(i); + auto name = getName(attr); + + + // Found node or attribute which is at the moment not handled by this parser. + // Notify the user and continue the parsing. + STORM_PRINT_AND_LOG("unknown attribute (node=" + XMLtoString(node->getNodeName()) + "): " + name + "\n"); + + } + + // traverse children + for (uint_fast64_t i = 0; i < node->getChildNodes()->getLength(); ++i) { + auto child = node->getChildNodes()->item(i); + auto name = getName(child); + + if (name.compare("arc") == 0) { + traverseArcElement(child); + } else if (std::all_of(name.begin(), name.end(), isspace)) { + // ignore node (contains only whitespace) + } else { + // Found node or attribute which is at the moment nod handled by this parser. + // Notify the user and continue the parsing. + STORM_PRINT_AND_LOG("unknown child (node=" + XMLtoString(node->getNodeName()) + "): " + name + "\n"); + } + } + } + + void GspnParser::traversePlaceElement(xercesc::DOMNode const* const node) { + storm::gspn::Place place; + place.setID(newNode); + ++newNode; + + + // traverse attributes + for (uint_fast64_t i = 0; i < node->getAttributes()->getLength(); ++i) { + auto attr = node->getAttributes()->item(i); + auto name = getName(attr); + + if (name.compare("name") == 0) { + place.setName(XMLtoString(attr->getNodeValue())); + } else if (name.compare("marking") == 0) { + place.setNumberOfInitialTokens(std::stoull(XMLtoString(attr->getNodeValue()))); + } else if (name.compare("x") == 0 || + name.compare("y") == 0) { + // ignore node + } else { + // Found node or attribute which is at the moment not handled by this parser. + // Notify the user and continue the parsing. + STORM_PRINT_AND_LOG( + "unknown attribute (node=" + XMLtoString(node->getNodeName()) + "): " + name + "\n"); + } + } + + // traverse children + for (uint_fast64_t i = 0; i < node->getChildNodes()->getLength(); ++i) { + auto child = node->getChildNodes()->item(i); + auto name = getName(child); + + if (std::all_of(name.begin(), name.end(), isspace)) { + // ignore node (contains only whitespace) + } else { + // Found node or attribute which is at the moment nod handled by this parser. + // Notify the user and continue the parsing. + STORM_PRINT_AND_LOG("unknown child (node=" + XMLtoString(node->getNodeName()) + "): " + name + "\n"); + } + } + + gspn.addPlace(place); + } + + void GspnParser::traverseTransitionElement(xercesc::DOMNode const* const node) { + std::string transitionName; + bool immediateTransition; + double rate; + + // traverse attributes + for (uint_fast64_t i = 0; i < node->getAttributes()->getLength(); ++i) { + auto attr = node->getAttributes()->item(i); + auto name = getName(attr); + + if (name.compare("name") == 0) { + transitionName = XMLtoString(attr->getNodeValue()); + } else if (name.compare("type") == 0) { + if (XMLtoString(attr->getNodeValue()).compare("EXP") == 0) { + immediateTransition = false; + } else { + immediateTransition = true; + } + } else if(name.compare("nservers-x") == 0) { + rate = std::stod(XMLtoString(attr->getNodeValue())); + } else if (name.compare("x") == 0 || + name.compare("y") == 0) { + // ignore node + } else { + // Found node or attribute which is at the moment not handled by this parser. + // Notify the user and continue the parsing. + STORM_PRINT_AND_LOG( + "unknown attribute (node=" + XMLtoString(node->getNodeName()) + "): " + name + "\n"); + } + } + + if (immediateTransition) { + auto transition = storm::gspn::ImmediateTransition<double>(); + transition.setName(transitionName); + gspn.addImmediateTransition(transition); + } else { + auto transition = storm::gspn::TimedTransition<double>(); + transition.setName(transitionName); + transition.setRate(rate); + gspn.addTimedTransition(transition); + } + + // traverse children + for (uint_fast64_t i = 0; i < node->getChildNodes()->getLength(); ++i) { + auto child = node->getChildNodes()->item(i); + auto name = getName(child); + + if (std::all_of(name.begin(), name.end(), isspace)) { + // ignore node (contains only whitespace) + } else { + // Found node or attribute which is at the moment nod handled by this parser. + // Notify the user and continue the parsing. + STORM_PRINT_AND_LOG("unknown child (node=" + XMLtoString(node->getNodeName()) + "): " + name + "\n"); + } + } + } + + void GspnParser::traverseArcElement(xercesc::DOMNode const* const node) { + std::string head, tail, kind; + uint_fast64_t mult = 1; + + // traverse attributes + for (uint_fast64_t i = 0; i < node->getAttributes()->getLength(); ++i) { + auto attr = node->getAttributes()->item(i); + auto name = getName(attr); + + if (name.compare("head") == 0) { + head = XMLtoString(attr->getNodeValue()); + } else if (name.compare("tail") == 0) { + tail = XMLtoString(attr->getNodeValue()); + } else if (name.compare("kind") == 0) { + kind = XMLtoString(attr->getNodeValue()); + } else if (name.compare("mult") == 0) { + mult = std::stoull(XMLtoString(attr->getNodeValue())); + } else if (name.compare("mult-x") == 0 || + name.compare("mult-y") == 0 || + name.compare("mult-k") == 0) { + // ignore node + } else { + // Found node or attribute which is at the moment not handled by this parser. + // Notify the user and continue the parsing. + STORM_PRINT_AND_LOG( + "unknown attribute (node=" + XMLtoString(node->getNodeName()) + "): " + name + "\n"); + } + } + + if (kind.compare("INPUT") == 0) { + auto transition = gspn.getTransition(head); + if (!transition.first) { + std::cout << "transition not found" << std::endl; + } + auto place = gspn.getPlace(tail); + if (!place.first) { + std::cout << "place not found" << std::endl; + } + transition.second->setInputArcMultiplicity(place.second, mult); + } else if (kind.compare("INHIBITOR") == 0) { + auto transition = gspn.getTransition(head); + auto place = gspn.getPlace(tail); + transition.second->setInhibitionArcMultiplicity(place.second, mult); + } else if (kind.compare("OUTPUT") == 0) { + auto transition = gspn.getTransition(tail); + auto place = gspn.getPlace(head); + transition.second->setOutputArcMultiplicity(place.second, mult); + } else { + // TODO error! + } + + // traverse children + for (uint_fast64_t i = 0; i < node->getChildNodes()->getLength(); ++i) { + auto child = node->getChildNodes()->item(i); + auto name = getName(child); + + if (std::all_of(name.begin(), name.end(), isspace)) { + // ignore node (contains only whitespace) + } else { + // Found node or attribute which is at the moment nod handled by this parser. + // Notify the user and continue the parsing. + STORM_PRINT_AND_LOG("unknown child (node=" + XMLtoString(node->getNodeName()) + "): " + name + "\n"); + } + } + } + + + + + + + + } } diff --git a/src/parser/GspnParser.h b/src/parser/GspnParser.h index 920a99b9f..81b28c40d 100644 --- a/src/parser/GspnParser.h +++ b/src/parser/GspnParser.h @@ -132,6 +132,18 @@ namespace storm { */ static std::string XMLtoString(const XMLCh* xmlString); + + void traverseProjectElement(xercesc::DOMNode const* const node); + + void traverseGspnElement(xercesc::DOMNode const* const node); + void traverseNodesElement(xercesc::DOMNode const* const node); + void traverseEdgesElement(xercesc::DOMNode const* const node); + + void traversePlaceElement(xercesc::DOMNode const* const node); + void traverseTransitionElement(xercesc::DOMNode const* const node); + void traverseArcElement(xercesc::DOMNode const* const node); + + // the constructed gspn storm::gspn::GSPN gspn; diff --git a/src/storm-gspn.cpp b/src/storm-gspn.cpp index 1f0240b0e..83230b785 100644 --- a/src/storm-gspn.cpp +++ b/src/storm-gspn.cpp @@ -109,7 +109,6 @@ int main(const int argc, const char **argv) { // parse GSPN from file auto parser = storm::parser::GspnParser(); - std::cout << "input_file: " << inputFile << std::endl; auto gspn = parser.parse(inputFile); // todo ------[marker]