17namespace alib {
namespace expressions {
namespace detail {
24: compileTimeAllocator(allocator)
26, unaryOperators (allocator)
27, binaryOperators (allocator)
40 ALIB_ASSERT_ERROR( !unaryOperators.Contains(op),
"EXPR",
41 "Doubly defined unary operator symbol {!Q'}.", op )
43 unaryOperators.EmplaceUnique(op);
45 operatorChars[static_cast<unsigned char>(it)]= true;
50 ALIB_ASSERT_ERROR( !unaryOperators.Contains(op.first),
"EXPR",
51 "Doubly defined unary operator symbol {!Q'}.", op.first )
53 unaryOperators.EmplaceUnique(op.first);
54 if( !isalpha( op.first.CharAtStart() ) )
55 for( auto it : op.first )
56 operatorChars[static_cast<unsigned char>(it)]= true;
62 ALIB_ASSERT_ERROR( !binaryOperators.Contains(op.first),
"EXPR",
63 "Doubly defined binary operator symbol {!Q'}.", op.first )
64 if( op.first == A_CHAR(
"[]") )
66 syntaxTokens[static_cast<unsigned char>(
'[')]= true;
67 syntaxTokens[static_cast<unsigned char>(
']')]= true;
71 binaryOperators.EmplaceUnique(op.first);
72 for( auto it : op.first )
73 operatorChars[static_cast<unsigned char>(it)]= true;
77 for(
auto op : compiler.AlphabeticBinaryOperatorAliases )
79 ALIB_ASSERT_ERROR( !binaryOperators.Contains(op.first),
"EXPR",
80 "Doubly defined binary operator symbol {!Q'}.", op.first )
82 ALIB_DBG( auto originalOp= )
83 compiler.BinaryOperators.Find( op.second );
84 ALIB_ASSERT_ERROR( originalOp != compiler.BinaryOperators.end(),
"EXPR",
85 "Alias {!Q'} defined for unknown operator {!Q'}.",
88 binaryOperators.EmplaceUnique(op.first);
89 if( !isalpha( op.first.CharAtStart() ) )
90 for( auto it : op.first )
91 operatorChars[static_cast<unsigned char>(it)]= true;
137 token= Tokens::SymbolicOp;
159 if( isalpha( first ) )
175 token= Tokens::AlphaUnOp;
188 token= Tokens::AlphaBinOp;
196 if( isalpha( first ) || first ==
'_' )
201 && ( isalnum( next=
scanner[endOfIdent] )
204 token= Tokens::Identifier;
213 if( isdigit( first ) )
218 && ( isdigit( next=
scanner[endOfDecPart] )
233 token = Tokens::LitFloat;
238 || numberParsed.
IndexOf(
'E') > 0
257 token= Tokens::LitInteger;
267 bool lastWasSlash=
false;
272 if( next ==
'\\' ) { lastWasSlash=
true;
continue; }
273 if( next ==
'\"' && !lastWasSlash )
break;
290 token = Tokens::LitString;
306#define Start parseConditional
328 if(
token != Tokens::EOT )
388 if(
token == Tokens::BraceOpen )
398 if(
token == Tokens::EOT )
420 if( parent ==
nullptr )
432 if(
token == Tokens::BraceOpen )
437 if(
token != Tokens::BraceClose )
464 if(
token == Tokens::Identifier ||
token == Tokens::AlphaBinOp )
470 if(
token == Tokens::BraceOpen )
477 if(
token == Tokens::BraceClose )
482 astFunction->
Arguments.EmplaceBack( Start() );
484 if(
token == Tokens::Comma )
487 if(
token != Tokens::BraceClose )
506 if(
token == Tokens::EOT )
513 if(
token == Tokens::BraceClose )
520 if(
token == Tokens::SubscriptOpen ||
token == Tokens::SubscriptClose )
527 if(
token == Tokens::Comma )
534 ALIB_ERROR(
"EXPR",
"Internal error. This should never happen.")
541 ||
token != Tokens::SubscriptOpen )
550 if(
token != Tokens::SubscriptClose )
570 if(
token == Tokens::SymbolicOp )
596 else if (
token == Tokens::AlphaUnOp )
600 return alphabeticOperator;
608 if (
token == Tokens::SymbolicOp )
639 else if (
token == Tokens::AlphaBinOp )
643 return alphabeticOperator;
HashMap< MonoAllocator, String, String, alib::hash_string_ignore_case< character >, alib::equal_to_string_ignore_case< character > > AlphabeticUnaryOperatorAliases
HashMap< MonoAllocator, String, int > BinaryOperators
List< MonoAllocator, String > UnaryOperators
int GetBinaryOperatorPrecedence(const String &symbol)
Compilation CfgCompilation
Compilation flags.
ASTLiteral::NFHint tokLiteralHint
The actual token type.
ALIB_API String getBinaryOp()
HashSet< MonoAllocator, String, alib::hash_string_ignore_case< character >, alib::equal_to_string_ignore_case< character > > unaryOperators
StdVectorMono< AST * > * ASTs
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.
std::bitset< 256 > operatorChars
ALIB_API String getUnaryOp()
AST * parseSubscript(AST *function)
MonoAllocator & compileTimeAllocator
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).
std::bitset< 256 > syntaxTokens
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
const String & GetResource(const NString &name)
Exception & Add(const lang::CallerInfo &ci, TEnum type, TArgs &&... args)
constexpr bool IsNull() const
integer IndexOf(TChar needle, integer startIdx=0) const
constexpr bool IsEmpty() const
void Allocate(TAllocator &allocator, const TString< TChar > ©)
constexpr bool IsNotEmpty() const
constexpr integer Length() const
TChar CharAtStart() const
constexpr bool IsNotNull() const
std::size_t HashcodeIgnoreCase() const
TString< TChar > Substring(integer regionStart, integer regionLength=MAX_LEN) const
bool Equals(const TString< TChar > &rhs) const
bool StartsWith(const TString &needle) const
constexpr const TChar * Buffer() const
ALIB_API bool ConsumeFloat(double &result, TNumberFormat< TChar > *numberFormat=nullptr)
integer ConsumeChars(integer regionLength, TSubstring *target=nullptr)
TSubstring & TrimStart(const TCString< TChar > &whiteSpaces=TT_CStringConstants< TChar >::DefaultWhitespaces())
bool ConsumeInt(TIntegral &result, TNumberFormat< TChar > *numberFormat=nullptr)
#define ALIB_CALLER_NULLED
#define ALIB_WARNINGS_RESTORE
#define ALIB_WARNINGS_ALLOW_UNSAFE_BUFFER_USAGE
@ AlphabeticOperatorsIgnoreCase
@ UnknownBinaryOperatorSymbol
Unknown binary operator symbol found when parsing expression string.
@ UnknownUnaryOperatorSymbol
Unknown unary operator symbol found when parsing expression string.
@ EmptyExpressionString
Thrown when an empty string is tried to be compiled.
@ SyntaxErrorExpectation
Syntax error with concrete information about what the parser expected at given position.
@ SyntaxError
General error thrown by the parser.
@ Off
Switch it off, switched off, etc.
lang::Exception Exception
Type alias in namespace alib.
expressions::ExpressionsCamp EXPRESSIONS
The singleton instance of ALib Camp class ExpressionsCamp.
std::vector< T, SCAMono< T > > StdVectorMono
Type alias in namespace alib.
strings::TSubstring< character > Substring
Type alias in namespace alib.
characters::character character
Type alias in namespace alib.
strings::TString< character > String
Type alias in namespace alib.
LocalString< 1024 > String1K
Type alias name for TLocalString<character,1024>.
constexpr String NULL_STRING
A nulled string of the default character type.
lang::integer integer
Type alias in namespace alib.
Abstract syntax tree node representing binary operators.
String Operator
The operator symbol.
AST * Lhs
The left-hand-side expression node.
Abstract syntax tree node representing ternary operator Q ? T : F.
Abstract syntax tree node representing a function call.
List< MonoAllocator, AST * > Arguments
The argument nodes.
@ Scientific
Float was given in scientific format.
@ Hexadecimal
Integral value was given in hexadecimal format.
@ Binary
Integral value was given in binary format.
@ Octal
Integral value was given in octal format.
Types NodeType
Type of derived this AST node.