ALib C++ Library
Library Version: 2412 R0
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#pragma once
17
18#include <bitset>
19
20namespace alib { namespace expressions {
21
22class Compiler;
23class Parser;
24
25namespace detail {
26
27//==================================================================================================
28/// Implementation of the default parser of module \alib_expressions_nl.
29///
30/// This internal class is not too well documented. Nevertheless, it is designed to be able
31/// to tweak its behavior slightly and in case of need, even derive and use a custom parser
32/// class. For doing so, please consult the source code of this class.
33/// A custom parser might be set to protected field \alib{expressions;Compiler::parser}by a derived
34/// compiler type before compiling a first expression.
35///
36/// It is possible to define scannable custom unary and binary operators. Definitions of binary
37/// operators include a "precedence value" that allows aligning them with the built-in types.
38/// Also, built-in operators can be \em removed if wanted.
39//==================================================================================================
40class ParserImpl : public Parser
41{
42 protected:
43 /// Types of tokens.
44 enum class Tokens : char
45 {
46 EOT = '\0',
47 SymbolicOp = 'O' , // can be unary or binary
48 AlphaUnOp = 'U' ,
49 AlphaBinOp = 'B' ,
50
51 LitString = 'S' ,
52 LitInteger = 'I' ,
53 LitFloat = 'F' ,
54
55 Identifier = 'A' ,
56
57 BraceOpen = '(' ,
58 BraceClose = ')' ,
59 Comma = ',' ,
60
61 SubscriptOpen = '[' ,
62 SubscriptClose = ']' ,
63 };
64
65 /// Memory for temporary allocations, like AST objects or literal strings with converted
66 /// escape sequences. Provided by the compiler with method #Parse.
68
69 /// The actual token type.
71
72 /// The actual token type.
74
75 /// Integer value of token (if applicable).
77
78 /// Float value of token (if applicable).
79 double tokFloat;
80
81 /// String value of token (if applicable).
83
84 /// The position of the token in #expression.
86
87 /// The compiler that this parser works for.
89
90 /// Used for scanning literals. Provided to this class with each parse request.
92
93
94 /// The given expression to parse.
96
97 /// The rest of #expression.
99
100 /// Lists single characters that get directly converted into tokens of corresponding type
101 /// when found in the expression string. Tokens are <c>"()[],"</c>.
102 std::bitset<256> syntaxTokens;
103
104 /// Lists single characters that got found in operator strings which have been registered
105 /// with
106 /// \alib{expressions;Compiler::AddUnaryOperator} and
107 /// \alib{expressions;Compiler::AddBinaryOperator}.
108 ///
109 /// Used by the internal token scanner (lexer) and by default will become something like
110 /// <c>"=+-*%/?:~!|&^!<>/%"</c>.
111 /// when found in the expression string.
112 std::bitset<256> operatorChars;
113
114 /// Hash set of unary operators. The key of the table is the operator string, which usually
115 /// consists of one character, like <c>'-'</c> or <c>'!'</c>.
116 ///
117 /// This table is filled in the constructor of the class with the values stored in
118 /// \alib{expressions;Compiler::UnaryOperators} and used for testing of existence.
120 String,
121 alib::hash_string_ignore_case <character>,
122 alib::equal_to_string_ignore_case<character> > unaryOperators;
123
124 /// Hash set of binary operators. The key of the table is the operator string, which usually
125 /// consists of one to three characters, like <c>'+'</c> or <c>'<<='</c>.
126 ///
127 /// This table is filled in the constructor of the class with the values stored in
128 /// \alib{expressions;Compiler::BinaryOperators} and used for testing of existence.
130 String,
131 alib::hash_string_ignore_case <character>,
132 alib::equal_to_string_ignore_case<character> > binaryOperators;
133
134 /// List of ASTs currently created in recursion.
135 /// \note
136 /// This vector is created in the monotonic allocator and never even deleted, as all
137 /// inserted \b AST elements, exclusively allocate from the same temporary allocator.
139
140 // #############################################################################################
141 // Constructor/destructor, interface
142 // #############################################################################################
143 public:
144 /// Constructor.
145 /// @param compiler The compiler that this parser works for.
146 /// @param allocator A monotonic allocator for permanent allocations.
148
149 /// Virtual destructor.
150 virtual ~ParserImpl() override
151 {}
152
153 /// Parses the given expression string.
154 /// \note
155 /// The return value is hidden by using <c>void*</c>. This is to allow avoid flooding
156 /// of \c boost header includes files to the code entities using module \alib_expressions_nl.
157 ///
158 /// @param exprString The string to parse.
159 /// @param nf Used to scan number literals.
160 /// @return The abstract syntax tree representing the expression.
161 ALIB_API virtual
162 detail::AST* Parse( const String& exprString, NumberFormat* nf ) override;
163
164
165 protected:
166 // #############################################################################################
167 // Lexer
168 // #############################################################################################
169 /// This is the "scanner" or "lexer" method.
170 void NextToken();
171
172
173 // #############################################################################################
174 // Parser
175 // #############################################################################################
176
177 /// Tests if the actual token represents a known unary operator.
178 /// @return Returns the binary operator symbol, respectively a \e nulled string on failure.
181
182 /// Tests if the actual token represents a known binary operator.
183 /// @return Returns the binary operator symbol, respectively a \e nulled string on failure.
186
187 /// Internal method that optionally parses a conditional operator (<c>Q ? T : F</c> )
188 ///
189 /// @return T.
191
192 /// Internal method that optionally parses a binary operator and levels (recursively)
193 /// trees of such according to operator precedence and brackets given.
194 /// @return T.
195 AST* parseBinary();
196
197 /// Parses unary ops, literals, identifiers, functions and expressions surrounded by
198 /// brackets.
199 /// @return The abstract syntax tree node parsed.
200 AST* parseSimple();
201
202 /// Invoked after an identifier or function was parsed. Tests for subscript
203 /// operator, otherwise returns the given ast as is.
204 /// @param function The identifier or function parsed.
205 /// @return Either the given node or a node of type \alib{expressions::detail;ASTBinaryOp}
206 /// with \c lhs set to \p{function}, \c rhs to the parsed subscript arg and
207 /// and operator set to <c>'[]'</c>.
208 AST* parseSubscript( AST* function );
209
210
211
212 /// Simple shortcut popping and returning last ast from the current list.
213 /// @return Popped AST object.
215 {
216 AST* ast= ASTs->back();
217 ASTs->pop_back();
218 return ast;
219 }
220
221 /// Simple shortcut pushing an ast to current list and returning it.
222 /// @param ast The AST node to push.
223 /// @return Popped AST object.
224 AST* push( AST* ast )
225 {
226 ASTs->emplace_back(ast);
227 return ast;
228 }
229
230 /// Simple shortcut to the topmost AST.
231 /// @return The topmost AST object.
233 {
234 return ASTs->back();
235 }
236
237 /// Simple shortcut replacing the topmost ast.
238 /// @param ast The new AST node to replace the existing one with.
239 /// @return The given object.
240 AST* replace( AST* ast )
241 {
242 ASTs->back()= ast;
243 return ast;
244 }
245}; // class ParserImpl
246
247
248}}} // namespace [alib::expressions::detail]
249
250
251
252#endif // HPP_ALIB_EXPRESSIONS_DETAIL_PARSER_IMPL
253
ASTLiteral::NFHint tokLiteralHint
The actual token type.
HashSet< MonoAllocator, 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) override
integer tokPosition
The position of the token in expression.
Tokens token
The actual token type.
integer tokInteger
Integer value of token (if applicable).
void NextToken()
This is the "scanner" or "lexer" method.
NumberFormat * numberFormat
Used for scanning literals. Provided to this class with each parse request.
virtual ~ParserImpl() override
Virtual destructor.
Substring scanner
The rest of expression.
String expression
The given expression to parse.
Compiler & compiler
The compiler that this parser works for.
ParserImpl(Compiler &compiler, MonoAllocator &allocator)
String tokString
String value of token (if applicable).
double tokFloat
Float value of token (if applicable).
HashSet< MonoAllocator, String, alib::hash_string_ignore_case< character >, alib::equal_to_string_ignore_case< character > > binaryOperators
#define ALIB_API
Definition alib.hpp:639
Definition alib.cpp:69
std::vector< T, SCAMono< T > > StdVectorMono
Type alias in namespace alib.
Definition stdvector.hpp:21
monomem::TMonoAllocator< lang::HeapAllocator > MonoAllocator
strings::TString< character > String
Type alias in namespace alib.
expressions::Compiler Compiler
Type alias in namespace alib.
Definition compiler.hpp:553
lang::integer integer
Type alias in namespace alib.
Definition integers.hpp:273
This detail class constitutes an abstract base class for expression parsers.
Definition parser.hpp:24