4 * This file is part of LyX, the document processor.
5 * Licence details can be found in the file COPYING.
7 * \author Alejandro Aguilar Sierra
8 * \author Lars Gullik Bjønnes
10 * Full author contact details are available in file CREDITS.
13 // Generalized simple lexical analizer.
14 // It can be used for simple syntax parsers, like lyxrc,
15 // texclass and others to come.
20 #include "support/strfwd.h"
25 namespace support { class FileName; }
27 /** A helper structure to describe a keyword for the Lexer.
28 Usually used bundled in C style arrays and passed to the
29 Lexer using a LexerKeywordTable object.
33 /// the string to be recognized
35 /// a corresponding numerical id
40 /** Generalized simple lexical analizer.
41 Use the method isOK() to check if there is still data available
42 for lexing. Use one of the the operators void* or ! to test if
43 the last reading operation was successful.
47 int readParam(LyxLex & lex)
49 int param = 1; // default value
50 if (lex.isOK()) { // the lexer has data to read
51 int p; // temporary variable
54 param = p; // only use the input if reading was successful
59 @see LyXRC.cpp for an example of usage.
64 /// initialize Lexer with no special keywords.
66 /// initialize Lexer with a bunch of keywords
67 template<int N> Lexer(LexerKeyword (&table)[N])
68 : pimpl_(0), lastReadOk_(false) { init(table, N); }
85 /// stream is open and end of stream is not reached
86 /// FIXME: test also if pushToken is not empty
87 /// FIXME: the method should be renamed to something like
88 /// dataAvailable(), in order to reflect the real behavior
90 /// FIXME: The next two operators should be replaced by one method
91 /// called e.g. lastReadOk(), in order to reflect the real
93 /// last read operation was successful.
94 operator void const *() const;
95 /// last read operation was not successful
96 bool operator!() const;
97 /// return true if able to open file, else false
98 bool setFile(support::FileName const & filename);
100 void setStream(std::istream & is);
102 std::istream & getStream();
103 /// Danger! Don't use it unless you know what you are doing.
104 void setLineNumber(int l);
105 /// Change the character that begins a comment. Default is '#'
106 void setCommentChar(char c);
108 /// returns a lex code
111 /// Read the next string, as delimited by double quotes or
112 /// whitespace. If esc is true, then we remember that some chars
113 /// might be escaped: \" at least.
114 bool next(bool esc = false);
116 /// Read next token. This one is almost the same as next(),
117 /// but it will consider " as a regular character and always
118 /// split a word if it contains a backslash.
121 /// Puts the rest of the line in the buffer, where it will
122 /// be available via getString() or getDocString().
125 /// Push a token, that next token got from lyxlex.
126 void pushToken(std::string const &);
128 /// return the current line number
129 int lineNumber() const;
132 int getInteger() const;
134 bool getBool() const;
136 double getFloat() const;
138 std::string const getString(bool trim = false) const;
140 docstring const getDocString(bool trim = false) const;
141 /** Get a long string, ended by the tag `endtoken'. This string
142 can span several lines. The first line serves as a template
143 for what sequence of tabs and spaces make up the indentation.
144 This prefix is skipped from each following line.
146 docstring getLongString(docstring const & endtoken);
148 /// Pushes a token list on a stack and replaces it with a new one.
149 template<int N> void pushTable(LexerKeyword (&table)[N])
150 { pushTable(table, N); }
152 /** Pops a token list into void and replaces it with the one now
157 /** Prints an error message with the corresponding line number
158 and file name. If message contains the substring `$$Token',
159 it is replaced with the value of GetString()
161 void printError(std::string const & message) const;
163 /// Prints the current token table on the supplied ostream.
164 void printTable(std::ostream &);
165 /// Used to dispaly context information in case of errors.
166 void setContext(std::string const & functionName);
169 Lexer & operator>>(std::string &);
170 /// extract docstring
171 Lexer & operator>>(docstring &);
173 Lexer & operator>>(double &);
175 Lexer & operator>>(int &);
176 /// extract unsigned integer
177 Lexer & operator>>(unsigned int &);
179 Lexer & operator>>(bool &);
180 /// extract first char of the string
181 Lexer & operator>>(char &);
183 /// read and check a required token
184 Lexer & operator>>(char const * required);
185 /// check for an optional token and swallow it if present.
186 bool checkFor(char const * required);
188 /// Quotes a string so that reading it again with Lexer::next(true)
189 /// gets the original string
190 static std::string quoteString(std::string const &);
191 /// Quotes a docstring so that reading it again with Lexer::next(true)
192 /// gets the original string
193 static docstring quoteString(docstring const &);
197 Lexer(Lexer const &);
198 void operator=(Lexer const &);
201 friend class PushPopHelper;
204 void init(LexerKeyword *, int);
205 void pushTable(LexerKeyword *, int);
212 mutable bool lastReadOk_;
216 /// extract something constructable from a string, i.e. a LaTeX length
218 Lexer & operator>>(Lexer & lex, T & t)
221 t = T(lex.getString());
226 /** Use to enable multiple exit points.
227 This is needed to ensure that the pop is done upon exit from methods
228 with more than one exit point or that can return as a response to
237 PushPopHelper(Lexer & l, LexerKeyword (&table)[N])
240 lex.pushTable(table, N);
250 /** Avoid wrong usage of PushPopHelper.
251 To avoid wrong usage:
252 PushPopHelper(...); // wrong
253 PushPopHelper pph(...); // right
255 #define PushPopHelper(x, y, z) unnamed_PushPopHelper;
256 // Tip gotten from Bobby Schmidt's column in C/C++ Users Journal