]> git.lyx.org Git - lyx.git/blob - src/Lexer.h
* lfuns doxification for math macros
[lyx.git] / src / Lexer.h
1 // -*- C++ -*-
2 /**
3  * \file Lexer.h
4  * This file is part of LyX, the document processor.
5  * Licence details can be found in the file COPYING.
6  *
7  * \author Alejandro Aguilar Sierra
8  * \author Lars Gullik Bjønnes
9  *
10  * Full author contact details are available in file CREDITS.
11  */
12
13 //  Generalized simple lexical analizer.
14 //  It can be used for simple syntax parsers, like lyxrc,
15 //  texclass and others to come.
16
17 #ifndef LEXER_H
18 #define LEXER_H
19
20 #include "support/strfwd.h"
21
22
23 namespace lyx {
24
25 namespace support { class FileName; }
26
27 ///
28 struct keyword_item {
29         ///
30         char const * tag;
31         ///
32         int code;
33 };
34
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.
39
40         Example:
41
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
46                         lex >> p;
47                         if (lex) param = p; // only use the input if reading was successful
48                 }
49                 return param;
50         }
51
52     @see LyXRC.cpp for an example of usage.
53   */
54 class Lexer {
55 public:
56         ///
57         Lexer(keyword_item *, int);
58         ///
59         ~Lexer();
60
61         /// Lex basic codes
62         enum {
63                 ///
64                 LEX_UNDEF = -1,
65                 ///
66                 LEX_FEOF  = -2,
67                 ///
68                 LEX_DATA  = -3,
69                 ///
70                 LEX_TOKEN = -4
71         };
72
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
77         bool isOK() const;
78         /// FIXME: The next two operators should be replaced by one method
79         ///        called e.g. lastReadOk(), in order to reflect the real
80         ///        behavior
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);
87         ///
88         void setStream(std::istream & is);
89         ///
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);
95
96         /// returns a lex code
97         int lex();
98
99         /** Just read the next word. If esc is true remember that
100             some chars might be escaped: "\ atleast
101         */
102         bool next(bool esc = false);
103
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.
107         */
108         bool nextToken();
109         /// Push a token, that next token got from lyxlex.
110         void pushToken(std::string const &);
111
112         ///
113         int getLineNo() const;
114
115         ///
116         int getInteger() const;
117         ///
118         bool getBool() const;
119         ///
120         double getFloat() const;
121         ///
122         std::string const getString() const;
123
124         ///
125         docstring const getDocString() const;
126
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.
133         */
134         std::string const getLongString(std::string const & endtag);
135
136         ///
137         bool eatLine();
138
139         /// Pushes a token list on a stack and replaces it with a new one.
140         void pushTable(keyword_item *, int);
141
142         /** Pops a token list into void and replaces it with the one now
143             on top of the stack.
144         */
145         void popTable();
146
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()
150         */
151         void printError(std::string const & message) const;
152
153         /// Prints the current token table on the supplied ostream.
154         void printTable(std::ostream &);
155
156         /// extract string
157         Lexer & operator>>(std::string &);
158         /// extract docstring
159         Lexer & operator>>(docstring &);
160         /// extract double
161         Lexer & operator>>(double &);
162         /// extract integer
163         Lexer & operator>>(int &);
164         /// extract unsigned integer
165         Lexer & operator>>(unsigned int &);
166         /// extract bool
167         Lexer & operator>>(bool &);
168
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 &);
172
173 private:
174         /// noncopiable
175         Lexer(Lexer const &);
176         void operator=(Lexer const &);
177
178         ///
179         class Pimpl;
180         ///
181         Pimpl * pimpl_;
182         ///
183         mutable bool lastReadOk_;
184 };
185
186
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
190     exceptions.
191     @author Lgb
192 */
193 class PushPopHelper {
194 public:
195         ///
196         PushPopHelper(Lexer & lexrc, keyword_item * i, int s) : lex(lexrc) {
197                 lex.pushTable(i, s);
198         }
199         ///
200         ~PushPopHelper() {
201                 lex.popTable();
202         }
203         ///
204         Lexer & lex;
205 };
206 /** Avoid wrong usage of PushPopHelper.
207     To avoid wrong usage:
208     PushPopHelper(...); // wrong
209     PushPopHelper pph(...); // right
210 */
211 #define PushPopHelper(x, y, z) unnamed_PushPopHelper;
212 // Tip gotten from Bobby Schmidt's column in C/C++ Users Journal
213
214
215 } // namespace lyx
216
217 #endif