#include <boost/iterator/iterator_facade.hpp>
#include <boost/function.hpp>
#include "../Utils/safe_bool.hh"
+#include "../Utils/Exception.hh"
//#include "Parse.mpp"
///////////////////////////////hh.p////////////////////////////////////////
| HexString
};
- Token();
- Token(TokenType type, std::string token);
+ Token(); ///< Create empty token
+ Token(TokenType type, std::string token); ///< Create token with given type and value
+
std::string const & value() const; ///< String value of token
/**< This value is properly unquoted */
std::ostream & operator<<(std::ostream & os, Token const & token);
+ /** \brief Create a \c None token
+ \related Token */
Token NoneToken();
+
+ /** \brief Create a \c PathSeparator ['/'] token
+ \related Token */
Token PathSeparatorToken();
+
+ /** \brief Create an \c ArgumentGroupOpen ['('] token
+ \related Token */
Token ArgumentGroupOpenToken();
+
+ /** \brief Create a \c ArgumentGroupClose [')'] token
+ \related Token */
Token ArgumentGroupCloseToken();
+
+ /** \brief Create a \c DirectoryGroupOpen ['{'] token
+ \related Token */
Token DirectoryGroupOpenToken();
+
+ /** \brief Create a \c DirectoryGroupClose ['}'] token
+ \related Token */
Token DirectoryGroupCloseToken();
+
+ /** \brief Create a \c CommandTerminator [';'] token
+ \related Token */
Token CommandTerminatorToken();
+
+ /** \brief Create a \c OtherPunctuation ['=', ','] token with the given \a value
+ \related Token */
Token OtherPunctuationToken(std::string const & value);
+
+ /** \brief Create a \c BasicString token with the given \a value
+ \related Token */
Token BasicStringToken(std::string const & value);
+
+ /** \brief Create a \c HexString token with the given \a value
+ \related Token */
Token HexStringToken(std::string const & value);
+
+ /** \brief Create a \c Word token with the given \a value
+ \related Token */
Token WordToken(std::string const & value);
/** \brief Single parsed console command
Every command parsed is returned in a ParseCommandInfo instance. This information is purely
taken from the parser, no semantic information is attached at this point, the config/console
- node tree is not involved in any why. ParseCommandInfo consist of
+ node tree is not involved in any way. ParseCommandInfo consist of
\li the type of command: built-in or normal command represented by a possibly relative path
into the command tree.
/**< The returned range contains \e all argument tokens in a
single range not divided into separate arguments. */
- void clear();
+ void clear(); ///< Clear all data members
+ bool empty(); ///< \c true, if the data is empty
- void builtin(BuiltinCommand builtin);
- void command(std::vector<Token> & commandPath);
+ void builtin(BuiltinCommand builtin); ///< Assign builtin command
+ void command(std::vector<Token> & commandPath); ///< Assign non-builtin command
- void addToken(Token const & token);
+ void addToken(Token const & token); ///< Add argument token
+ /**< You \e must ensure, that the resulting argument tokens
+ are properly nested regarding '()' groups, otherwise
+ interpreting arguments using the arguments() call will
+ crash the program. */
protected:
All errors while parsing the arguments of a command must be signaled by throwing an instance
of SyntaxErrorException. This is important, so command overloading works.
*/
- struct SyntaxErrorException : public std::exception
- {
- explicit SyntaxErrorException(std::string const & msg = "");
- virtual ~SyntaxErrorException() throw();
-
- virtual char const * what() const throw();
- std::string const & message() const;
-
- private:
- std::string message_;
- };
+ struct SyntaxErrorException : public senf::Exception
+ { explicit SyntaxErrorException(std::string const & msg = "syntax error")
+ : senf::Exception(msg) {} };
/** \brief Wrapper checking argument iterator access for validity
using IteratorFacade::operator++;
ParseCommandInfo::ArgumentIterator operator++(int);
-
+
private:
reference dereference() const;
void increment();
some special iterator adaptors from Boost.Spirit. However, the amount of backtracking
needs to be analyzed before this is viable.
- \todo Implement more detailed error reporting and error recovery.
-
\ingroup console_parser
*/
class CommandParser
///@}
///////////////////////////////////////////////////////////////////////////
- bool parse(std::string command, Callback cb); ///< Parse string
- bool parseFile(std::string filename, Callback cb); ///< Parse file
+ void parse(std::string const & command, Callback cb); ///< Parse string
+ void parseFile(std::string const & filename, Callback cb); ///< Parse file
/**< \throws SystemException if the file cannot be
read. */
- bool parseArguments(std::string arguments, ParseCommandInfo & info);
+ void parseArguments(std::string const & arguments, ParseCommandInfo & info);
+ ///< Parse \a arguments
+ /**< parseArguments() parses the string \a arguments which
+ contains arbitrary command arguments (without the name
+ of the command). The argument tokens are written into
+ \a info. */
+
+ std::string::size_type parseIncremental(std::string const & commands, Callback cb);
+ ///< Incremental parse
+ /**< An incremental parse will parse all complete statements
+ in \a commands. parseIncremental() will return the
+ number of characters successfully parsed from \a
+ commands.
+
+ \note The incremental parser \e requires all statements
+ to be terminated explicitly. This means, that the
+ last ';' is \e not optional in this case. */
+
+ /** \brief Exception thrown when the parser detects an error */
+ struct ParserErrorException : public SyntaxErrorException
+ { explicit ParserErrorException(std::string const & msg) : SyntaxErrorException(msg) {} };
private:
struct Impl;
+ struct SetIncremental;
+
+ template <class Iterator>
+ Iterator parseLoop(Iterator b, Iterator e, std::string const & source, Callback cb);
Impl & impl();
boost::scoped_ptr<Impl> impl_;
+
+ friend class SetIncremental;
};
}}