|
#pragma once
#include <boost/spirit.hpp>
#include <string>
#include <exception>
namespace Calculator
{
class CParser;
namespace Private
{
////////////////////////////////////////////////////////////////////////////////
/// A set of functors that are used as callbacks from within the parser framework
///
////////////////////////////////////////////////////////////////////////////////
struct FinishedProcessing
{
public:
FinishedProcessing( CParser &parser ) : m_parser( parser ) {}
template <typename IteratorT>
void operator()( IteratorT, IteratorT ) const
{
m_parser.SetProcessingFinished();
}
template <typename CharT>
void operator()( CharT ) const
{
m_parser.SetProcessingFinished();
}
private:
CParser &m_parser;
};
} // namespace Private
////////////////////////////////////////////////////////////////////////////////
/// The syntax, defined according to specific boost::spirit requirements
///
////////////////////////////////////////////////////////////////////////////////
struct Syntax :
public boost::spirit::grammar<Syntax>
{
public:
Syntax( CParser &parser );
virtual ~Syntax();
template <typename ScannerT>
struct definition
{
public:
definition( Syntax const &self )
{
integer =
lexeme_d[ (+digit_p) ]
;
factor =
integer |
vars |
'(' >> expression >> ')' |
( '-' >> factor ) |
( '+' >> factor )
;
term =
factor >> *( ( '*' >> factor) | ( '/' >> factor ) )
;
expression =
term >> *( ( '+' >> term ) | ( '-' >> term ) )
;
assignment =
vars
>> '=' >> expression
;
var_decl =
lexeme_d
[
( ( alpha_p >> *( alnum_p | '_' ) )
- vars )[vars.add]
]
;
declaration =
"int" >> var_decl >> *( ',' >> var_decl )
;
baseExpression =
str_p( "exit" )[*self.m_finishedProcessing] |
str_p( "mod" ) >> integer |
declaration |
assignment |
'?' >> expression
;
}
boost::spirit::symbols<int> vars;
boost::spirit::rule<ScannerT> integer, factor, term,
expression, assignment, var_decl, declaration,
baseExpression;
const boost::spirit::rule<ScannerT> &start() const { return baseExpression; }
};
friend struct definition;
private:
Private::FinishedProcessing *m_finishedProcessing;
};
} // namespace Calculator
|
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.
I started programming on 8 bit machines as a teenager, writing my first compiled programming language before I was 16. I went on to study Engineering and Computer Science at Oxford University, getting a first and the University Prize for the best results in Computer Science. Since then I have worked in a variety of roles, involving systems management and development management on a wide variety of platforms. Now I manage a software development company producing CAD software for Windows using C++.
My 3 favourite reference books are: Design Patterns, Gamma et al; The C++ Standard Library, Josuttis; and Computer Graphics, Foley et al.
Outside computers, I am also the drummer in a band, The Unbelievers and we have just released our first album. I am a pretty good juggler and close up magician, and in my more insane past, I have cycled from Spain to Eastern Turkey, and cycled across the Namib desert.