Parse.hh
Go to the documentation of this file.
1 //
2 // Copyright (c) 2020 Fraunhofer Institute for Applied Information Technology (FIT)
3 // Network Research Group (NET)
4 // Schloss Birlinghoven, 53754 Sankt Augustin, GERMANY
5 // Contact: support@wiback.org
6 //
7 // This file is part of the SENF code tree.
8 // It is licensed under the 3-clause BSD License (aka New BSD License).
9 // See LICENSE.txt in the top level directory for details or visit
10 // https://opensource.org/licenses/BSD-3-Clause
11 //
12 
13 
17 #ifndef HH_SENF_Utils_Console_Parse_
18 #define HH_SENF_Utils_Console_Parse_ 1
19 
183 // Custom includes
184 #include <string>
185 #include <vector>
186 #include <boost/noncopyable.hpp>
187 #include <boost/scoped_ptr.hpp>
188 #include <boost/range/iterator_range.hpp>
189 #include <boost/iterator/iterator_facade.hpp>
190 #include <boost/function.hpp>
191 #include <senf/Utils/safe_bool.hh>
192 #include <senf/Utils/Exception.hh>
193 
194 //#include "Parse.mpp"
195 //-/////////////////////////////////////////////////////////////////////////////////////////////////
196 
197 namespace senf {
198 namespace console {
199 
200  template <class Type>
202  template <class Type>
204 
205  namespace detail {
206  struct FilePositionWithIndex;
207  struct ParserAccess;
208  template <class ParameterType>
209  struct ArgumentInfo;
210  template<class Collection, class Adder>
212  template <class Collection>
214  }
215 
216 # define SENF_CONSOLE_PARSE_FRIEND( type ) \
217  friend void senf_console_parse_argument(senf::console::ParseCommandInfo::TokensRange const &, type &); \
218  friend struct senf::console::detail::ArgumentInfo<type>; \
219  friend struct senf::console::ArgumentTraits<type>; \
220  friend struct senf::console::ReturnValueTraits<type>; \
221  template<class Collection, class Adder> \
222  friend struct senf::console::detail::CollectionArgumentTraits; \
223  template <class Collection> \
224  friend struct senf::console::detail::MapArgumentTraits;
225 
226 
234  class Token
235  {
236  public:
237  enum TokenType {
238  None = 0,
239  PathSeparator = 0x0001, // '/'
240  ArgumentGroupOpen = 0x0002, // '('
241  ArgumentGroupClose = 0x0004, // ')'
242  DirectoryGroupOpen = 0x0008, // '{'
243  DirectoryGroupClose = 0x0010, // '}'
244  CommandTerminator = 0x0020, // ';'
245  OtherPunctuation = 0x0040,
246  BasicString = 0x0080,
247  HexString = 0x0100,
248  Word = 0x0200
249  };
250 
251  enum TokenGroup {
252  ArgumentGrouper = ArgumentGroupOpen
253  | ArgumentGroupClose,
254 
255  DirectoryGrouper = DirectoryGroupOpen
256  | DirectoryGroupClose,
257 
258  Punctuation = DirectoryGroupOpen
259  | DirectoryGroupClose
260  | PathSeparator
261  | CommandTerminator
262  | OtherPunctuation,
263 
264  String = BasicString
265  | HexString,
266 
267  SimpleArgument = Word
268  | BasicString
269  | HexString
270  };
271 
272  Token();
273  Token(TokenType type, std::string token);
275  Token(TokenType type, std::string token, detail::FilePositionWithIndex const & pos);
277 
278 
279  std::string const & value() const;
280 
282  TokenType type() const;
283 
284  unsigned line() const;
285  unsigned column() const;
286  unsigned index() const;
287 
288  bool is(unsigned tokens) const;
289 
291  bool operator==(Token const & other) const;
292  bool operator!=(Token const & other) const;
293 
294  protected:
295 
296  private:
297  TokenType type_;
298  std::string token_;
299  unsigned line_;
300  unsigned column_;
301  unsigned index_;
302  };
303 
304  std::ostream & operator<<(std::ostream & os, Token const & token);
305 
308  Token NoneToken();
309 
312  Token PathSeparatorToken();
313 
316  Token ArgumentGroupOpenToken();
317 
320  Token ArgumentGroupCloseToken();
321 
324  Token DirectoryGroupOpenToken();
325 
328  Token DirectoryGroupCloseToken();
329 
332  Token CommandTerminatorToken();
333 
336  Token OtherPunctuationToken(std::string const & value);
337 
340  Token BasicStringToken(std::string const & value);
341 
344  Token HexStringToken(std::string const & value);
345 
348  Token WordToken(std::string const & value);
349 
364  {
365  typedef std::vector<Token> Tokens;
366  typedef std::vector<std::string> CommandPath;
367 
368  public:
370 
371  typedef CommandPath::const_iterator path_iterator;
372  typedef Tokens::const_iterator token_iterator;
374  typedef Tokens::size_type size_type;
375 
376  typedef boost::iterator_range<path_iterator> CommandPathRange;
377  typedef boost::iterator_range<argument_iterator> ArgumentsRange;
378  typedef boost::iterator_range<token_iterator> TokensRange;
379 
389  BuiltinECHO };
390 
392 
393  BuiltinCommand builtin() const;
394 
396  TokensRange commandPath() const;
397 
403  ArgumentsRange arguments() const;
404 
406  TokensRange tokens() const;
407 
410  void clear();
411  bool empty();
412 
413  void builtin(BuiltinCommand builtin);
414  void command(std::vector<Token> & commandPath);
415 
416  void addToken(Token const & token);
417 
422  protected:
423 
424  private:
425  struct MakeRange;
426 
427  std::vector<Token> commandPath_;
428  BuiltinCommand builtin_;
429  Tokens tokens_;
430  };
431 
443  : public boost::iterator_facade< ParseCommandInfo::ArgumentIterator,
444  ParseCommandInfo::TokensRange,
445  boost::bidirectional_traversal_tag,
446  ParseCommandInfo::TokensRange >
447  {
448  public:
450  explicit ArgumentIterator(ParseCommandInfo::TokensRange::iterator i);
451 
452  private:
453  reference dereference() const;
454  bool equal(ArgumentIterator const & other) const;
455  void increment();
456  void decrement();
457 
458  mutable ParseCommandInfo::TokensRange::iterator b_;
459  mutable ParseCommandInfo::TokensRange::iterator e_;
460 
461  void setRange() const;
462 
463  friend class boost::iterator_core_access;
464  friend class ParseCommandInfo;
465  };
466 
473  { explicit SyntaxErrorException(std::string const & msg = "syntax error")
474  : senf::Exception(msg) {} };
475 
509  : boost::noncopyable,
510  public boost::iterator_facade< CheckedArgumentIteratorWrapper,
511  ParseCommandInfo::TokensRange,
512  boost::forward_traversal_tag,
513  ParseCommandInfo::TokensRange >,
514  public senf::safe_bool<CheckedArgumentIteratorWrapper>
515 
516  {
517  typedef boost::iterator_facade< CheckedArgumentIteratorWrapper,
519  boost::forward_traversal_tag,
520  ParseCommandInfo::TokensRange > IteratorFacade;
521 
522  public:
523  explicit CheckedArgumentIteratorWrapper(
524  ParseCommandInfo::ArgumentsRange const & range,
525  std::string const & msg = "invalid number of arguments");
527 
531  explicit CheckedArgumentIteratorWrapper(
532  ParseCommandInfo::TokensRange const & range,
533  std::string const & msg = "invalid number of arguments");
535 
542  ~CheckedArgumentIteratorWrapper() noexcept(false);
544 
554 
555  bool boolean_test() const;
556  bool done() const;
557 
558  void clear();
559 
563  bool operator==(ParseCommandInfo::ArgumentIterator const & other) const;
565  bool operator!=(ParseCommandInfo::ArgumentIterator const & other) const;
567 
568  using IteratorFacade::operator++;
569  ParseCommandInfo::ArgumentIterator operator++(int);
570 
571  private:
572  reference dereference() const;
573  void increment();
574 
577  std::string msg_;
578 
579  friend class boost::iterator_core_access;
580  };
581 
585  std::ostream & operator<<(std::ostream & stream, ParseCommandInfo const & info);
586 
603  : boost::noncopyable
604  {
605  public:
606  //-////////////////////////////////////////////////////////////////////////
607  // Types
608 
609  typedef boost::function<void (ParseCommandInfo const &)> Callback;
610 
611  //-////////////////////////////////////////////////////////////////////////
613  //\{
614 
615  CommandParser();
616  ~CommandParser();
617 
618  //\}
619  //-////////////////////////////////////////////////////////////////////////
620 
621  void parse(std::string const & command, Callback cb);
622  void parseFile(std::string const & filename, Callback cb);
623 
626  void parseArguments(std::string const & arguments, ParseCommandInfo & info);
628 
633  void parsePath(std::string const & path, ParseCommandInfo & info);
635 
638  std::string::size_type parseIncremental(std::string const & commands, Callback cb);
640 
649  static bool isSpecialChar(char ch);
650  static bool isPunctuationChar(char ch);
651  static bool isSpaceChar(char ch);
652  static bool isInvalidChar(char ch);
653  static bool isWordChar(char ch);
654 
657  { explicit ParserErrorException(std::string const & msg) : SyntaxErrorException(msg) {} };
658 
659  private:
660  struct Impl;
661  struct SetIncremental;
662 
663  template <class Iterator>
664  Iterator parseLoop(Iterator b, Iterator e, std::string const & source, Callback cb);
665 
666  Impl & impl();
667 
668  boost::scoped_ptr<Impl> impl_;
669 
670  friend struct SetIncremental;
671  };
672 
673 }}
674 
675 //-/////////////////////////////////////////////////////////////////////////////////////////////////
676 #include "Parse.cci"
677 //#include "Parse.ct"
678 //#include "Parse.cti"
679 #endif
680 
681 
682 // Local Variables:
683 // mode: c++
684 // fill-column: 100
685 // comment-column: 40
686 // c-file-style: "senf"
687 // indent-tabs-mode: nil
688 // ispell-local-dictionary: "american"
689 // compile-command: "scons -u test"
690 // End:
Exception thrown when the parser detects an error.
Definition: Parse.hh:656
bool empty()
boost::iterator_range< argument_iterator > ArgumentsRange
Definition: Parse.hh:377
Parse commands.
Definition: Parse.hh:602
u8 type
Tokens::size_type size_type
Definition: Parse.hh:374
Tokens::const_iterator token_iterator
Definition: Parse.hh:372
boost::function< void(ParseCommandInfo const &)> Callback
Definition: Parse.hh:609
Iterator parsing argument groups.
Definition: Parse.hh:442
Syntax error parsing command arguments exception.
Definition: Parse.hh:472
boost::iterator_range< path_iterator > CommandPathRange
Definition: Parse.hh:376
Customize return value formating.
Definition: Parse.hh:203
Definition: Config.hh:28
bool operator==(ArrayValueParserBase< Parser, ValueType > const &parser, ValueType const &value)
ParserErrorException(std::string const &msg)
Definition: Parse.hh:657
std::ostream & operator<<(std::ostream &os, Token const &token)
Definition: Parse.cc:129
Single parsed console command.
Definition: Parse.hh:363
Wrapper checking argument iterator access for validityOutput ParseCommandInfo instance.
Definition: Parse.hh:508
void parse(ParseCommandInfo::TokensRange const &tokens, Type &out)
Parse token range.
SyntaxErrorException(std::string const &msg="syntax error")
Definition: Parse.hh:473
bool operator!=(ArrayValueParserBase< Parser, ValueType > const &parser, ValueType const &value)
boost::iterator_range< token_iterator > TokensRange
Definition: Parse.hh:378
ArgumentIterator argument_iterator
Definition: Parse.hh:373
CommandPath::const_iterator path_iterator
Definition: Parse.hh:369
Customize argument parsing.
Definition: Parse.hh:201
::phoenix::function< detail::clear > const clear
Single argument token.
Definition: Parse.hh:234