1 /*
2 ** Copyright (c) 2010, Braden "Blzut3" Obrzut
3 ** All rights reserved.
4 **
5 ** Redistribution and use in source and binary forms, with or without
6 ** modification, are permitted provided that the following conditions are met:
7 **     * Redistributions of source code must retain the above copyright
8 **       notice, this list of conditions and the following disclaimer.
9 **     * Redistributions in binary form must reproduce the above copyright
10 **       notice, this list of conditions and the following disclaimer in the
11 **       documentation and/or other materials provided with the distribution.
12 **     * The names of its contributors may be used to endorse or promote
13 **       products derived from this software without specific prior written
14 **       permission.
15 **
16 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 ** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 ** ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
20 ** INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 ** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 ** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27 
28 #ifndef __SCANNER_H__
29 #define __SCANNER_H__
30 
31 #include "scanner_support.h"
32 
33 enum
34 {
35 	TK_Identifier,		// Ex: SomeIdentifier
36 	TK_StringConst,		// Ex: "Some String"
37 	TK_IntConst,		// Ex: 27
38 	TK_FloatConst,		// Ex: 1.5
39 	TK_BoolConst,		// Ex: true
40 	TK_AndAnd,			// &&
41 	TK_OrOr,			// ||
42 	TK_EqEq,			// ==
43 	TK_NotEq,			// !=
44 	TK_GtrEq,			// >=
45 	TK_LessEq,			// <=
46 	TK_ShiftLeft,		// <<
47 	TK_ShiftRight,		// >>
48 	TK_Increment,		// ++
49 	TK_Decrement,		// --
50 	TK_PointerMember,	// ->
51 	TK_ScopeResolution,	// ::
52 	TK_MacroConcat,		// ##
53 	TK_AddEq,			// +=
54 	TK_SubEq,			// -=
55 	TK_MulEq,			// *=
56 	TK_DivEq,			// /=
57 	TK_ModEq,			// %=
58 	TK_ShiftLeftEq,		// <<=
59 	TK_ShiftRightEq,	// >>=
60 	TK_AndEq,			// &=
61 	TK_OrEq,			// |=
62 	TK_XorEq,			// ^=
63 	TK_Ellipsis,		// ...
64 
65 	TK_NumSpecialTokens,
66 
67 	TK_NoToken = -1
68 };
69 
70 class Scanner
71 {
72 	public:
73 		struct ParserState
74 		{
75 			SCString		str;
76 			int				number;
77 			double			decimal;
78 			bool			boolean;
79 			char			token;
80 			unsigned int	tokenLine;
81 			unsigned int	tokenLinePosition;
82 			unsigned int	scanPos;
83 		};
84 
85 		enum MessageLevel
86 		{
87 			ERROR,
88 			WARNING,
89 			NOTICE
90 		};
91 
92 		Scanner(const char* data, size_t length=0);
93 		~Scanner();
94 
95 		void			CheckForMeta();
96 		void			CheckForWhitespace();
97 		bool			CheckToken(char token);
98 		void			ExpandState();
GetData()99 		const char*		GetData() const { return data; }
GetLine()100 		int				GetLine() const { return state.tokenLine; }
GetLinePos()101 		int				GetLinePos() const { return state.tokenLinePosition; }
GetPos()102 		int				GetPos() const { return logicalPosition; }
GetScanPos()103 		unsigned int	GetScanPos() const { return scanPos; }
104 		bool			GetNextString();
105 		bool			GetNextToken(bool expandState=true);
106 		void			MustGetToken(char token);
107 		void			Rewind(); /// Only can rewind one step.
108 		void			ScriptMessage(MessageLevel level, const char* error, ...) const;
SetScriptIdentifier(const SCString & ident)109 		void			SetScriptIdentifier(const SCString &ident) { scriptIdentifier = ident; }
110 		int				SkipLine();
111 		bool			TokensLeft() const;
112 		const ParserState &operator*() const { return state; }
113 		const ParserState *operator->() const { return &state; }
114 
115 		static const SCString	&Escape(SCString &str);
116 		static const SCString	Escape(const char *str);
117 		static const SCString	&Unescape(SCString &str);
118 
SetMessageHandler(void (* handler)(MessageLevel,const char *,va_list))119 		static void		SetMessageHandler(void (*handler)(MessageLevel, const char*, va_list)) { messageHander = handler; }
120 
121 
122 		ParserState		state;
123 
124 	protected:
125 		void	IncrementLine();
126 
127 	private:
128 		ParserState		nextState, prevState;
129 
130 		char*	data;
131 		size_t	length;
132 
133 		unsigned int	line;
134 		unsigned int	lineStart;
135 		unsigned int	logicalPosition;
136 		unsigned int	scanPos;
137 
138 		bool			needNext; // If checkToken returns false this will be false.
139 
140 		SCString		scriptIdentifier;
141 
142 		static void		(*messageHander)(MessageLevel, const char*, va_list);
143 };
144 
145 #endif /* __SCANNER_H__ */
146