Milo  0.1
Milo:EquationManipulationProgram
xml.h
Go to the documentation of this file.
1 #ifndef __XML_H
2 #define __XML_H
3 
4 /* Copyright (C) 2015 - James Terman
5  *
6  * milo is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * milo 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 GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
33 #include <iostream>
34 #include <vector>
35 #include <unordered_map>
36 #include <stack>
37 #include <regex>
38 
44 namespace XML {
60  enum State { HEADER=1, HEADER_END=2, FOOTER=4, ATOM_END=8, NAME_VALUE=16,
61  ELEMENT=32, NEW=64, ILLEGAL=128, FINISH=256 };
62 
68  class FSM
69  {
70  public:
75  FSM() : m_state(NEW) {}
76 
81  State getState() { return m_state; }
82 
87  const std::string& getTag() { return m_tags.top(); }
88 
95  void next(State new_state, const std::string& tag = std::string());
96 
101  bool finished() { return m_tags.empty(); }
102  private:
107  void advance(State new_state);
108 
110  std::stack<std::string> m_tags;
111 
131  const std::vector<std::array<int, 2>> transitions = {
132  { NEW, HEADER },
133  { ATOM_END|FOOTER, FOOTER|HEADER },
134  { HEADER, NAME_VALUE|HEADER_END|ATOM_END },
135  { NAME_VALUE, HEADER_END|ATOM_END|NAME_VALUE },
136  { HEADER_END, ELEMENT|HEADER },
137  { ELEMENT, FOOTER }
138  };
139  };
140 
165  class Stream
166  {
167  public:
176  Stream(std::ostream& os, const std::string& root, int step = 2, std::string sep = "\n");
177 
182  ~Stream();
183 
190  void out(State state);
191 
197  void out(const std::string& tag);
198  private:
206  enum Pending { NONE, HEADER_TAG, NAME, VALUE, ELEMENT_TAG };
207 
208  std::string m_sep;
209  std::ostream& m_os;
210  const int m_indent_step;
211  Pending m_pending = NONE;
212  std::string m_nv;
213  int m_indent = 0;
215  };
216 
221  Stream& operator<<(Stream& xml, State state);
222 
228  Stream& operator<<(Stream& xml, const std::string& tag);
229 
235  class Parser
236  {
237  public:
245  Parser(std::istream& in, const std::string& root);
246 
253  virtual ~Parser() {}
254 
262  bool check(State state, const std::string& tag = std::string());
263 
271  Parser& next(State state, const std::string& tag = std::string());
272 
277  void finish();
278 
285  const std::string& getTag() const { return m_tag; }
286 
295  bool getAttribute(const std::string& name, std::string& value);
296 
302  bool hasAttributes() { return m_attributes.size() != 0; }
303 
309  bool hasElement() { return !m_element.empty(); }
310 
316  const std::string& getElement() { return m_element; }
317 
324  void syntaxError(const std::string& msg);
325 
326  private:
327  std::vector<std::string> m_tokens;
328  unsigned int m_pos;
329 
335  std::unordered_map<std::string, std::string> m_attributes;
336 
338  std::string m_tag;
339  std::string m_element;
340 
345  bool EOL() const { return m_pos == m_tokens.size(); }
346 
352  void next();
353 
362  void tokenize(std::istream& in);
363 
370  void tokenize(std::string xml);
371 
378  void parse_attributes(const std::string& nv);
379 
387  void parse(State& state, std::string& tag);
388  };
389 
394  void escape_tag(std::string& tag);
395 
400  void unescape_tag(std::string& tag);
401 }
402 
403 #endif // __XML_H
FSM fsm
current FSM state.
Definition: xml.h:214
std::string m_tag
last heder name tag processed
Definition: xml.h:338
bool finished()
Definition: xml.h:101
Definition: xml.h:165
bool hasElement()
Definition: xml.h:309
std::vector< std::string > m_tokens
Storage for XML tokens to be processed.
Definition: xml.h:327
unsigned int m_pos
Index of current token being processed.
Definition: xml.h:328
std::unordered_map< std::string, std::string > m_attributes
Definition: xml.h:335
static void parse(const string &eqn_str)
EqnPanel class object.
Definition: milo_test.cpp:271
State getState()
Definition: xml.h:81
const int m_indent_step
Number of spaces in indention before HEADER and standalone FOOTER.
Definition: xml.h:210
State
Definition: xml.h:60
virtual ~Parser()
Definition: xml.h:253
std::string m_sep
Character to output before indention.
Definition: xml.h:208
FSM()
Definition: xml.h:75
Definition: xml.cpp:36
std::string m_element
last tag element processed
Definition: xml.h:339
std::stack< std::string > m_tags
Stack of header name tags.
Definition: xml.h:110
const std::vector< std::array< int, 2 > > transitions
Definition: xml.h:131
FSM fsm
XML finite state machine.
Definition: xml.h:337
Definition: xml.h:235
void next(State new_state, const std::string &tag=std::string())
Definition: xml.cpp:56
bool EOL() const
Definition: xml.h:345
void advance(State new_state)
Definition: xml.cpp:39
const std::string & getTag()
Definition: xml.h:87
Pending
Definition: xml.h:206
bool hasAttributes()
Definition: xml.h:302
Definition: xml.h:68
State m_state
Current state. Initialized to NEW.
Definition: xml.h:109
const std::string & getTag() const
Definition: xml.h:285
Stream & operator<<(Stream &xml, State state)
Definition: xml.cpp:188
std::ostream & m_os
Ouput character stream to write XML.
Definition: xml.h:209
const std::string & getElement()
Definition: xml.h:316
std::string m_nv
temp space for name tag value.
Definition: xml.h:212