~verifypn-cpn/verifypn/colored

« back to all changes in this revision

Viewing changes to PetriParse/PNMLParser.cpp

  • Committer: Jonas Finnemann Jensen
  • Date: 2011-09-15 13:30:00 UTC
  • Revision ID: jopsen@gmail.com-20110915133000-wnywm1odf82emiuw
Import of sources from github

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* PeTe - Petri Engine exTremE
 
2
 * Copyright (C) 2011  Jonas Finnemann Jensen <jopsen@gmail.com>,
 
3
 *                     Thomas Søndersø Nielsen <primogens@gmail.com>,
 
4
 *                     Lars Kærlund Østergaard <larsko@gmail.com>,
 
5
 * 
 
6
 * This program is free software: you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License as published by
 
8
 * the Free Software Foundation, either version 3 of the License, or
 
9
 * (at your option) any later version.
 
10
 * 
 
11
 * This program is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 * GNU General Public License for more details.
 
15
 * 
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
18
 */
 
19
#include "PNMLParser.h"
 
20
 
 
21
#include <string>
 
22
#include <stdio.h>
 
23
#include <stdlib.h>
 
24
 
 
25
using namespace PetriEngine;
 
26
using namespace XMLSP;
 
27
using namespace std;
 
28
 
 
29
void PNMLParser::parse(const std::string& xml,
 
30
                                           AbstractPetriNetBuilder* builder){
 
31
        //Clear any left overs
 
32
        id2name.clear();
 
33
        arcs.clear();
 
34
        transitions.clear();
 
35
        inhibarcs.clear();
 
36
 
 
37
        //Set the builder
 
38
        this->builder = builder;
 
39
 
 
40
        //Parser the xml
 
41
        DOMElement* root = DOMElement::loadXML(xml);
 
42
        parseElement(root);
 
43
 
 
44
        //Create inhibitor arcs
 
45
        for(InhibitorArcIter inhb = inhibarcs.begin(); inhb != inhibarcs.end(); inhb++){
 
46
                //Check that source id exists
 
47
                if(id2name.find(inhb->source) == id2name.end()){
 
48
                        fprintf(stderr,
 
49
                                        "XML Parsing error: Inhibitor arc source with id=\"%s\" wasn't found!\n",
 
50
                                        inhb->source.c_str());
 
51
                        continue;
 
52
                }
 
53
                //Check that target id exists
 
54
                if(id2name.find(inhb->target) == id2name.end()){
 
55
                        fprintf(stderr,
 
56
                                        "XML Parsing error: Inhibitor arc target with id=\"%s\" wasn't found!\n",
 
57
                                        inhb->target.c_str());
 
58
                        continue;
 
59
                }
 
60
                //Find source and target
 
61
                NodeName source = id2name[inhb->source];
 
62
                NodeName target = id2name[inhb->target];
 
63
 
 
64
                //Find target transition
 
65
                for(TransitionIter it = transitions.begin(); it != transitions.end(); it++){
 
66
                        if(it->name == target.name){
 
67
                                if(it->cond.empty())
 
68
                                        it->cond = source.name + " == 0";
 
69
                                else
 
70
                                        it->cond = source.name + " == 0 and ( " + it->cond + " )";
 
71
                        }
 
72
                }
 
73
        }
 
74
 
 
75
        //Add all the transition
 
76
        for(TransitionIter it = transitions.begin(); it != transitions.end(); it++)
 
77
                builder->addTransition(it->name, it->cond, it->assign, it->x, it->y);
 
78
 
 
79
        //Add all the arcs
 
80
        for(ArcIter it = arcs.begin(); it != arcs.end(); it++){
 
81
                //Check that source id exists
 
82
                if(id2name.find(it->source) == id2name.end()){
 
83
                        fprintf(stderr,
 
84
                                        "XML Parsing error: Arc source with id=\"%s\" wasn't found!\n",
 
85
                                        it->source.c_str());
 
86
                        continue;
 
87
                }
 
88
                //Check that target id exists
 
89
                if(id2name.find(it->target) == id2name.end()){
 
90
                        fprintf(stderr,
 
91
                                        "XML Parsing error: Arc target with id=\"%s\" wasn't found!\n",
 
92
                                        it->target.c_str());
 
93
                        continue;
 
94
                }
 
95
                //Find source and target
 
96
                NodeName source = id2name[it->source];
 
97
                NodeName target = id2name[it->target];
 
98
 
 
99
                if(source.isPlace && !target.isPlace){
 
100
                        builder->addInputArc(source.name, target.name, it->weight);
 
101
                }else if(!source.isPlace && target.isPlace){
 
102
                        builder->addOutputArc(source.name, target.name, it->weight);
 
103
                }else{
 
104
                        fprintf(stderr,
 
105
                                        "XML Parsing error: Arc from \"%s\" to \"%s\" is neight input nor output!\n",
 
106
                                        source.name.c_str(),
 
107
                                        target.name.c_str());
 
108
                }
 
109
        }
 
110
 
 
111
        //Release DOM tree
 
112
        delete root;
 
113
 
 
114
        //Unset the builder
 
115
        this->builder = NULL;
 
116
 
 
117
        //Cleanup
 
118
        id2name.clear();
 
119
        arcs.clear();
 
120
        transitions.clear();
 
121
        inhibarcs.clear();
 
122
}
 
123
 
 
124
void PNMLParser::makePetriNet(){
 
125
        builder = NULL;
 
126
}
 
127
 
 
128
void PNMLParser::parseElement(DOMElement* element){
 
129
        DOMElements elements = element->getChilds();
 
130
        DOMElements::iterator it;
 
131
        for(it = elements.begin(); it != elements.end(); it++){
 
132
                if((*it)->getElementName() == "place"){
 
133
                        parsePlace(*it);
 
134
                }else if((*it)->getElementName() == "transition"){
 
135
                        parseTransition(*it);
 
136
                }else if((*it)->getElementName() == "arc" ||
 
137
                                 (*it)->getElementName() == "inputArc" ||
 
138
                                 (*it)->getElementName() == "outputArc"){
 
139
                        parseArc(*it);
 
140
                }else if((*it)->getElementName() == "transportArc"){
 
141
                        parseTransportArc(*it);
 
142
                }else if((*it)->getElementName() == "inhibitorArc"){
 
143
                        parseInhibitorArc(*it);
 
144
                }else if((*it)->getElementName() == "variable"){
 
145
                        parseVariable(*it);
 
146
                } else if((*it)->getElementName() == "queries"){
 
147
                        parseQueries(*it);
 
148
                }else
 
149
                        parseElement(*it);
 
150
        }
 
151
}
 
152
 
 
153
void PNMLParser::parseQueries(DOMElement* element){
 
154
        string name, query;
 
155
 
 
156
        DOMElements elements = element->getChilds();
 
157
        DOMElements::iterator it;
 
158
        for(it = elements.begin(); it != elements.end(); it++){
 
159
                name = element->getAttribute("name");
 
160
                parseValue(element,query);
 
161
                Query q;
 
162
                q.name = name;
 
163
                q.text = query;
 
164
                this->queries.push_back(q);
 
165
        }
 
166
}
 
167
 
 
168
void PNMLParser::parsePlace(DOMElement* element){
 
169
        double x = 0, y = 0;
 
170
        string name = element->getAttribute("name"),
 
171
                   id = element->getAttribute("id");
 
172
        int initialMarking = atoi(element->getAttribute("initialMarking").c_str());
 
173
 
 
174
        DOMElements elements = element->getChilds();
 
175
        DOMElements::iterator it;
 
176
        for(it = elements.begin(); it != elements.end(); it++){
 
177
                if((*it)->getElementName() == "name"){
 
178
                        parseValue(*it, name);
 
179
                }else if((*it)->getElementName() == "graphics"){
 
180
                        parsePosition(*it, x, y);
 
181
                }else if((*it)->getElementName() == "initialMarking"){
 
182
                        string text;
 
183
                        parseValue(*it, text);
 
184
                        initialMarking = atoi(text.c_str());
 
185
                }
 
186
        }
 
187
        //Create place
 
188
        builder->addPlace(name, initialMarking, x, y);
 
189
        //Map id to name
 
190
        NodeName nn;
 
191
        nn.name = name;
 
192
        nn.isPlace = true;
 
193
        id2name[id] = nn;
 
194
}
 
195
 
 
196
void PNMLParser::parseTransportArc(DOMElement* element){
 
197
        string source           = element->getAttribute("source"),
 
198
                   transiton    = element->getAttribute("transition"),
 
199
                   target               = element->getAttribute("target");
 
200
        int weight = 1;
 
201
 
 
202
        Arc inArc;
 
203
        inArc.source = source;
 
204
        inArc.target = transiton;
 
205
        inArc.weight = weight;
 
206
        arcs.push_back(inArc);
 
207
 
 
208
        Arc outArc;
 
209
        outArc.source = transiton;
 
210
        outArc.target = target;
 
211
        outArc.weight = weight;
 
212
        arcs.push_back(outArc);
 
213
}
 
214
 
 
215
void PNMLParser::parseInhibitorArc(DOMElement* element){
 
216
        InhibitorArc arc;
 
217
        arc.source = element->getAttribute("source");
 
218
        arc.target = element->getAttribute("target");
 
219
 
 
220
        inhibarcs.push_back(arc);
 
221
}
 
222
 
 
223
void PNMLParser::parseArc(DOMElement* element){
 
224
        string source = element->getAttribute("source"),
 
225
                   target = element->getAttribute("target");
 
226
        int weight = 1;
 
227
 
 
228
        DOMElements elements = element->getChilds();
 
229
        DOMElements::iterator it;
 
230
        for(it = elements.begin(); it != elements.end(); it++){
 
231
                if((*it)->getElementName() == "inscription"){
 
232
                        string text;
 
233
                        parseValue(*it, text);
 
234
                        weight = atoi(text.c_str());
 
235
                }
 
236
        }
 
237
 
 
238
        Arc arc;
 
239
        arc.source = source;
 
240
        arc.target = target;
 
241
        arc.weight = weight;
 
242
        arcs.push_back(arc);
 
243
}
 
244
 
 
245
void PNMLParser::parseTransition(DOMElement* element){
 
246
        Transition t;
 
247
        t.x = 0; t.y = 0;
 
248
        t.name = element->getAttribute("name");
 
249
        string id = element->getAttribute("id");
 
250
 
 
251
        DOMElements elements = element->getChilds();
 
252
        DOMElements::iterator it;
 
253
        for(it = elements.begin(); it != elements.end(); it++){
 
254
                if((*it)->getElementName() == "name"){
 
255
                        parseValue(*it, t.name);
 
256
                }else if((*it)->getElementName() == "graphics"){
 
257
                        parsePosition(*it, t.x, t.y);
 
258
                }else if((*it)->getElementName() == "conditions"){
 
259
                        t.cond = (*it)->getCData();
 
260
                }else if((*it)->getElementName() == "assignments"){
 
261
                        t.assign = (*it)->getCData();
 
262
                }
 
263
        }
 
264
        //Add transition to list
 
265
        transitions.push_back(t);
 
266
        //Map id to name
 
267
        NodeName nn;
 
268
        nn.name = t.name;
 
269
        nn.isPlace = false;
 
270
        id2name[id] = nn;
 
271
}
 
272
 
 
273
void PNMLParser::parseVariable(DOMElement* element){
 
274
        string name = element->getAttribute("name");
 
275
        int initialValue = atoi(element->getAttribute("initial-value").c_str());
 
276
        int range = atoi(element->getAttribute("range").c_str());
 
277
 
 
278
        //Add the variable
 
279
        builder->addVariable(name, initialValue, range);
 
280
}
 
281
 
 
282
 
 
283
void PNMLParser::parseValue(DOMElement* element, string& text){
 
284
        DOMElements elements = element->getChilds();
 
285
        DOMElements::iterator it;
 
286
        for(it = elements.begin(); it != elements.end(); it++){
 
287
                if((*it)->getElementName() == "value" || (*it)->getElementName() == "text")
 
288
                        text = (*it)->getCData();
 
289
                else
 
290
                        parseValue(*it, text);
 
291
        }
 
292
}
 
293
 
 
294
void PNMLParser::parsePosition(DOMElement* element, double& x, double& y){
 
295
        DOMElements elements = element->getChilds();
 
296
        DOMElements::iterator it;
 
297
        for(it = elements.begin(); it != elements.end(); it++){
 
298
                if((*it)->getElementName() == "position"){
 
299
                        x = atof((*it)->getAttribute("x").c_str());
 
300
                        y = atof((*it)->getAttribute("y").c_str());
 
301
                }else
 
302
                        parsePosition(*it, x, y);
 
303
        }
 
304
}