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; }
35 /** Generalized simple lexical analizer.
36 Use the method isOK() to check if there is still data available
37 for lexing. Use one of the the operators void* or ! to test if
38 the last reading operation was successful.
42 int readParam(LyxLex &lex) {
43 int param = 1; // default value
44 if (lex.isOK()) { // the lexer has data to read
45 int p; // temporary variable
47 if (lex) param = p; // only use the input if reading was successful
52 @see LyXRC.cpp for an example of usage.
57 Lexer(keyword_item *, int);
73 /// stream is open and end of stream is not reached
74 /// FIXME: test also if pushTok is not empty
75 /// FIXME: the method should be renamed to something like
76 /// dataAvailable(), in order to reflect the real behavior
78 /// FIXME: The next two operators should be replaced by one method
79 /// called e.g. lastReadOk(), in order to reflect the real
81 /// last read operation was successful.
82 operator void const *() const;
83 /// last read operation was not successful
84 bool operator!() const;
85 /// return true if able to open file, else false
86 bool setFile(support::FileName const & filename);
88 void setStream(std::istream & is);
90 std::istream & getStream();
91 /// Danger! Don't use it unless you know what you are doing.
92 void setLineNo(int l);
93 /// Change the character that begins a comment. Default is '#'
94 void setCommentChar(char c);
96 /// returns a lex code
99 /** Just read the next word. If esc is true remember that
100 some chars might be escaped: "\ atleast
102 bool next(bool esc = false);
104 /** Read next token. This one is almost the same as next,
105 but it will consider " as a regular character and always
106 split a word if it contains a backslash.
109 /// Push a token, that next token got from lyxlex.
110 void pushToken(std::string const &);
113 int getLineNo() const;
116 int getInteger() const;
118 bool getBool() const;
120 double getFloat() const;
122 std::string const getString() const;
125 docstring const getDocString() const;
127 /** Get a long string, ended by the tag `endtag'.
128 This string can span several lines. The first line
129 serves as a template for how many spaces the lines
130 are indented. This much white space is skipped from
131 each following line. This mechanism does not work
132 perfectly if you use tabs.
134 std::string const getLongString(std::string const & endtag);
139 /// Pushes a token list on a stack and replaces it with a new one.
140 void pushTable(keyword_item *, int);
142 /** Pops a token list into void and replaces it with the one now
147 /** Prints an error message with the corresponding line number
148 and file name. If message contains the substring `$$Token',
149 it is replaced with the value of GetString()
151 void printError(std::string const & message) const;
153 /// Prints the current token table on the supplied ostream.
154 void printTable(std::ostream &);
157 Lexer & operator>>(std::string &);
158 /// extract docstring
159 Lexer & operator>>(docstring &);
161 Lexer & operator>>(double &);
163 Lexer & operator>>(int &);
164 /// extract unsigned integer
165 Lexer & operator>>(unsigned int &);
167 Lexer & operator>>(bool &);
169 /// Quotes a string so that reading it again with Lexer::next(true)
170 /// gets the original string
171 static std::string const quoteString(std::string const &);
175 Lexer(Lexer const &);
176 void operator=(Lexer const &);
183 mutable bool lastReadOk_;
187 /** Use to enable multiple exit points.
188 This is needed to ensure that the pop is done upon exit from methods
189 with more than one exit point or that can return as a response to
193 class PushPopHelper {
196 PushPopHelper(Lexer & lexrc, keyword_item * i, int s) : lex(lexrc) {
206 /** Avoid wrong usage of PushPopHelper.
207 To avoid wrong usage:
208 PushPopHelper(...); // wrong
209 PushPopHelper pph(...); // right
211 #define PushPopHelper(x, y, z) unnamed_PushPopHelper;
212 // Tip gotten from Bobby Schmidt's column in C/C++ Users Journal