Click here to Skip to main content
15,885,216 members
Articles / Desktop Programming / ATL

Visual Calc v3.0 - A new dimension for the desktop calculator

Rate me:
Please Sign up or sign in to vote.
3.62/5 (113 votes)
28 Apr 2006CPOL22 min read 351.2K   6.8K   104  
How to start programming a parser.
/**
 * @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 2.5
 *
 * @par Release:
 *      06 February 2006
 *
 * @author <A href="http://www.codeproject.com/script/profile/whos_who.asp?id=741829">toxcct</A>
 *
 * @par Copyright:
 *      &copy;2004-2006 toxcct
 *      for <A href="http://www.codeproject.com">The CodeProject</A>
 *
 * @par Homepage:
 *      http://www.codeproject.com/cpp/visualcalc.asp
 *
 * @par Plateform:
 *      Every plateform which provides a standard compliant compiler.<BR>
 *      Not tested yet for any other plateforms than Microsoft Windows<SUP><SMALL>&reg;</SMALL></SUP> 2000, XP, 2003.<BR>
 *      Initially written with Microsoft Visual C++<SUP><SMALL>&reg;</SMALL></SUP> 6.<BR>
 *      Migratting for Microsoft Visual C++.NET<SUP><SMALL>&reg;</SMALL></SUP> 2003.
 *
 * @par History of the public releases:
 *      - <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

// Identifier was truncated to '255' characters in the debug information
#pragma warning (disable: 4786)

#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 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				*/
	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);
	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__)

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Accenture Technology Solutions
France France

Toxcct is an electronics guy who felt in love with programming at the age of 10 when he discovered C to play with Texas-Instruments calculators.

Few years later, he discovered "The C++ Language" from Bjarne Stroustrup ; a true transformation in his life.

Now, toxcct is experiencing the Web by developing Siebel CRM Applications for a living. He also respects very much the Web Standards (YES, a HTML/CSS code MUST validate !), and plays around with HTML/CSS/Javascript/Ajax/PHP and such.

_____

After four years of services as a Codeproject MVP, toxcct is now taking some distance as he doesn't like how things are going on the forums. he particularly doesn't accept how some totally ignorant people got the MVP Reward by only being arrogant and insulting while replying on the technical forums.



Comments and Discussions