8684f800e8a2898817f89e3a7199a97774a99c52
[senf.git] / Console / Parse.hh
1 // $Id$
2 //
3 // Copyright (C) 2008 
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief Parse public header */
25
26 #ifndef HH_Parse_
27 #define HH_Parse_ 1
28
29 // Custom includes
30 #include <string>
31 #include <vector>
32 #include <boost/utility.hpp>
33 #include <boost/scoped_ptr.hpp>
34 #include <boost/range/iterator_range.hpp>
35 #include <boost/function.hpp>
36
37 //#include "Parse.mpp"
38 ///////////////////////////////hh.p////////////////////////////////////////
39
40 namespace senf {
41 namespace console {
42
43     namespace detail { struct ParserAccess; }
44
45     /** \brief Single argument token
46
47         All command arguments are split into tokens by the parser. Each token is returned as an
48         ArgumentToken instance. 
49       */
50     class ArgumentToken
51     {
52     public:
53         std::string const & value() const; ///< String value of token
54                                         /**< This value is properly unquoted */
55
56     protected:
57
58     private:
59         explicit ArgumentToken(std::string token);
60
61         std::string token_;
62
63         friend class detail::ParserAccess;
64     };
65
66     /** \brief Console command
67
68         Every command parsed is returned in a ParseCommandInfo instance. This information is purely
69         taken from the parser, no semantic information is attached at this point, the config/console
70         is not involved in any why. ParseCommandInfo consist of
71         
72         \li the type of command: builtin or normal command represented by a possibly relative path
73             into the command tree.
74         \li the command
75         \li the arguments. Every argument consists of a range of ArgumentToken instances.
76       */
77     class ParseCommandInfo
78     {
79         typedef std::vector<ArgumentToken> Tokens;
80         typedef std::vector<std::string> CommandPath;
81         
82     public:
83         typedef CommandPath::const_iterator path_iterator;
84         typedef Tokens::const_iterator token_iterator;
85         typedef boost::iterator_range<token_iterator> argument_value_type;
86
87
88     private:
89         typedef std::vector<argument_value_type> Arguments;
90
91     public:
92         typedef Arguments::const_iterator argument_iterator;
93         typedef Arguments::size_type size_type;
94
95         typedef boost::iterator_range<path_iterator> CommandPathRange;
96         typedef boost::iterator_range<argument_iterator> ArgumentsRange;
97         typedef boost::iterator_range<token_iterator> TokensRange;
98
99         enum BuiltinCommand { NoBuiltin, 
100                               BuiltinCD, 
101                               BuiltinLS, 
102                               BuiltinPUSHD, 
103                               BuiltinPOPD,
104                               BuiltinEXIT,
105                               BuiltinHELP };
106
107         BuiltinCommand builtin() const; ///< Command type
108                                         /**< \returns \c NoBuiltin, if the command is an ordinary
109                                              command, otherwise the id of the builtin command */
110         CommandPathRange commandPath() const; ///< Command path
111                                         /**< This is the path to the command if it is not a builtin
112                                              command. Every element of the returned range
113                                              constitutes one path element. If the first element is
114                                              empty, the path is an absolute path, otherwise it is
115                                              relative. If the last element is an empty string, the
116                                              path ends in a '/' char. */
117         ArgumentsRange arguments() const; ///< Command arguments
118                                         /**< The returned range contains one token range for each
119                                              agument. */
120         TokensRange tokens() const;     ///< All argument tokens
121                                         /**< The returned range contains \e all argument tokens in a
122                                              single range not divided into separate arguments. */
123     protected:
124
125     private:
126         void init();
127         void setBuiltin(BuiltinCommand builtin);
128         void setCommand(std::vector<std::string> & commandPath);
129         void startArgument();
130         void endArgument();
131         void addToken(ArgumentToken const & token);
132         void finalize();
133
134         struct MakeRange;
135
136         std::vector<std::string> commandPath_;
137
138         typedef std::pair<Tokens::size_type, Tokens::size_type> TempArgumentRange;
139         typedef std::vector<TempArgumentRange> TempArguments;
140
141         BuiltinCommand builtin_;
142         Tokens tokens_;
143         Arguments arguments_;
144         TempArguments tempArguments_;
145
146         friend class detail::ParserAccess;
147     };
148
149     /**< \brief Output ParseCommandInfo instance
150          \related ParseCommandInfo
151       */
152     std::ostream & operator<<(std::ostream & stream, ParseCommandInfo const & info);
153
154     /** \brief Parse commands
155
156         This class implements a parser for the console/config language. It supports parsing strings
157         as well as files. For every parsed command, a callback function is called.
158
159         \implementation The implementation is based on Boost.Spirit. See the file \ref Parse.ih for
160             the formal language grammar.
161
162         \implementation Parsing an arbitrary iostream is not supported since arbitrary streams are
163             not seekable. If this is needed, it can however be provided using stream iterators and
164             some special iterator adaptors from Boost.Spirit. However, the amount of backtracking
165             needs to be analyzed before this is viable.
166
167         \todo Implement more detailed error reporting and error recovery.
168       */
169     class CommandParser
170         : boost::noncopyable
171     {
172     public:
173         ///////////////////////////////////////////////////////////////////////////
174         // Types
175
176         typedef boost::function<void (ParseCommandInfo const &)> Callback;
177
178         ///////////////////////////////////////////////////////////////////////////
179         ///\name Structors and default members
180         ///@{
181
182         CommandParser();
183         ~CommandParser();
184
185         ///@}
186         ///////////////////////////////////////////////////////////////////////////
187
188         bool parse(std::string command, Callback cb); ///< Parse string
189         bool parseFile(std::string filename, Callback cb); ///< Parse file
190                                         /**< \throws SystemException if the file cannot be
191                                              read. */
192
193     private:
194         struct Impl;
195
196         Impl & impl();
197
198         boost::scoped_ptr<Impl> impl_;
199     };
200
201 }}
202
203 ///////////////////////////////hh.e////////////////////////////////////////
204 #include "Parse.cci"
205 //#include "Parse.ct"
206 //#include "Parse.cti"
207 #endif
208
209 \f
210 // Local Variables:
211 // mode: c++
212 // fill-column: 100
213 // comment-column: 40
214 // c-file-style: "senf"
215 // indent-tabs-mode: nil
216 // ispell-local-dictionary: "american"
217 // compile-command: "scons -u test"
218 // End: