File expressionparser.hxx#

Parses strings containing expressions, returning a tree of generators

Copyright 2010-2024 BOUT++ contributors

Contact: Ben Dudson, dudson2@llnl.gov

This file is part of BOUT++.

BOUT++ is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

BOUT++ is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with BOUT++. If not, see http://www.gnu.org/licenses/.

Typedefs

using FieldGeneratorPtr = std::shared_ptr<FieldGenerator>#
class FieldGenerator#
#include <expressionparser.hxx>

Represents an operation which generates a value at a given (x,y,z) location, perhaps using other generators passed to clone()

Subclassed by FieldATan, FieldBallooning, FieldBinary, FieldClamp, FieldFunction, FieldGaussian, FieldGenOneArg< Op >, FieldGenTwoArg< Op >, FieldHeaviside, FieldMax, FieldMin, FieldMixmode, FieldNull, FieldRound, FieldTanhHat, FieldValue, FieldValuePtr, FieldWhere, LogicalNot

Public Functions

virtual ~FieldGenerator() = default#
inline virtual FieldGeneratorPtr clone(const std::list<FieldGeneratorPtr> args)#

Virtual constructor. Makes a copy of this FieldGenerator, initialised with the given list of arguments. It is up to the implementations to test whether the correct number of arguments is passed.

Parameters:

args[in] A (possibly empty) list of arguments to the generator function

inline virtual double generate(BoutReal x, BoutReal y, BoutReal z, BoutReal t)#
virtual double generate(const bout::generator::Context &ctx)#

Generate a value at the given coordinates (x,y,z,t) This should be deterministic, always returning the same value given the same inputs

Note: The default implementations of generate call each other; the implementor of a FieldGenerator type must implement one of them or an infinite recursion results. This is for backward compatibility for users and implementors. In a future version this function will be made pure virtual.

inline virtual std::string str() const#

Create a string representation of the generator, for debugging output.

class ExpressionParser#
#include <expressionparser.hxx>

Parses expressions, turning strings into FieldGenerator objects which can be used to perform calculations.

This class is not intended to be used directly, but should be inherited to add additional functionality

Subclassed by FieldFactory

Public Functions

ExpressionParser()#
virtual ~ExpressionParser() = default#
void addGenerator(const std::string &name, FieldGeneratorPtr g)#

Add a generator to the parser, which can then be recognised and used in expressions.

Parameters:
  • name[in] The name to be recognised in expressions. This should start with a letter and contain no whitespace, only alphanumeric letters and underscores.

  • g[in] The class inheriting from FieldGenerator. When recognised in an expression, the clone() function will be called to build a tree of generators

void addBinaryOp(char sym, FieldGeneratorPtr b, int precedence)#

Add a binary operator such as +,-,*,/,^

Parameters:
  • sym[in] The operator symbol. This must be a single character

  • b[in] The FieldGenerator to use. When the symbol is recognised, b->clone() will be called with two input arguments

  • precedence[in] The precedence of the operator, which decides which order operators are performed in. Higher precedence operations are done before low precedence operations. Binary operators already defined are +, - precedence = 10 *, / precedence = 20 ^ precedence = 30

Protected Functions

inline virtual FieldGeneratorPtr resolve(const std::string &name) const#

This will be called to resolve any unknown symbols.

virtual std::multiset<FuzzyMatch> fuzzyFind(const std::string &name, std::string::size_type max_distance = 2) const#

Find approximate matches for name in the known generators. max_distance controls the similarity of results.

Returns a set of possible matches ordered by similarity to name. A distance of 1 means: a single insertion, deletion, substitution, or transposition; that the case differs, for example, “key” and “KEY” match with distance 1

FieldGeneratorPtr parseString(const std::string &input) const#

Parses a given string into a tree of FieldGenerator objects.

Protected Attributes

std::string reserved_chars = "+-*/^[](){},=!"#

Characters which cannot be used in symbols without escaping; all other allowed. In addition, whitespace cannot be used. Adding a binary operator adds its symbol to this string

Private Functions

FieldGeneratorPtr parseIdentifierExpr(LexInfo &lex) const#
FieldGeneratorPtr parseParenExpr(LexInfo &lex) const#
FieldGeneratorPtr parseContextExpr(LexInfo &lex) const#

Context definition

Returns a pointer to a FieldContext object.

Matches [ symbol = expression , symbol = expression … ] ( expression )

FieldGeneratorPtr parsePrimary(LexInfo &lex) const#

Parse a primary expression, one of:

  • number

  • identifier

  • ( … ) parenexpr

  • [ … ]() context

  • a unary ‘-’, which is converted to ‘0 -’ A ParseException is thrown if none of these is found

FieldGeneratorPtr parseBinOpRHS(LexInfo &lex, int prec, FieldGeneratorPtr lhs) const#
FieldGeneratorPtr parseExpression(LexInfo &lex) const#

Private Members

std::map<std::string, FieldGeneratorPtr> gen#

Generators, addressed by name.

std::map<char, std::pair<FieldGeneratorPtr, int>> bin_op#

Binary operations.

struct FuzzyMatch#
#include <expressionparser.hxx>

A result that’s almost what we were looking for. Return type of ExpressionParser::fuzzyFind

Public Members

std::string name#

Name of the match.

std::string::size_type distance#

Edit distance from original search term.

Friends

inline friend bool operator<(const FuzzyMatch &lhs, const FuzzyMatch &rhs)#

Comparison operator so this works in a std::multiset.

struct LexInfo#

Lexing info, used when splitting input into tokens.

Public Functions

LexInfo(const std::string &input, std::string reserved_chars = "")#
char nextToken()#

Get the next token in the string.

Public Members

signed char curtok = 0#

Current token. -1 for number, -2 for symbol, -3 for {string}, 0 for “end of input”.

double curval#

Value if a number.

std::string curident#

Identifier, variable or function name.

signed char LastChar#

The last character read from the string.

std::stringstream ss#

Used to read values from the input string.

std::string reserved_chars#

Reserved characters, not in symbols.

class FieldBinary : public FieldGenerator#
#include <expressionparser.hxx>

Binary operators.

Public Functions

inline FieldBinary(FieldGeneratorPtr l, FieldGeneratorPtr r, char o)#
virtual FieldGeneratorPtr clone(const std::list<FieldGeneratorPtr> args) override#

Virtual constructor. Makes a copy of this FieldGenerator, initialised with the given list of arguments. It is up to the implementations to test whether the correct number of arguments is passed.

Parameters:

args[in] A (possibly empty) list of arguments to the generator function

virtual double generate(const bout::generator::Context &context) override#

Generate a value at the given coordinates (x,y,z,t) This should be deterministic, always returning the same value given the same inputs

Note: The default implementations of generate call each other; the implementor of a FieldGenerator type must implement one of them or an infinite recursion results. This is for backward compatibility for users and implementors. In a future version this function will be made pure virtual.

inline virtual std::string str() const override#

Create a string representation of the generator, for debugging output.

Private Members

FieldGeneratorPtr lhs#
FieldGeneratorPtr rhs#
char op#
class FieldValue : public FieldGenerator#
#include <expressionparser.hxx>

Represent fixed values.

Public Functions

inline FieldValue(double val)#
inline virtual FieldGeneratorPtr clone(const std::list<FieldGeneratorPtr> args) override#

Virtual constructor. Makes a copy of this FieldGenerator, initialised with the given list of arguments. It is up to the implementations to test whether the correct number of arguments is passed.

Parameters:

args[in] A (possibly empty) list of arguments to the generator function

inline virtual double generate(const bout::generator::Context&) override#

Generate a value at the given coordinates (x,y,z,t) This should be deterministic, always returning the same value given the same inputs

Note: The default implementations of generate call each other; the implementor of a FieldGenerator type must implement one of them or an infinite recursion results. This is for backward compatibility for users and implementors. In a future version this function will be made pure virtual.

inline virtual std::string str() const override#

Create a string representation of the generator, for debugging output.

Private Members

double value#
class ParseException : public std::exception#

Public Functions

inline ParseException(const std::string &message_)#
template<class S, class ...Args>
inline ParseException(const S &format, const Args&... args)#
~ParseException() override = default#
inline const char *what() const noexcept override#

Private Members

std::string message#