pd_dotparser.cpp
Go to the documentation of this file.
1 /** @file pd_dotparser.cpp parser functions for DOT language */
2 
3 
4 /* Pushdown plugin for FAU Discrete Event Systems Library (libfaudes)
5 
6  Copyright (C) 2014 Ramon Barakat, Stefan Jacobi, Sven Schneider, Anne-Kathrin Hess
7 
8 */
9 
10 #include "pd_dotparser.h"
11 
12 namespace faudes {
13 
14 // create temporary copy of file (fileName) and
15 // annotate dot labels with '[][]' to create transitions that pop and push lambda
16 std::string RewriteDotFile(const std::string& fileName) {
17 
18  std::string::size_type pos = 0;
19 
20  //create temporary file
21  std::string tmpFileName = CreateTempFile();
22 
23  if (tmpFileName == "") {
24  std::stringstream errstr;
25  errstr << "Exception opening temp file";
26  throw Exception("pd_dotparser::RewriteDotFile", errstr.str(), 2);
27  }
28  try {
29  std::ofstream tmp;
30  tmp.open(tmpFileName.c_str());
31 
32  //open file
33  //std::fstream file(fileName);
34  std::ifstream file (fileName.c_str(), std::ios::in | std::ios::binary);
35  if (file.is_open()) {
36  std::string line = "";
37  int nr = 0;
38 
39  // parsing line by line
40  while (getline(file, line)) {
41  nr++;
42  //remove spaces
43  line.erase(std::remove_if(line.begin(), line.end(), ::isspace),
44  line.end());
45 
46  // rewrite transition
47  if (line.find("->") != std::string::npos
48  && line.find("label") != std::string::npos) {
49  pos = line.find("label");
50  std::string label = "";
51  getIde(pos, line, label, fileName, nr);
52 
53  std::string post = "\"];";
54 
55  #ifdef FAUDES_CHECKED
56  // check '[' or ']' not in ID
57  if (label.find('[') != std::string::npos
58  || label.find(']') != std::string::npos) {
59  file.close();
60  std::stringstream errstr;
61  errstr << "Transition containing '[' or ']' as part of label, which is not allowed ! Line "
62  << nr << " in " << fileName;
63  throw Exception("pd_dotparser::RewriteDotFile",
64  errstr.str(), 300);
65  }
66 
67  //check if end of line exists
68  if (line.find(post) == std::string::npos) {
69  file.close();
70  std::stringstream errstr;
71  errstr << "Can not find end of label ( ' \"]; ' ) ! Line "
72  << nr << " in " << fileName;
73  throw Exception("pd_dotparser::RewriteDotFile",
74  errstr.str(), 300);
75  }
76  #endif
77 
78  //add annotation
79  line.replace(line.find(post), post.length(),",[],[]" + post);
80  }
81 
82  //write line to temporary file
83  tmp << line << std::endl;
84  }
85 
86  //add default stack bottom
87  tmp << std::endl << "\"" << "default_stackbottom"
88  << "\" [style=\"invis\", attr=\"stackbottom\"];"
89  << std::endl;
90 
91  //close file
92  file.close();
93 
94  } else {
95  #ifdef FAUDES_CHECKED
96  std::stringstream errstr;
97  errstr << "Unable to open file : " << fileName;
98  throw Exception("pd_dotparser::RewriteDotFile", errstr.str(), 1);
99  #endif
100  }
101 
102  //close temporary file
103  tmp.close();
104  } catch (faudes::Exception& exception) {
105  //remove temporary file
106  RemoveFile(tmpFileName);
107  std::stringstream errstr;
108  errstr << "Exception writing dot input file";
109  throw Exception("pd_dotparser::RewriteDotFile", errstr.str(), 2);
110  }
111 
112  return tmpFileName;
113 }
114 
115 // parse System from *.dot
116 System SystemFromDot(const std::string& filename) {
117  FD_DF("ParseSystemFromDot(...): " << filename);
118 
119  //resulting system
120  System res;
121 
122  // generate temporary dot input file
123  std::string dotin = RewriteDotFile(filename);
124  if (dotin == "") {
125  std::stringstream errstr;
126  errstr << "Exception opening temporary file";
127  throw Exception("pd_dotparser::ParseSystemFromDot", errstr.str(), 2);
128  }
129  try {
130  //create generator
132 
133  //parse file
134  pd.DotRead(dotin);
135 
136  //get System
137  res = System(pd);
138  } catch (faudes::Exception& exception) {
139  RemoveFile(dotin);
140  std::stringstream errstr;
141  errstr << "Exception writing dot input file";
142  throw Exception("pd_dotparser::ParseSystemFromDot", errstr.str(), 2);
143  }
144 
145  //remove file
146  RemoveFile(dotin);
147 
148  return res;
149 }
150 
151 //check if lanmda replacement
152 bool IsLambdaReplacement(const std::string& s) {
153  return ((s == "_") || (s == "&lambda;") || (s == "lambda"));
154 }
155 
156 // split string by separator
157 std::vector<std::string> split(const std::string& rStr, const std::string& rSep,
158  const std::string& rFilename, const int lineNr) {
159 
160  //resulting tokens
161  std::vector<std::string> vTokens;
162 
163  if (!rStr.empty()) {
164  std::string::size_type start = 0, end = 0, curr = 0;
165 
166  std::string str = rStr;
167  std::string sub;
168 
169  //if no separator in string
170  if ((end = str.find(rSep, start)) == std::string::npos) {
171  //push whole string to result
172  vTokens.push_back(str);
173  return vTokens;
174  }
175 
176  curr = start;
177 
178  //while separator from current position exists
179  while ((end = str.find(rSep, curr)) != std::string::npos) {
180  //substring from current position to separator
181  sub = str.substr(curr, end - curr);
182 
183  //ensure that tuple (x,y) will seen as one ID
184  if (sub.find("(") != std::string::npos) {
185  end = str.find(")", curr);
186  #ifdef FAUDES_CHECKED
187  if (end == std::string::npos) {
188  std::stringstream errstr;
189  errstr << "Missing ')' in " << rFilename << " L:" << lineNr
190  << " " << rStr;
191  throw Exception("pd_dotparser::split(inp,sep)", errstr.str(),
192  200);
193  }
194  #endif
195  end++;
196 
197  //get whole tuple
198  sub = str.substr(curr, end - curr);
199  }
200 
201  //push ID to token
202  vTokens.push_back(sub);
203  //continue after separator
204  curr = end + 1;
205  }
206 
207  //add last token
208  if (curr < str.size())
209  vTokens.push_back(str.substr(curr));
210  }
211 
212  return vTokens;
213 }
214 
215 // set string literal between "..." to &resText and return the position after the second quotation.
216 std::string::size_type getIde(std::string::size_type& rPos,
217  const std::string& rInput, std::string& rRestString,
218  const std::string& rFilename, const int lineNr) {
219  std::string::size_type end_position = rPos;
220 
221  rPos = rInput.find('"', rPos);
222  if (rPos != std::string::npos) {
223  //get end position;
224  end_position = rInput.find('"', ++rPos);
225  if (end_position != std::string::npos) {
226  //get string literal
227  rRestString = rInput.substr(rPos, end_position - rPos);
228  return end_position + 1;
229  } else {
230  #ifdef FAUDES_CHECKED
231  std::stringstream errstr;
232  errstr << "Missing \" in " << rFilename << " L:" << lineNr << " "
233  << rInput << std::endl;
234  throw Exception("pd_dotparser::getIde for" + rInput.substr(rPos),
235  errstr.str(), 200);
236  #endif
237  }
238  }
239 
240  return rInput.size();
241 }
242 
243 }

libFAUDES 2.28c --- 2016.09.30 --- c++ api documentaion by doxygen