1 /** @file hexlex.h  Lexical analyzer for Hexen definition/script syntax.
2  *
3  * @authors Copyright © 2003-2017 Jaakko Keränen <jaakko.keranen@iki.fi>
4  * @authors Copyright © 2007-2013 Daniel Swanson <danij@dengine.net>
5  * @authors Copyright © 1999 Activision
6  *
7  * @par License
8  * GPL: http://www.gnu.org/licenses/gpl.html
9  *
10  * <small>This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by the
12  * Free Software Foundation; either version 2 of the License, or (at your
13  * option) any later version. This program is distributed in the hope that it
14  * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
16  * Public License for more details. You should have received a copy of the GNU
17  * General Public License along with this program; if not, write to the Free
18  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19  * 02110-1301 USA</small>
20  */
21 
22 #ifndef LIBCOMMON_HEXLEX_H
23 #define LIBCOMMON_HEXLEX_H
24 
25 #include "common.h"
26 
27 /**
28  * Lexical analyzer for Hexen definition/script syntax.
29  */
30 class HexLex
31 {
32 public:
33     /**
34      * Construct a new lexer and optionally prepare a script for parsing.
35      *
36      * @param script      If non-zero, prepare this script for parsing.
37      * @param sourcePath  If non-zero, set this as the script source path.
38      *
39      * @see parse(), setSourcePath()
40      */
41     HexLex(Str const *script = 0, Str const *sourcePath = 0);
42     ~HexLex();
43 
44     /**
45      * Prepare a new script for parsing. It is assumed that the @a script data
46      * remains available until parsing is completed (or the script is replaced).
47      *
48      * @param script  The script source to be parsed.
49      */
50     void parse(Str const *script);
51 
52     /**
53      * Change the source path used to identify the script in log messages.
54      *
55      * @param sourcePath  New source path to apply. A copy is made.
56      */
57     void setSourcePath(Str const *sourcePath = 0);
58 
59     /**
60      * Attempt to read the next token from the script. @c true is returned if a
61      * token was parsed (or the previously parsed token was @em unread); otherwise
62      * @c false is returned (e.g., the end of the script was reached).
63      */
64     bool readToken();
65 
66     /**
67      * Mark the last read token as @em unread, so that it will be re-read as the
68      * next read token.
69      */
70     void unreadToken();
71 
72     /**
73      * Returns a copy of the last read token.
74      */
75     Str const *token();
76 
77     de::ddouble readNumber();
78     Str const *readString();
79     de::Uri readUri(de::String const &defaultScheme = "");
80 
81     /**
82      * Returns the line number at the current position in the script.
83      */
84     int lineNumber() const;
85 
86 private:
87     void checkOpen();
88     bool atEnd();
89     void syntaxError(char const *message);
90 
91     Str _sourcePath;    ///< Used to identify the source in error messages.
92 
93     Str const *_script; ///< The start of the script being parsed.
94     int _readPos;       ///< Current read position.
95     int _lineNumber;
96 
97     Str _token;
98     bool _alreadyGot;
99     bool _multiline;    ///< @c true= current token spans multiple lines.
100 };
101 
102 #endif // LIBCOMMON_HEXLEX_H
103