]> git.lyx.org Git - lyx.git/blob - src/Lexer.h
Fixed some lines that were too long. It compiled afterwards.
[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/docstring.h"
21
22 #include <boost/utility.hpp>
23
24 #include <iosfwd>
25
26
27 namespace lyx {
28
29 namespace support { class FileName; }
30
31 ///
32 struct keyword_item {
33         ///
34         char const * tag;
35         ///
36         int code;
37 };
38
39 /** Generalized simple lexical analizer.
40         Use the method isOK() to check if there is still data available
41         for lexing. Use one of the the operators void* or ! to test if
42         the last reading operation was successful.
43
44         Example:
45
46         int readParam(LyxLex &lex) {
47                 int param = 1; // default value
48                 if (lex.isOK()) { // the lexer has data to read
49                         int p;    // temporary variable
50                         lex >> p;
51                         if (lex) param = p; // only use the input if reading was successful
52                 }
53                 return param;
54         }
55
56     @see LyXRC.cpp for an example of usage.
57   */
58 class Lexer : boost::noncopyable {
59 public:
60         ///
61         Lexer(keyword_item *, int);
62         ///
63         ~Lexer();
64
65         /// Lex basic codes
66         enum {
67                 ///
68                 LEX_UNDEF = -1,
69                 ///
70                 LEX_FEOF  = -2,
71                 ///
72                 LEX_DATA  = -3,
73                 ///
74                 LEX_TOKEN = -4
75         };
76
77         /// stream is open and end of stream is not reached
78         /// FIXME: test also if pushTok is not empty
79         /// FIXME: the method should be renamed to something like
80         ///        dataAvailable(), in order to reflect the real behavior
81         bool isOK() const;
82         /// FIXME: The next two operators should be replaced by one method
83         ///        called e.g. lastReadOk(), in order to reflect the real
84         ///        behavior
85         /// last read operation was successful.
86         operator void const *() const;
87         /// last read operation was not successful
88         bool operator!() const;
89         /// return true if able to open file, else false
90         bool setFile(support::FileName const & filename);
91         ///
92         void setStream(std::istream & is);
93         ///
94         std::istream & getStream();
95         /// Danger! Don't use it unless you know what you are doing.
96         void setLineNo(int l);
97         /// Change the character that begins a comment. Default is '#'
98         void setCommentChar(char c);
99
100         /// returns a lex code
101         int lex();
102
103         /** Just read the next word. If esc is true remember that
104             some chars might be escaped: "\ atleast
105         */
106         bool next(bool esc = false);
107
108         /** Read next token. This one is almost the same as next,
109             but it will consider " as a regular character and always
110             split a word if it contains a backslash.
111         */
112         bool nextToken();
113         /// Push a token, that next token got from lyxlex.
114         void pushToken(std::string const &);
115
116         ///
117         int getLineNo() const;
118
119         ///
120         int getInteger() const;
121         ///
122         bool getBool() const;
123         ///
124         double getFloat() const;
125         ///
126         std::string const getString() const;
127
128         ///
129         docstring const getDocString() const;
130
131         /** Get a long string, ended by the tag `endtag'.
132             This string can span several lines. The first line
133             serves as a template for how many spaces the lines
134             are indented. This much white space is skipped from
135             each following line. This mechanism does not work
136             perfectly if you use tabs.
137         */
138         std::string const getLongString(std::string const & endtag);
139
140         ///
141         bool eatLine();
142
143         /// Pushes a token list on a stack and replaces it with a new one.
144         void pushTable(keyword_item *, int);
145
146         /** Pops a token list into void and replaces it with the one now
147             on top of the stack.
148         */
149         void popTable();
150
151         /** Prints an error message with the corresponding line number
152             and file name. If message contains the substring `$$Token',
153             it is replaced with the value of GetString()
154         */
155         void printError(std::string const & message) const;
156
157         /// Prints the current token table on the supplied ostream.
158         void printTable(std::ostream &);
159
160         /// extract string
161         Lexer & operator>>(std::string &);
162         /// extract docstring
163         Lexer & operator>>(docstring &);
164         /// extract double
165         Lexer & operator>>(double &);
166         /// extract integer
167         Lexer & operator>>(int &);
168         /// extract unsigned integer
169         Lexer & operator>>(unsigned int &);
170         /// extract bool
171         Lexer & operator>>(bool &);
172
173         /// Quotes a string so that reading it again with Lexer::next(true)
174         /// gets the original string
175         static std::string const quoteString(std::string const &);
176
177 private:
178         class Pimpl;
179         ///
180         Pimpl * pimpl_;
181         ///
182         mutable bool lastReadOk_;
183 };
184
185
186 /** Use to enable multiple exit points.
187     This is needed to ensure that the pop is done upon exit from methods
188     with more than one exit point or that can return as a response to
189     exceptions.
190     @author Lgb
191 */
192 class PushPopHelper {
193 public:
194         ///
195         PushPopHelper(Lexer & lexrc, keyword_item * i, int s) : lex(lexrc) {
196                 lex.pushTable(i, s);
197         }
198         ///
199         ~PushPopHelper() {
200                 lex.popTable();
201         }
202         ///
203         Lexer & lex;
204 };
205 /** Avoid wrong usage of PushPopHelper.
206     To avoid wrong usage:
207     PushPopHelper(...); // wrong
208     PushPopHelper pph(...); // right
209 */
210 #define PushPopHelper(x, y, z) unnamed_PushPopHelper;
211 // Tip gotten from Bobby Schmidt's column in C/C++ Users Journal
212
213
214 } // namespace lyx
215
216 #endif