Re: Why no @ or $ operator in C++?
ram@zedat.fu-berlin.de (Stefan Ram) writes:
int main(){ ::std::cout << 2**10_ << '\n'; }
When writing a parser for exponentiation, one needs to know
that exponentiation is right-associative, while division is
left-associative. I just wrote this tiny parser to show how
this might be implemented:
#include <iostream>
#include <ostream>
#include <map>
#include <functional>
#include <cmath>
#include <sstream>
#include <cstring>
::std::map< char, ::std::function< double( double, double )>> ex
{ { '^', []( double const x, double const y )->double
{ return ::std::pow( x, y ); }},
{ '*', []( double const x, double const y )->double{ return x * y; }},
{ '/', []( double const x, double const y )->double{ return x / y; }},
{ '+', []( double const x, double const y )->double{ return x + y; }},
{ '-', []( double const x, double const y )->double{ return x - y; }}};
::std::map< char, bool >left_associative
{ { '^', false }, { '*', true }, { '/', true }, { '+', true }, { '-', true }};
template< typename scanner >struct parser
{ scanner s; parser( char const * s ): s{ s } {}
char check( char const * const op )
{ return ::std::strchr( op, static_cast< char >( s.peek() )) ?
static_cast< char >( s.get() ): 0; }
double numeral(){ return s.get() - '0'; }
double prefix(){ int sign = 1;
while( '-' == s.peek() ){ s.get(); sign *= -1; } return sign * numeral(); }
double parse( char const * const op, double( ::parser< scanner >::*next ) () )
{ double result =( this->*next )();
for( char sym; sym = check( op ); )result = ex[ sym ]
( result, left_associative[ sym ]?( this->*next )(): parse( op, next ));
return result; };
double power(){ return parse( "^", &::parser< scanner >::prefix ); }
double product(){ return parse( "*/", &::parser< scanner >::power ); }
double sum(){ return parse( "+-", &::parser< scanner >::product ); }
double start(){ return sum(); }};
int main()
{ using p = ::parser< ::std::stringstream >;
auto test = []( char const * s ){ ::std::cout << p{ s }.start() << '\n'; };
test( "2^2^3/2/2" ); test( "2+2*2^2^-3" ); }
64
4.18102