00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef FORMULAGRAMMAR_H
00019 #define FORMULAGRAMMAR_H
00020
00021
00022 #include <math.h>
00023
00024 #include <vector>
00025 #include <string>
00026 using namespace std;
00027
00028
00029 #include <boost/spirit/core.hpp>
00030 using namespace boost;
00031 using namespace boost::spirit;
00032
00033
00034
00036 struct PushDouble
00037 {
00041 PushDouble( vector< string > & code ) :
00042 Code( code )
00043 {
00044 }
00045
00050 void operator() ( char const * Start, char const * End ) const
00051 {
00052 Code.push_back( "PUSH " + string( Start, End - Start ) );
00053 }
00054
00055 vector< string > & Code;
00056 };
00057
00058
00059
00061 struct PushOperation
00062 {
00067 PushOperation( const string & cop, vector< string > & code ) :
00068 COP( cop ), Code( code )
00069 {
00070 }
00071
00076 void operator() ( char const * Unused, char const * End ) const
00077 {
00078 Code.push_back( COP );
00079 }
00080
00081 string COP;
00082 vector< string > & Code;
00083 };
00084
00085
00086
00087
00088
00090 struct SFormulaGrammar : public grammar< SFormulaGrammar >
00091 {
00095 SFormulaGrammar( vector< string > & code ) :
00096 Code( code )
00097 {
00098 }
00099
00101 template < typename ScannerT >
00102 struct definition
00103 {
00104 definition( SFormulaGrammar const & Self )
00105 {
00106 Function =
00107 ( str_p( "sin" ) >> '(' >> Expression >> ')' )
00108 [ PushOperation( "SIN", Self.Code ) ] |
00109 ( str_p( "cos" ) >> '(' >> Expression >> ')' )
00110 [ PushOperation( "COS", Self.Code ) ];
00111
00112 Double =
00113 lexeme_d[ (+ureal_p)[ PushDouble( Self.Code ) ] ] |
00114 str_p( "value" )[ PushOperation( "VALUE", Self.Code ) ];
00115
00116 Factor =
00117 Double | Function | '(' >> Expression >> ')' |
00118 ('-' >> Factor)[ PushOperation( "NEGATE", Self.Code ) ] |
00119 ('+' >> Factor);
00120
00121 Term =
00122 Factor
00123 >> *( ('*' >> Factor)[ PushOperation( "MULT", Self.Code ) ]
00124 | ('/' >> Factor)[ PushOperation( "DIV", Self.Code ) ]
00125 );
00126
00127 Expression =
00128 Term
00129 >> *( ('+' >> Term)[ PushOperation( "ADD", Self.Code ) ]
00130 | ('-' >> Term)[ PushOperation( "SUB", Self.Code ) ]
00131 );
00132 }
00133
00134
00135
00136 rule< ScannerT > Expression;
00137 rule< ScannerT > Term;
00138 rule< ScannerT > Factor;
00139 rule< ScannerT > Double;
00140 rule< ScannerT > Function;
00141
00142
00143 rule< ScannerT > const & start( void ) const
00144 {
00145 return Expression;
00146 }
00147 };
00148
00149 vector< string > & Code;
00150 };
00151
00152
00153 #endif
00154