LTP GCOV extension - code coverage report
Current view: directory - libstx-exparser - ExpressionParser.h
Test: STX ExpressionParser Testsuite
Date: 2007-07-17 Instrumented lines: 44
Code covered: 88.6 % Executed lines: 39

       1                 : // $Id: ExpressionParser.h 59 2007-07-17 14:43:23Z tb $
       2                 : 
       3                 : /*
       4                 :  * STX Expression Parser C++ Framework v0.7
       5                 :  * Copyright (C) 2007 Timo Bingmann
       6                 :  *
       7                 :  * This library is free software; you can redistribute it and/or modify it
       8                 :  * under the terms of the GNU Lesser General Public License as published by the
       9                 :  * Free Software Foundation; either version 2.1 of the License, or (at your
      10                 :  * option) any later version.
      11                 :  *
      12                 :  * This library is distributed in the hope that it will be useful, but WITHOUT
      13                 :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      14                 :  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
      15                 :  * for more details.
      16                 :  *
      17                 :  * You should have received a copy of the GNU Lesser General Public License
      18                 :  * along with this library; if not, write to the Free Software Foundation,
      19                 :  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      20                 :  */
      21                 : 
      22                 : /** \file ExpressionParser.h
      23                 :  * Definition of a the public interface of the STX Expression Parser. It
      24                 :  * exports the abstract interface to a ParseNode tree root and the parse
      25                 :  * functions themselves.
      26                 :  */
      27                 : 
      28                 : #ifndef _STX_ExpressionParser_H_
      29                 : #define _STX_ExpressionParser_H_
      30                 : 
      31                 : #include <string>
      32                 : #include <vector>
      33                 : #include <map>
      34                 : #include <assert.h>
      35                 : #include <boost/smart_ptr.hpp>
      36                 : #include "AnyScalar.h"
      37                 : 
      38                 : /// STX - Some Template Extensions namespace
      39                 : namespace stx {
      40                 : 
      41                 : /** Base class for other exceptions of the expression parser and
      42                 :  * evaluators. \ingroup Exception */
      43                 : class ExpressionParserException : public std::runtime_error
      44               5 : {
      45                 : public:
      46                 :     /// Construct with a description string.
      47               5 :     inline ExpressionParserException(const std::string &s) throw()
      48               5 :         : std::runtime_error(s)
      49               5 :     { }
      50                 : };
      51                 : 
      52                 : /** ConversionException is an exception class thrown by some combinations of
      53                 :  * get and set in AnyScalar. \ingroup Exception */
      54                 : 
      55                 : class ConversionException : public ExpressionParserException
      56               1 : {
      57                 : public:
      58                 :     /// Constructor of the exception takes the description string s.
      59               1 :     inline ConversionException(const std::string &s) throw()
      60               1 :         : ExpressionParserException(s)
      61               1 :     { }
      62                 : };
      63                 : 
      64                 : /** ArithmeticException is an exception class thrown upon some arithmetic
      65                 :  * errors like integer divison by zero. \ingroup Exception */
      66                 : 
      67                 : class ArithmeticException : public ExpressionParserException
      68               0 : {
      69                 : public:
      70                 :     /// Constructor of the exception takes the description string s.
      71               0 :     inline ArithmeticException(const std::string &s) throw()
      72               0 :         : ExpressionParserException(s)
      73               0 :     { }
      74                 : };
      75                 : 
      76                 : /** Exception class thrown when the parser recognizes a syntax error.
      77                 :  * \ingroup Exception */
      78                 : 
      79                 : class BadSyntaxException : public ExpressionParserException
      80               1 : {
      81                 : public:
      82                 :     /// Construct with a description string.
      83               1 :     inline BadSyntaxException(const std::string &s) throw()
      84               1 :         : ExpressionParserException(s)
      85               1 :     { }
      86                 : };
      87                 : 
      88                 : /** Exception class thrown when the symbol table cannot find a variable or
      89                 :  * function. \ingroup Exception */
      90                 : 
      91                 : class UnknownSymbolException : public ExpressionParserException
      92               2 : {
      93                 : public:
      94                 :     /// Construct with a description string.
      95               2 :     inline UnknownSymbolException(const std::string &s) throw()
      96               2 :         : ExpressionParserException(s)
      97               2 :     { }
      98                 : };
      99                 : 
     100                 : /** Exception class thrown when the symbol table cannot correctly execute a
     101                 :  * function. \ingroup Exception */
     102                 : 
     103                 : class BadFunctionCallException : public ExpressionParserException
     104               1 : {
     105                 : public:
     106                 :     /// Construct with a description string.
     107               1 :     inline BadFunctionCallException(const std::string &s) throw()
     108               1 :         : ExpressionParserException(s)
     109               1 :     { }
     110                 : };
     111                 : 
     112                 : /** Abstract class used for evaluation of variables and function placeholders
     113                 :  * within an expression. If you wish some standard mathematic function, then
     114                 :  * derive your SymbolTable class from BasicSymbolTable instead of directly from
     115                 :  * this one. */
     116                 : class SymbolTable
     117              17 : {
     118                 : public:
     119                 :     /// STL container type used for parameter lists: a vector
     120                 :     typedef std::vector<AnyScalar>        paramlist_type;
     121                 : 
     122                 :     /// Required for virtual functions.
     123                 :     virtual ~SymbolTable();
     124                 : 
     125                 :     /// Return the (constant) value of a variable.
     126                 :     virtual AnyScalar   lookupVariable(const std::string &varname) const = 0;
     127                 : 
     128                 :     /// Called when a program-defined function needs to be evaluated within an
     129                 :     /// expression.
     130                 :     virtual AnyScalar   processFunction(const std::string &funcname,
     131                 :                                         const paramlist_type &paramlist) const = 0;
     132                 : };
     133                 : 
     134                 : /** Concrete class used for evaluation of variables and function placeholders
     135                 :  * within an expression. This class will always throw an UnknownSymbolException
     136                 :  * for both lookup functions. It can be used as a base class for symbol tables
     137                 :  * without the standard functions included in BasicSymbolTable. */
     138                 : class EmptySymbolTable : public SymbolTable
     139                 : {
     140                 : public:
     141                 :     /// STL container type used for parameter lists: a vector
     142                 :     typedef std::vector<AnyScalar>        paramlist_type;
     143                 : 
     144                 :     /// Required for virtual functions.
     145                 :     virtual ~EmptySymbolTable();
     146                 : 
     147                 :     /// Return the (constant) value of a variable. In this dummy implementation
     148                 :     /// no variables are defined, it always throws an UnknownSymbolException.
     149                 :     virtual AnyScalar   lookupVariable(const std::string &varname) const;
     150                 : 
     151                 :     /// Called when a program-defined function needs to be evaluated within an
     152                 :     /// expression. In this dummy implementation no functions are defined, it
     153                 :     /// always throws an UnknownSymbolException.
     154                 :     virtual AnyScalar   processFunction(const std::string &funcname,
     155                 :                                         const paramlist_type &paramlist) const;
     156                 : };
     157                 : 
     158                 : /** Class representing variables and functions placeholders within an
     159                 :  * expression. This base class contain two tables of variables and
     160                 :  * functions. Variables may be filled into the STL map by the program. The
     161                 :  * class also contains a set of basic mathematic functions.
     162                 :  */
     163                 : class BasicSymbolTable : public SymbolTable
     164                 : {
     165                 : public:
     166                 :     /// Signature of a function used in the symbol table.
     167                 :     typedef AnyScalar   (*functionptr_type)(const paramlist_type& paramlist);
     168                 : 
     169                 : protected:
     170                 : 
     171                 :     /// Container used to save a map of variable names
     172                 :     typedef std::map<std::string, AnyScalar>      variablemap_type;
     173                 : 
     174                 :     /// Extra info about a function: the valid arguments.
     175                 :     struct FunctionInfo
     176                 :     {
     177                 :         /// Number of arguments this function takes: either >= 0 for a fixed
     178                 :         /// number of -1 for no checking.
     179                 :         int             arguments;
     180                 : 
     181                 :         /// Function pointer to call.
     182                 :         functionptr_type func;
     183                 : 
     184                 :         /// Initializing Constructor
     185             306 :         FunctionInfo(int _arguments = 0, functionptr_type _func = NULL)
     186             306 :             : arguments(_arguments), func(_func)
     187                 :         {
     188             306 :         }
     189                 :     };
     190                 : 
     191                 :     /// Container used to save a map of function names
     192                 :     typedef std::map<std::string, struct FunctionInfo>    functionmap_type;
     193                 : 
     194                 : private:
     195                 :     /// Variable map which can be filled by the user-application
     196                 :     variablemap_type    variablemap;
     197                 : 
     198                 :     /// Function map used to lookup standard or user-added function
     199                 :     functionmap_type    functionmap;
     200                 : 
     201                 : protected:
     202                 :     // *** Lots of Standard Functions
     203                 : 
     204                 :     /// Return the value of PI as a double AnyScalar
     205                 :     static AnyScalar    funcPI(const paramlist_type& paramlist);
     206                 : 
     207                 :     /// Return the value of sin(x) as a double AnyScalar
     208                 :     static AnyScalar    funcSIN(const paramlist_type& paramlist);
     209                 : 
     210                 :     /// Return the value of cos(x) as a double AnyScalar
     211                 :     static AnyScalar    funcCOS(const paramlist_type& paramlist);
     212                 : 
     213                 :     /// Return the value of tan(x) as a double AnyScalar
     214                 :     static AnyScalar    funcTAN(const paramlist_type& paramlist);
     215                 : 
     216                 :     /// Return the value of abs(x) or fabs(f)
     217                 :     static AnyScalar    funcABS(const paramlist_type& paramlist);
     218                 : 
     219                 :     /// Return the value of exp(x) as a double AnyScalar
     220                 :     static AnyScalar    funcEXP(const paramlist_type& paramlist);
     221                 : 
     222                 :     /// Return the value of log(x) as a double AnyScalar
     223                 :     static AnyScalar    funcLOGN(const paramlist_type& paramlist);
     224                 : 
     225                 :     /// Return the value of pow(x,y) as a double AnyScalar
     226                 :     static AnyScalar    funcPOW(const paramlist_type& paramlist);
     227                 : 
     228                 :     /// Return the value of sqrt(x) as a double AnyScalar
     229                 :     static AnyScalar    funcSQRT(const paramlist_type& paramlist);
     230                 : 
     231                 : public:
     232                 :     /// Fills in the functionmap with the standard functions.
     233                 :     BasicSymbolTable();
     234                 : 
     235                 :     /// Required for virtual functions.
     236                 :     virtual ~BasicSymbolTable();
     237                 : 
     238                 :     /// Return the (constant) value of a variable. In this basic implementation
     239                 :     /// no variables are defined, it always throws an UnknownSymbolException.
     240                 :     virtual AnyScalar   lookupVariable(const std::string &varname) const;
     241                 : 
     242                 :     /// Called when a program-defined function needs to be evaluated within an
     243                 :     /// expression.
     244                 :     virtual AnyScalar   processFunction(const std::string &funcname,
     245                 :                                         const paramlist_type &paramlist) const;
     246                 : 
     247                 :     /// Add or replace a variable to the symbol table
     248                 :     void        setVariable(const std::string& varname, const AnyScalar &value);
     249                 : 
     250                 :     /// Add or replace a function to the symbol table
     251                 :     void        setFunction(const std::string& funcname, int arguments, functionptr_type funcptr);
     252                 : 
     253                 :     /// Clear variables table
     254                 :     void        clearVariables();
     255                 : 
     256                 :     /// Clear function table
     257                 :     void        clearFunctions();
     258                 : 
     259                 :     /// Add set of standard mathematic functions
     260                 :     void        addStandardFunctions();
     261                 : };
     262                 : 
     263                 : /** ParseNode is the abstract node interface of different parse nodes. From
     264                 :  * these parse nodes the the ExpressionParser constructs a tree which can be
     265                 :  * evaluated using different SymbolTable settings.
     266                 :  */
     267                 : class ParseNode
     268                 : {
     269                 : protected:
     270                 :     /// Usual construction
     271             222 :     inline ParseNode()
     272             222 :     { }
     273                 : 
     274                 :     /// Disable copy construction
     275                 :     ParseNode(const ParseNode &pn);
     276                 : 
     277                 :     /// And disable assignment
     278                 :     ParseNode& operator=(const ParseNode &pn);
     279                 :     
     280                 : public:
     281                 :     /// Virtual destructor so derived classes can deallocate their children
     282                 :     /// nodes.
     283             222 :     virtual ~ParseNode()
     284             222 :     {
     285             222 :     }
     286                 : 
     287                 :     /// Function to recursively evaluate the contained parse tree and retrieve
     288                 :     /// the calculated scalar value based on the given symbol table.
     289                 :     virtual AnyScalar evaluate(const class SymbolTable &st = BasicSymbolTable()) const = 0;
     290                 : 
     291                 :     /// (Internal) Function to check if the subtree evaluates to a constant
     292                 :     /// expression. If dest == NULL then do a static check whether the node is
     293                 :     /// always a constant (ignoring subnodes), if dest != NULL try to calculate
     294                 :     /// the constant value and type recursively, thus the return value can be
     295                 :     /// true for a non-constant tree node.
     296                 :     virtual bool evaluate_const(AnyScalar *dest) const = 0;
     297                 : 
     298                 :     /// Return the parsed expression as a string, which can be parsed again.
     299                 :     virtual std::string toString() const = 0;
     300                 : };
     301                 : 
     302                 : /** ParseTree contains the root node of a parse tree. It correctly allocates
     303                 :  * and deletes parse node, because they themselves are not copy-constructable
     304                 :  * or assignable. Pimpl class pattern with exposed inner class. */
     305                 : class ParseTree
     306              34 : {
     307                 : protected:
     308                 :     /// Enclosed smart ptr so that the parse tree is not cloned when ParseTree
     309                 :     /// instances are copied.
     310                 :     boost::shared_ptr<ParseNode>  rootnode;
     311                 : 
     312                 : public:
     313                 :     /// Create NULL parse tree object from the root ParseNode. All functions
     314                 :     /// will assert() or segfault unless the tree is assigned.
     315                 :     ParseTree()
     316                 :         : rootnode(static_cast<ParseNode*>(NULL))
     317                 :     {
     318                 :     }
     319                 : 
     320                 :     /// Create parse tree object from the root ParseNode.
     321              34 :     ParseTree(ParseNode* pt)
     322              34 :         : rootnode(pt)
     323                 :     {
     324              34 :     }
     325                 : 
     326                 :     /// Returns true if this object does not contain a parse tree.
     327                 :     inline bool isEmpty() const
     328                 :     {
     329                 :         return (rootnode.get() == NULL);
     330                 :     }
     331                 : 
     332                 :     /// Function to recursively evaluate the contained parse tree and retrieve
     333                 :     /// the calculated scalar value based on the given symbol table.
     334              17 :     AnyScalar   evaluate(const class SymbolTable &st = BasicSymbolTable()) const
     335                 :     {
     336              17 :         assert(rootnode.get() != NULL);
     337              17 :         return rootnode->evaluate(st);
     338                 :     }
     339                 : 
     340                 :     /// Return the parsed expression as a string, which can be parsed again.
     341              34 :     std::string toString() const
     342                 :     {
     343              34 :         assert(rootnode.get() != NULL);
     344              34 :         return rootnode->toString();
     345                 :     }
     346                 : };
     347                 : 
     348                 : /// Parse the given input expression into a parse tree. The parse tree is
     349                 : /// represented by its root node, which can be evaluated.
     350                 : const ParseTree parseExpression(const std::string &input);
     351                 : 
     352                 : /// Parse the given input expression into a parse tree. The parse tree is then
     353                 : /// transformed into a XML tree for better visualisation.
     354                 : std::string parseExpressionXML(const std::string &input);
     355                 : 
     356                 : /** ParseTreeList contains the root parse nodes of a list of expressions. It
     357                 :  * correctly allocates and deletes the parse nodes, because they themselves are
     358                 :  * not copy-constructable or assignable. */
     359                 : class ParseTreeList : public std::vector<ParseTree>
     360               0 : {
     361                 : protected:
     362                 :     /// typedef of our parent class
     363                 :     typedef std::vector<ParseTree>        parent_type;
     364                 : 
     365                 : public:
     366                 :     /// Function to recursively evaluate all the contained parse trees and
     367                 :     /// retrieve each calculated scalar value for the given symbol table.
     368                 :     std::vector<AnyScalar>        evaluate(const class SymbolTable &st = BasicSymbolTable()) const;
     369                 : 
     370                 :     /// Return the list of parsed expression as a string, which can be parsed
     371                 :     /// again.
     372                 :     std::string toString() const;
     373                 : };
     374                 : 
     375                 : /// Parse the given input as an expression list "expr1, expr2, ..." into a
     376                 : /// vector of parse trees. Each parse tree is represented by its root node,
     377                 : /// which can be evaluated.
     378                 : ParseTreeList parseExpressionList(const std::string &input);
     379                 : 
     380                 : } // namespace stx
     381                 : 
     382                 : #endif // _STX_ExpressionParser_H_

Generated by: LTP GCOV extension version 1.4