/* VCalcParser.h
*
* Copyright (c) 2004-2006 by toxcct. All rights reserved.
* Consult your license regarding permissions and restrictions.
*/
/**
* @file VCalcParser.h
* @brief VisualCalc Parser class interface.
*
* Defines the CVCalcParser class which is the place
* where all the calculations are done.
*/
/**
* @mainpage
*
* @par Project name:
* VisualCalc Parser
*
* @version 3.0
*
* @par Release:
* 16 April 2006
*
* @author <A href="http://www.codeproject.com/script/profile/whos_who.asp?id=741829">toxcct</A>
*
* @par Copyright:
* ©2004-2006 toxcct
* for <A href="http://www.codeproject.com">The CodeProject</A>
*
* @par Homepage:
* http://www.codeproject.com/cpp/visualcalc.asp
*
* @par License:
* VisualCalc is released and distributed under the terms of the GNU
* <A href="http://www.gnu.org/licenses/gpl.html">General Public License</A>.<BR>
* This code may be used in compiled form in any way you desire (including commercial use).
* The code may be redistributed unmodified by any means providing it is not sold for profit without the authors
* written consent, and providing that this notice and the authors name and all copyright notices remains intact.
* However, this file and the accompanying source code may not be hosted on a website or bulletin board without the
* authors written permission.<BR>
* This software is provided <I>"as is"</I> without express or implied warranty. The authors can be held responsible
* if the program's undesirable "features" causes any damage or loss of time or data.
*
* @par Plateform:
* Every plateform which provides a standard compliant compiler.<BR>
* Not tested yet for any other plateforms than Microsoft Windows<SUP><SMALL>®</SMALL></SUP> 2000, XP, 2003.<BR>
* Initially written with Microsoft Visual C++<SUP><SMALL>®</SMALL></SUP> 6.<BR>
* Project migrated for Microsoft Visual C++<SUP><SMALL>®</SMALL></SUP> .NET 2003.
*
*
* @par Parser compilation instructions:
* The project is designed to compile with any C++ standard compliant.<BR>
* The requirement is to place the parser source files in your project and to <CODE>#include "VCalcParser.h"</CODE>.<BR>
* If compiling with Visual C++<SUP><SMALL>®</SMALL></SUP> 6, .NET 2003 or later,
* the parser can be set in a Win32 DLL project.<BR>
* In such a project, you have to define the following macros (ignored if non-Microsoft compiler):
* - <CODE>VCALCPARSER_DLL</CODE> : This macro tells the compiler that the parser is in a DLL project.<BR>
* - <CODE>VCALCPARSER_EXPORTS</CODE> : This macro defines the directions of symbols imports/exports.<BR><BR>
* These macros must be define BEFORE including the header, and <CODE>VCALCPARSER_DLL</CODE> must be defined in either
* the DLL and any projects that uses the parser (commonly, in stdafx.h).<BR>
* The DLL project must also set its "Code generation" | "Runtime library" to "Multithreaded DLL"
* (/MD in release or /MDd in debug compilation) due to heap deallocation reasons.
*
* @par History of the public releases:
* - <B>3.0</B> - <I>16/04/2006</I>
* - Separation of the parser in its own DLL project<BR><BR>
* - <B>2.5</B> - <I>06/02/2006</I>
* - New sqrtn() user function
* - Doxygen comments
* - Fix pow() calculation error
* - Fix variables handling exception case
* - Change in the reading stream function<BR><BR>
* - <B>2.3</B> - <I>19/10/2005</I>
* - Separation of the parser in its own project
* - Use of the Standard library only for standard compliance
* - Use of new <CODE>long double</CODE> data type
* - Errors management by exceptions<BR><BR>
* - <B>2.2</B> - <I>26/01/2005</I>
* - Errors management by codes<BR><BR>
* - <B>2.1</B> - <I>28/12/2004</I>
* - New user functions
* - New operators<BR><BR>
* - <B>2.0</B> - <I>13/11/2004</I>
* - New list of the user functions
* - New sequence operator (',')
* - Source code uniformization<BR><BR>
* - <B>1.0</B> - <I>05/10/2004</I>
* - First release (still mixed into the GUI project)
* - Lists of answers and variables available for the user
*/
#if !defined(__AFX_VCALCPARSER_H_INCLUDED__)
#define __AFX_VCALCPARSER_H_INCLUDED__
#if _MSC_VER > 1000
#pragma once
#endif
#if !defined(__cplusplus)
#error C++ compiler required
#endif
//Hides superfluous MS VC++ compiler warnings
#ifdef _MSC_VER
#pragma message("Hiding compiler warnings C4786, C4251 and C4290")
// Identifier was truncated to '255' characters in the debug information
#pragma warning (disable: 4786)
// Identifier : class 'type' needs to have dll-interface to be used by clients of class 'CVCalcParser'
#pragma warning (disable: 4251)
// C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
#pragma warning (disable: 4290)
#endif
// If compiling a DLL project
#if defined(VCALCPARSER_DLL)
#if !defined(_MSC_VER)
#error Microsoft Visual C++ compiler required
#endif
#if !defined(_DLL)
#error You must compile the project as a Multithreaded DLL (/MD or /MDd)
#endif
#ifdef VCALCPARSER_EXPORTS
#define VCALCPARSER_API __declspec(dllexport)
#else
#define VCALCPARSER_API __declspec(dllimport)
#pragma message("Linking to VCalcParser.lib")
#pragma comment(lib, "VCalcParser.lib")
#endif
#else
#define VCALCPARSER_API
#endif
#include <ALGORITHM> // std::find()
#include <STRING> // std::string
#include <LIST> // std::list<>
#include <MAP> // std::map<>
#include <DEQUE> // std::deque<>
#include <CMATH> // ::abs(), ::acos(), ::asin(), ::atan(), ::cos(), ::cosh()
// ::exp(), ::fabs(), ::floor() ::log(), ::log10(), ::fmod()
// ::pow(), ::sin(), ::sinh(), ::sqrt(), ::tan(), ::tanh()
#include "VCalcParserTypes.h"
/**
* @class CVCalcParser
* @brief VisualCalc Parser.
*
* This is the VisualCalc Parser class which take a formula as input,
* and returns either the floating point result or an error describing
* what is wrong in the string to parse.<BR>
*
* The VisualCalc Parser is able to make the following actions, because of
* its data members :
* - know what is the current Token during the parsing process,
* - know depending on the case either the Function/Variable/Constant name,
* the number value or the current operator,
* - raise a warning flag (non-blocking error during parsing),
* - store the mathematic functions defined to be used in the formula to be parsed,
* - store each variable name associated to its stored value,
* - store each formula correctly parsed and the related result.
*
* There is a public interface compound of :
* - the constructor/Desctructor,
* - the Functions/Variables/Answers lists handling member functions,
* - the Warnings handling member functions.
* - the Evaluate() member function, which launches the parsing process.<BR>
*
* All the other member functions are private :
* - the mathematic functions presented as the functions that can be
* used in the formula to be parsed,
* - the 5 level functions and the 2 low level functions that actually
* make the parsing process.
*/
class VCALCPARSER_API CVCalcParser {
private:
// Mathematic constants
const VALUES_TYPE m_PI; /**< 32 digits <I>pi</I> value : 3.1415926535897932384626433832795 */
const VALUES_TYPE m_E; /**< 32 digits <I>e</I> value : 2.7182818284590452353602874713527 */
// Members for parsing treatment
TokenValue m_tokCurrentToken; /**< Current token extracted from the input stream */
std::string m_strSource; /**< Reference to the input stream */
std::string m_strIdentifierValue; /**< Identifier extracted as an IDENTIFIER token */
std::string m_strWarningMsg; /**< To describe the warning */
VALUES_TYPE m_valNumberValue; /**< Number extracted as a NUMBER token */
bool m_bWarningFlag; /**< Non-interrupting low level message */
bool m_bEndEncountered; /**< The end of the input stream is reached */
unsigned int m_iCurrentIndex; /**< Index in the input stream */
std::list<std::string> m_lstFunctions; /**< Supported functions */
std::map<std::string, VALUES_TYPE>
m_mapVariables; /**< User defined variables table mapping the identifier with a value */
std::deque<AnswerItem> m_dqeAnswersHistory; /**< Answers History mapping a formula with a result */
std::string m_strParserVersion; /**< Version of the Parser */
// Locally defined/redefined mathematic functions
VALUES_TYPE ffactor (VALUES_TYPE);
VALUES_TYPE nCp (VALUES_TYPE, VALUES_TYPE);
VALUES_TYPE nAp (VALUES_TYPE, VALUES_TYPE);
AnswerItem Ans (VALUES_TYPE valIndex);
VALUES_TYPE abs (VALUES_TYPE);
VALUES_TYPE cos (VALUES_TYPE);
VALUES_TYPE sin (VALUES_TYPE);
VALUES_TYPE tan (VALUES_TYPE);
VALUES_TYPE cosh (VALUES_TYPE);
VALUES_TYPE sinh (VALUES_TYPE);
VALUES_TYPE tanh (VALUES_TYPE);
VALUES_TYPE Acos (VALUES_TYPE);
VALUES_TYPE Asin (VALUES_TYPE);
VALUES_TYPE Atan (VALUES_TYPE);
VALUES_TYPE deg (VALUES_TYPE);
VALUES_TYPE rad (VALUES_TYPE);
VALUES_TYPE exp (VALUES_TYPE);
VALUES_TYPE ln (VALUES_TYPE);
VALUES_TYPE log (VALUES_TYPE);
VALUES_TYPE logn (VALUES_TYPE, VALUES_TYPE);
VALUES_TYPE sqrt (VALUES_TYPE);
VALUES_TYPE sqrtn (VALUES_TYPE, VALUES_TYPE);
VALUES_TYPE pow (VALUES_TYPE, VALUES_TYPE);
VALUES_TYPE mod (VALUES_TYPE, VALUES_TYPE);
VALUES_TYPE sum (std::string expr, std::string var, VALUES_TYPE low, VALUES_TYPE high);
VALUES_TYPE product (std::string expr, std::string var, VALUES_TYPE low, VALUES_TYPE high);
public:
CVCalcParser();
virtual ~CVCalcParser();
void ResetParserMembers(const std::string& strSource = "");
void ResetFunctions();
void ResetVariables();
void ResetAnswersHistory();
const std::list<std::string>& GetFunctions();
const std::map<std::string, VALUES_TYPE>& GetVariables();
const std::deque<AnswerItem>& GetAnswersHistory();
bool HasWarning();
std::string GetWarningMsg();
std::string GetVersion();
//Parsing functions following (in the recursive-descending order)...
VALUES_TYPE Evaluate(const std::string& Source) throw(CVCalcParserException);
private:
VALUES_TYPE Level_1 (void); // + , -
VALUES_TYPE Level_2 (void); // * , /
VALUES_TYPE Level_3 (void); // ^
VALUES_TYPE Level_4 (void); // %
VALUES_TYPE Level_5 (void); // ! , �
VALUES_TYPE Primary (void); // ( ) , Unary + , Unary -
TokenValue GetToken (void);
bool StepIndexForward(void);
};
#endif // !defined(__AFX_VCALCPARSER_H_INCLUDED__)