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]