File expressionparser.hxx

Parses strings containing expressions, returning a tree of generators

Copyright 2010 B.D.Dudson, S.Farley, M.V.Umansky, X.Q.Xu

Contact: Ben Dudson, bd512@york.ac.uk

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

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)

Note: This will be removed in a future version. Implementations should override the Context version of this function.

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