ALib C++ Library
Library Version: 2402 R1
Documentation generated by doxygen
Loading...
Searching...
No Matches
parser_impl.hpp
Go to the documentation of this file.
1/** ************************************************************************************************
2 * \file
3 * This header file is part of module \alib_expressions of the \aliblong.
4 *
5 * \emoji :copyright: 2013-2024 A-Worx GmbH, Germany.
6 * Published under \ref mainpage_license "Boost Software License".
7 **************************************************************************************************/
8#ifndef HPP_ALIB_EXPRESSIONS_DETAIL_PARSER_IMPL
9#define HPP_ALIB_EXPRESSIONS_DETAIL_PARSER_IMPL
10
11#if !defined (HPP_ALIB_EXPRESSIONS_DETAIL_AST)
13#endif
14
15#if !defined (HPP_ALIB_EXPRESSIONS_DETAIL_PARSER)
17#endif
18
19#if !defined(HPP_ALIB_MONOMEM_HASHSET)
21#endif
22#if !defined (HPP_ALIB_MONOMEM_STDCONTAINERMA)
24#endif
25#if !defined (HPP_ALIB_STRINGS_SUBSTRING)
27#endif
28#if !defined(HPP_ALIB_COMPATIBILITY_STD_STRINGS_FUNCTIONAL)
30#endif
31
32#include <bitset>
33
34namespace alib { namespace expressions {
35
36class Compiler;
37class Parser;
38
39namespace detail {
40
41/** ************************************************************************************************
42 * Implementation of the default parser of module \alib_expressions_nl.
43 *
44 * This internal class is not too well documented. Nevertheless, it is designed to be able
45 * to tweak its behavior slightly and in case of need, even derive and use a custom parser
46 * class. For doing so, please consult the source code of this class.
47 * A custom parser might be set to protected field \alib{expressions;Compiler::parser}by a derived
48 * compiler type prior to compiling a first expression.
49 *
50 * It is possible to define scannable custom unary and binary operators. Definitions of binary
51 * operators include a "precedence value" that allows to align them with the built-in types.
52 * Also, built-in operators can be \em removed if wanted.
53 **************************************************************************************************/
54class ParserImpl : public Parser
55{
56 protected:
57 /** Types of tokens. */
58 enum class Tokens : char
59 {
60 EOT = '\0',
61 SymbolicOp = 'O' , // can be unary or binary
62 AlphaUnOp = 'U' ,
63 AlphaBinOp = 'B' ,
64
65 LitString = 'S' ,
66 LitInteger = 'I' ,
67 LitFloat = 'F' ,
68
69 Identifier = 'A' ,
70
71 BraceOpen = '(' ,
72 BraceClose = ')' ,
73 Comma = ',' ,
74
75 SubscriptOpen = '[' ,
76 SubscriptClose = ']' ,
77 };
78
79 /** Memory for temporary allocations, like AST objects or literal strings with converted
80 * escape sequences. Provided by the compiler with method #Parse. */
82
83 /** The actual token type. */
85
86 /** The actual token type. */
88
89 /** Integer value of token (if applicable). */
91
92 /** Float value of token (if applicable). */
93 double tokFloat;
94
95 /** String value of token (if applicable). */
97
98 /** The position of the token in #expression. */
100
101 /** The compiler that this parser works for. */
103
104 /** Used for scanning literals. Provided to this class with each parse request. */
106
107
108 /** The given expression to parse. */
110
111 /** The rest of #expression. */
113
114 /**
115 * Lists single characters that get directly converted into tokens of corresponding type
116 * when found in the expression string. Tokens are <c>"()[],"</c>.
117 */
118 std::bitset<256> syntaxTokens;
119
120 /**
121 * Lists single characters that got found in operator strings which have been registered
122 * with
123 * \alib{expressions;Compiler::AddUnaryOperator} and
124 * \alib{expressions;Compiler::AddBinaryOperator}.
125 *
126 * Used by the internal token scanner (lexer) and by default will become something like
127 * <c>"=+-*%/?:~!|&^!<>/%"</c>.
128 * when found in the expression string.
129 */
130 std::bitset<256> operatorChars;
131
132 /**
133 * Hash set of unary operators. The key of the table is the operator string, which usually
134 * consists of one character, like <c>'-'</c> or <c>'!'</c>.
135 *
136 * This table is filled in the constructor of the class with the values stored in
137 * \alib{expressions;Compiler::UnaryOperators} and used for testing of existence.
138 */
140 alib::hash_string_ignore_case <character>,
141 alib::equal_to_string_ignore_case<character> > unaryOperators;
142
143 /**
144 * Hash set of binary operators. The key of the table is the operator string, which usually
145 * consists of one to three characters, like <c>'+'</c> or <c>'<<='</c>.
146 *
147 * This table is filled in the constructor of the class with the values stored in
148 * \alib{expressions;Compiler::BinaryOperators} and used for testing of existence.
149 */
151 alib::hash_string_ignore_case <character>,
152 alib::equal_to_string_ignore_case<character> > binaryOperators;
153
154 /** List of ASTs currently created in recursion.
155 * \note
156 * This vector is created in the monotonic allocator and never even deleted, as all
157 * inserted \b AST elements, exclusively allocate from the same temporary allocator. */
158 std::vector<AST*, StdContMA<AST*>>* ASTs;
159
160 // #############################################################################################
161 // Constructor/destructor, interface
162 // #############################################################################################
163 public:
164 /**
165 * Constructor.
166 * @param compiler The compiler that this parser works for.
167 * @param allocator A monotonic allocator for permanent allocations.
168 */
170
171 /** Virtual destructor. */
172 virtual ~ParserImpl() override
173 {}
174
175 /**
176 * Parses the given expression string.
177 * \note
178 * The return value is hidden by using <c>void*</c>. This is to allow avoid flooding
179 * of \c boost header includes files to the code entities using module \alib_expressions_nl.
180 *
181 * @param exprString The string to parse.
182 * @param nf Used to scan number literals.
183 * @param allocator Allocator to create temporary objects.
184 * @return The abstract syntax tree representing the expression.
185 */
186 ALIB_API virtual
187 detail::AST* Parse( const String& exprString, NumberFormat* nf,
188 MonoAllocator* allocator ) override;
189
190
191 protected:
192 // #############################################################################################
193 // Lexer
194 // #############################################################################################
195 /**
196 * This is the "scanner" or "lexer" method.
197 */
198 void NextToken();
199
200
201 // #############################################################################################
202 // Parser
203 // #############################################################################################
204
205 /**
206 * Tests if the actual token represents a known unary operator.
207 * @return Returns the binary operator symbol, respectively a \e nulled string on failure.
208 */
211
212 /**
213 * Tests if the actual token represents a known binary operator.
214 * @return Returns the binary operator symbol, respectively a \e nulled string on failure.
215 */
218
219 /**
220 * Internal method that optionally parses a conditional operator (<c>Q ? T : F</c> )
221 *
222 * @return T.
223 */
225
226 /**
227 * Internal method that optionally parses a binary operator and levels (recursively)
228 * trees of such according to operator precedence and brackets given.
229 * @return T.
230 */
231 AST* parseBinary();
232
233 /**
234 * Parses unary ops, literals, identifiers, functions and expressions surrounded by
235 * brackets.
236 * @return The abstract syntax tree node parsed.
237 */
238 AST* parseSimple();
239
240 /**
241 * Invoked after an identifier or function was parsed. Tests for subscript
242 * operator, otherwise returns teh given ast as is.
243 * @param function The identifier or function parsed.
244 * @return Either the given node or a node of type \alib{expressions::detail;ASTBinaryOp}
245 * with \c lhs set to \p{function}, \c rhs to the parsed subscript arg and
246 * and operator set to <c>'[]'</c>.
247 */
248 AST* parseSubscript( AST* function );
249
250
251
252 /**
253 * Simple shortcut popping and returning last ast from the current list.
254 * @return Popped AST object.
255 */
257 {
258 AST* ast= ASTs->back();
259 ASTs->pop_back();
260 return ast;
261 }
262
263 /**
264 * Simple shortcut pushing an ast to current list and returning it.
265 * @param ast The AST node to push.
266 * @return Popped AST object.
267 */
268 AST* push( AST* ast )
269 {
270 ASTs->emplace_back(ast);
271 return ast;
272 }
273
274 /**
275 * Simple shortcut to the topmost AST.
276 * @return The topmost AST object.
277 */
279 {
280 return ASTs->back();
281 }
282
283 /**
284 * Simple shortcut replacing the topmost ast.
285 * @param ast The new AST node to replace the existing one with.
286 * @return The given object.
287 */
288 AST* replace( AST* ast )
289 {
290 ASTs->back()= ast;
291 return ast;
292 }
293}; // class ParserImpl
294
295
296}}} // namespace [alib::expressions::detail]
297
298
299
300#endif // HPP_ALIB_EXPRESSIONS_DETAIL_PARSER_IMPL
std::vector< AST *, StdContMA< AST * > > * ASTs
HashSet< String, alib::hash_string_ignore_case< character >, alib::equal_to_string_ignore_case< character > > binaryOperators
ParserImpl(Compiler &compiler, MonoAllocator *allocator)
HashSet< String, alib::hash_string_ignore_case< character >, alib::equal_to_string_ignore_case< character > > unaryOperators
virtual ALIB_API detail::AST * Parse(const String &exprString, NumberFormat *nf, MonoAllocator *allocator) override
#define ALIB_API
Definition alib.hpp:538
Definition alib.cpp:57
strings::TString< character > String
Type alias in namespace alib.
expressions::Compiler Compiler
Type alias in namespace alib.
Definition compiler.hpp:596
lang::integer integer
Type alias in namespace alib.
Definition integers.hpp:286