1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_connectivity.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir // Makes parser a static resource, 32*cdf0e10cSrcweir // we're synchronized externally. 33*cdf0e10cSrcweir // But watch out, the parser might have 34*cdf0e10cSrcweir // state not visible to this code! 35*cdf0e10cSrcweir #define BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE 36*cdf0e10cSrcweir #if defined(VERBOSE) && defined(DBG_UTIL) 37*cdf0e10cSrcweir #include <typeinfo> 38*cdf0e10cSrcweir #define BOOST_SPIRIT_DEBUG 39*cdf0e10cSrcweir #endif 40*cdf0e10cSrcweir #include <boost/spirit/include/classic_core.hpp> 41*cdf0e10cSrcweir #include "RowFunctionParser.hxx" 42*cdf0e10cSrcweir #include <rtl/ustring.hxx> 43*cdf0e10cSrcweir #include <tools/fract.hxx> 44*cdf0e10cSrcweir 45*cdf0e10cSrcweir 46*cdf0e10cSrcweir 47*cdf0e10cSrcweir #if (OSL_DEBUG_LEVEL > 0) 48*cdf0e10cSrcweir #include <iostream> 49*cdf0e10cSrcweir #endif 50*cdf0e10cSrcweir #include <functional> 51*cdf0e10cSrcweir #include <algorithm> 52*cdf0e10cSrcweir #include <stack> 53*cdf0e10cSrcweir 54*cdf0e10cSrcweir namespace connectivity 55*cdf0e10cSrcweir { 56*cdf0e10cSrcweir using namespace com::sun::star; 57*cdf0e10cSrcweir 58*cdf0e10cSrcweir namespace 59*cdf0e10cSrcweir { 60*cdf0e10cSrcweir ////////////////////// 61*cdf0e10cSrcweir ////////////////////// 62*cdf0e10cSrcweir // EXPRESSION NODES 63*cdf0e10cSrcweir ////////////////////// 64*cdf0e10cSrcweir ////////////////////// 65*cdf0e10cSrcweir class ConstantValueExpression : public ExpressionNode 66*cdf0e10cSrcweir { 67*cdf0e10cSrcweir ORowSetValueDecoratorRef maValue; 68*cdf0e10cSrcweir 69*cdf0e10cSrcweir public: 70*cdf0e10cSrcweir 71*cdf0e10cSrcweir ConstantValueExpression( ORowSetValueDecoratorRef rValue ) : 72*cdf0e10cSrcweir maValue( rValue ) 73*cdf0e10cSrcweir { 74*cdf0e10cSrcweir } 75*cdf0e10cSrcweir virtual ORowSetValueDecoratorRef evaluate(const ODatabaseMetaDataResultSet::ORow& /*_aRow*/ ) const 76*cdf0e10cSrcweir { 77*cdf0e10cSrcweir return maValue; 78*cdf0e10cSrcweir } 79*cdf0e10cSrcweir virtual void fill(const ODatabaseMetaDataResultSet::ORow& /*_aRow*/ ) const 80*cdf0e10cSrcweir { 81*cdf0e10cSrcweir } 82*cdf0e10cSrcweir virtual ExpressionFunct getType() const 83*cdf0e10cSrcweir { 84*cdf0e10cSrcweir return FUNC_CONST; 85*cdf0e10cSrcweir } 86*cdf0e10cSrcweir virtual ODatabaseMetaDataResultSet::ORow fillNode( std::vector< RowEquation >& /*rEquations*/, ExpressionNode* /* pOptionalArg */, sal_uInt32 /* nFlags */ ) 87*cdf0e10cSrcweir { 88*cdf0e10cSrcweir ODatabaseMetaDataResultSet::ORow aRet; 89*cdf0e10cSrcweir return aRet; 90*cdf0e10cSrcweir } 91*cdf0e10cSrcweir }; 92*cdf0e10cSrcweir 93*cdf0e10cSrcweir 94*cdf0e10cSrcweir /** ExpressionNode implementation for unary 95*cdf0e10cSrcweir function over two ExpressionNodes 96*cdf0e10cSrcweir */ 97*cdf0e10cSrcweir class BinaryFunctionExpression : public ExpressionNode 98*cdf0e10cSrcweir { 99*cdf0e10cSrcweir const ExpressionFunct meFunct; 100*cdf0e10cSrcweir ExpressionNodeSharedPtr mpFirstArg; 101*cdf0e10cSrcweir ExpressionNodeSharedPtr mpSecondArg; 102*cdf0e10cSrcweir 103*cdf0e10cSrcweir public: 104*cdf0e10cSrcweir 105*cdf0e10cSrcweir BinaryFunctionExpression( const ExpressionFunct eFunct, const ExpressionNodeSharedPtr& rFirstArg, const ExpressionNodeSharedPtr& rSecondArg ) : 106*cdf0e10cSrcweir meFunct( eFunct ), 107*cdf0e10cSrcweir mpFirstArg( rFirstArg ), 108*cdf0e10cSrcweir mpSecondArg( rSecondArg ) 109*cdf0e10cSrcweir { 110*cdf0e10cSrcweir } 111*cdf0e10cSrcweir virtual ORowSetValueDecoratorRef evaluate(const ODatabaseMetaDataResultSet::ORow& _aRow ) const 112*cdf0e10cSrcweir { 113*cdf0e10cSrcweir ORowSetValueDecoratorRef aRet; 114*cdf0e10cSrcweir switch(meFunct) 115*cdf0e10cSrcweir { 116*cdf0e10cSrcweir case ENUM_FUNC_EQUATION: 117*cdf0e10cSrcweir aRet = new ORowSetValueDecorator(sal_Bool(mpFirstArg->evaluate(_aRow )->getValue() == mpSecondArg->evaluate(_aRow )->getValue()) ); 118*cdf0e10cSrcweir break; 119*cdf0e10cSrcweir case ENUM_FUNC_AND: 120*cdf0e10cSrcweir aRet = new ORowSetValueDecorator( sal_Bool(mpFirstArg->evaluate(_aRow )->getValue().getBool() && mpSecondArg->evaluate(_aRow )->getValue().getBool()) ); 121*cdf0e10cSrcweir break; 122*cdf0e10cSrcweir case ENUM_FUNC_OR: 123*cdf0e10cSrcweir aRet = new ORowSetValueDecorator( sal_Bool(mpFirstArg->evaluate(_aRow )->getValue().getBool() || mpSecondArg->evaluate(_aRow )->getValue().getBool()) ); 124*cdf0e10cSrcweir break; 125*cdf0e10cSrcweir default: 126*cdf0e10cSrcweir break; 127*cdf0e10cSrcweir } 128*cdf0e10cSrcweir return aRet; 129*cdf0e10cSrcweir } 130*cdf0e10cSrcweir virtual void fill(const ODatabaseMetaDataResultSet::ORow& _aRow ) const 131*cdf0e10cSrcweir { 132*cdf0e10cSrcweir switch(meFunct) 133*cdf0e10cSrcweir { 134*cdf0e10cSrcweir case ENUM_FUNC_EQUATION: 135*cdf0e10cSrcweir (*mpFirstArg->evaluate(_aRow )) = mpSecondArg->evaluate(_aRow )->getValue(); 136*cdf0e10cSrcweir break; 137*cdf0e10cSrcweir default: 138*cdf0e10cSrcweir break; 139*cdf0e10cSrcweir } 140*cdf0e10cSrcweir } 141*cdf0e10cSrcweir virtual ExpressionFunct getType() const 142*cdf0e10cSrcweir { 143*cdf0e10cSrcweir return meFunct; 144*cdf0e10cSrcweir } 145*cdf0e10cSrcweir virtual ODatabaseMetaDataResultSet::ORow fillNode( std::vector< RowEquation >& /*rEquations*/, ExpressionNode* /*pOptionalArg*/, sal_uInt32 /*nFlags*/ ) 146*cdf0e10cSrcweir { 147*cdf0e10cSrcweir ODatabaseMetaDataResultSet::ORow aRet; 148*cdf0e10cSrcweir return aRet; 149*cdf0e10cSrcweir } 150*cdf0e10cSrcweir }; 151*cdf0e10cSrcweir 152*cdf0e10cSrcweir 153*cdf0e10cSrcweir //////////////////////// 154*cdf0e10cSrcweir //////////////////////// 155*cdf0e10cSrcweir // FUNCTION PARSER 156*cdf0e10cSrcweir //////////////////////// 157*cdf0e10cSrcweir //////////////////////// 158*cdf0e10cSrcweir 159*cdf0e10cSrcweir typedef const sal_Char* StringIteratorT; 160*cdf0e10cSrcweir 161*cdf0e10cSrcweir struct ParserContext 162*cdf0e10cSrcweir { 163*cdf0e10cSrcweir typedef ::std::stack< ExpressionNodeSharedPtr > OperandStack; 164*cdf0e10cSrcweir 165*cdf0e10cSrcweir // stores a stack of not-yet-evaluated operands. This is used 166*cdf0e10cSrcweir // by the operators (i.e. '+', '*', 'sin' etc.) to pop their 167*cdf0e10cSrcweir // arguments from. If all arguments to an operator are constant, 168*cdf0e10cSrcweir // the operator pushes a precalculated result on the stack, and 169*cdf0e10cSrcweir // a composite ExpressionNode otherwise. 170*cdf0e10cSrcweir OperandStack maOperandStack; 171*cdf0e10cSrcweir }; 172*cdf0e10cSrcweir 173*cdf0e10cSrcweir typedef ::boost::shared_ptr< ParserContext > ParserContextSharedPtr; 174*cdf0e10cSrcweir 175*cdf0e10cSrcweir /** Generate apriori constant value 176*cdf0e10cSrcweir */ 177*cdf0e10cSrcweir 178*cdf0e10cSrcweir class ConstantFunctor 179*cdf0e10cSrcweir { 180*cdf0e10cSrcweir ParserContextSharedPtr mpContext; 181*cdf0e10cSrcweir 182*cdf0e10cSrcweir public: 183*cdf0e10cSrcweir 184*cdf0e10cSrcweir ConstantFunctor( const ParserContextSharedPtr& rContext ) : 185*cdf0e10cSrcweir mpContext( rContext ) 186*cdf0e10cSrcweir { 187*cdf0e10cSrcweir } 188*cdf0e10cSrcweir void operator()( StringIteratorT rFirst,StringIteratorT rSecond) const 189*cdf0e10cSrcweir { 190*cdf0e10cSrcweir rtl::OUString sVal( rFirst, rSecond - rFirst, RTL_TEXTENCODING_UTF8 ); 191*cdf0e10cSrcweir mpContext->maOperandStack.push( ExpressionNodeSharedPtr( new ConstantValueExpression( new ORowSetValueDecorator( sVal ) ) ) ); 192*cdf0e10cSrcweir } 193*cdf0e10cSrcweir }; 194*cdf0e10cSrcweir 195*cdf0e10cSrcweir /** Generate parse-dependent-but-then-constant value 196*cdf0e10cSrcweir */ 197*cdf0e10cSrcweir class IntConstantFunctor 198*cdf0e10cSrcweir { 199*cdf0e10cSrcweir ParserContextSharedPtr mpContext; 200*cdf0e10cSrcweir 201*cdf0e10cSrcweir public: 202*cdf0e10cSrcweir IntConstantFunctor( const ParserContextSharedPtr& rContext ) : 203*cdf0e10cSrcweir mpContext( rContext ) 204*cdf0e10cSrcweir { 205*cdf0e10cSrcweir } 206*cdf0e10cSrcweir void operator()( sal_Int32 n ) const 207*cdf0e10cSrcweir { 208*cdf0e10cSrcweir mpContext->maOperandStack.push( ExpressionNodeSharedPtr( new ConstantValueExpression( new ORowSetValueDecorator( n ) ) ) ); 209*cdf0e10cSrcweir } 210*cdf0e10cSrcweir void operator()( StringIteratorT rFirst,StringIteratorT rSecond) const 211*cdf0e10cSrcweir { 212*cdf0e10cSrcweir rtl::OUString sVal( rFirst, rSecond - rFirst, RTL_TEXTENCODING_UTF8 ); 213*cdf0e10cSrcweir (void)sVal; 214*cdf0e10cSrcweir } 215*cdf0e10cSrcweir }; 216*cdf0e10cSrcweir 217*cdf0e10cSrcweir /** Implements a binary function over two ExpressionNodes 218*cdf0e10cSrcweir 219*cdf0e10cSrcweir @tpl Generator 220*cdf0e10cSrcweir Generator functor, to generate an ExpressionNode of 221*cdf0e10cSrcweir appropriate type 222*cdf0e10cSrcweir 223*cdf0e10cSrcweir */ 224*cdf0e10cSrcweir class BinaryFunctionFunctor 225*cdf0e10cSrcweir { 226*cdf0e10cSrcweir const ExpressionFunct meFunct; 227*cdf0e10cSrcweir ParserContextSharedPtr mpContext; 228*cdf0e10cSrcweir 229*cdf0e10cSrcweir public: 230*cdf0e10cSrcweir 231*cdf0e10cSrcweir BinaryFunctionFunctor( const ExpressionFunct eFunct, const ParserContextSharedPtr& rContext ) : 232*cdf0e10cSrcweir meFunct( eFunct ), 233*cdf0e10cSrcweir mpContext( rContext ) 234*cdf0e10cSrcweir { 235*cdf0e10cSrcweir } 236*cdf0e10cSrcweir 237*cdf0e10cSrcweir void operator()( StringIteratorT, StringIteratorT ) const 238*cdf0e10cSrcweir { 239*cdf0e10cSrcweir ParserContext::OperandStack& rNodeStack( mpContext->maOperandStack ); 240*cdf0e10cSrcweir 241*cdf0e10cSrcweir if( rNodeStack.size() < 2 ) 242*cdf0e10cSrcweir throw ParseError( "Not enough arguments for binary operator" ); 243*cdf0e10cSrcweir 244*cdf0e10cSrcweir // retrieve arguments 245*cdf0e10cSrcweir ExpressionNodeSharedPtr pSecondArg( rNodeStack.top() ); 246*cdf0e10cSrcweir rNodeStack.pop(); 247*cdf0e10cSrcweir ExpressionNodeSharedPtr pFirstArg( rNodeStack.top() ); 248*cdf0e10cSrcweir rNodeStack.pop(); 249*cdf0e10cSrcweir 250*cdf0e10cSrcweir // create combined ExpressionNode 251*cdf0e10cSrcweir ExpressionNodeSharedPtr pNode = ExpressionNodeSharedPtr( new BinaryFunctionExpression( meFunct, pFirstArg, pSecondArg ) ); 252*cdf0e10cSrcweir // check for constness 253*cdf0e10cSrcweir rNodeStack.push( pNode ); 254*cdf0e10cSrcweir } 255*cdf0e10cSrcweir }; 256*cdf0e10cSrcweir /** ExpressionNode implementation for unary 257*cdf0e10cSrcweir function over one ExpressionNode 258*cdf0e10cSrcweir */ 259*cdf0e10cSrcweir class UnaryFunctionExpression : public ExpressionNode 260*cdf0e10cSrcweir { 261*cdf0e10cSrcweir const ExpressionFunct meFunct; 262*cdf0e10cSrcweir ExpressionNodeSharedPtr mpArg; 263*cdf0e10cSrcweir 264*cdf0e10cSrcweir public: 265*cdf0e10cSrcweir UnaryFunctionExpression( const ExpressionFunct eFunct, const ExpressionNodeSharedPtr& rArg ) : 266*cdf0e10cSrcweir meFunct( eFunct ), 267*cdf0e10cSrcweir mpArg( rArg ) 268*cdf0e10cSrcweir { 269*cdf0e10cSrcweir } 270*cdf0e10cSrcweir virtual ORowSetValueDecoratorRef evaluate(const ODatabaseMetaDataResultSet::ORow& _aRow ) const 271*cdf0e10cSrcweir { 272*cdf0e10cSrcweir return _aRow[mpArg->evaluate(_aRow )->getValue().getInt32()]; 273*cdf0e10cSrcweir } 274*cdf0e10cSrcweir virtual void fill(const ODatabaseMetaDataResultSet::ORow& /*_aRow*/ ) const 275*cdf0e10cSrcweir { 276*cdf0e10cSrcweir } 277*cdf0e10cSrcweir virtual ExpressionFunct getType() const 278*cdf0e10cSrcweir { 279*cdf0e10cSrcweir return meFunct; 280*cdf0e10cSrcweir } 281*cdf0e10cSrcweir virtual ODatabaseMetaDataResultSet::ORow fillNode( std::vector< RowEquation >& /*rEquations*/, ExpressionNode* /* pOptionalArg */, sal_uInt32 /* nFlags */ ) 282*cdf0e10cSrcweir { 283*cdf0e10cSrcweir ODatabaseMetaDataResultSet::ORow aRet; 284*cdf0e10cSrcweir return aRet; 285*cdf0e10cSrcweir } 286*cdf0e10cSrcweir }; 287*cdf0e10cSrcweir 288*cdf0e10cSrcweir class UnaryFunctionFunctor 289*cdf0e10cSrcweir { 290*cdf0e10cSrcweir const ExpressionFunct meFunct; 291*cdf0e10cSrcweir ParserContextSharedPtr mpContext; 292*cdf0e10cSrcweir 293*cdf0e10cSrcweir public : 294*cdf0e10cSrcweir 295*cdf0e10cSrcweir UnaryFunctionFunctor( const ExpressionFunct eFunct, const ParserContextSharedPtr& rContext ) : 296*cdf0e10cSrcweir meFunct( eFunct ), 297*cdf0e10cSrcweir mpContext( rContext ) 298*cdf0e10cSrcweir { 299*cdf0e10cSrcweir } 300*cdf0e10cSrcweir void operator()( StringIteratorT, StringIteratorT ) const 301*cdf0e10cSrcweir { 302*cdf0e10cSrcweir 303*cdf0e10cSrcweir ParserContext::OperandStack& rNodeStack( mpContext->maOperandStack ); 304*cdf0e10cSrcweir 305*cdf0e10cSrcweir if( rNodeStack.size() < 1 ) 306*cdf0e10cSrcweir throw ParseError( "Not enough arguments for unary operator" ); 307*cdf0e10cSrcweir 308*cdf0e10cSrcweir // retrieve arguments 309*cdf0e10cSrcweir ExpressionNodeSharedPtr pArg( rNodeStack.top() ); 310*cdf0e10cSrcweir rNodeStack.pop(); 311*cdf0e10cSrcweir 312*cdf0e10cSrcweir rNodeStack.push( ExpressionNodeSharedPtr( new UnaryFunctionExpression( meFunct, pArg ) ) ); 313*cdf0e10cSrcweir } 314*cdf0e10cSrcweir }; 315*cdf0e10cSrcweir 316*cdf0e10cSrcweir /* This class implements the following grammar (more or 317*cdf0e10cSrcweir less literally written down below, only slightly 318*cdf0e10cSrcweir obfuscated by the parser actions): 319*cdf0e10cSrcweir 320*cdf0e10cSrcweir basic_expression = 321*cdf0e10cSrcweir number | 322*cdf0e10cSrcweir '(' additive_expression ')' 323*cdf0e10cSrcweir 324*cdf0e10cSrcweir unary_expression = 325*cdf0e10cSrcweir basic_expression 326*cdf0e10cSrcweir 327*cdf0e10cSrcweir multiplicative_expression = 328*cdf0e10cSrcweir unary_expression ( ( '*' unary_expression )* | 329*cdf0e10cSrcweir ( '/' unary_expression )* ) 330*cdf0e10cSrcweir 331*cdf0e10cSrcweir additive_expression = 332*cdf0e10cSrcweir multiplicative_expression ( ( '+' multiplicative_expression )* | 333*cdf0e10cSrcweir ( '-' multiplicative_expression )* ) 334*cdf0e10cSrcweir 335*cdf0e10cSrcweir */ 336*cdf0e10cSrcweir class ExpressionGrammar : public ::boost::spirit::grammar< ExpressionGrammar > 337*cdf0e10cSrcweir { 338*cdf0e10cSrcweir public: 339*cdf0e10cSrcweir /** Create an arithmetic expression grammar 340*cdf0e10cSrcweir 341*cdf0e10cSrcweir @param rParserContext 342*cdf0e10cSrcweir Contains context info for the parser 343*cdf0e10cSrcweir */ 344*cdf0e10cSrcweir ExpressionGrammar( const ParserContextSharedPtr& rParserContext ) : 345*cdf0e10cSrcweir mpParserContext( rParserContext ) 346*cdf0e10cSrcweir { 347*cdf0e10cSrcweir } 348*cdf0e10cSrcweir 349*cdf0e10cSrcweir template< typename ScannerT > class definition 350*cdf0e10cSrcweir { 351*cdf0e10cSrcweir public: 352*cdf0e10cSrcweir // grammar definition 353*cdf0e10cSrcweir definition( const ExpressionGrammar& self ) 354*cdf0e10cSrcweir { 355*cdf0e10cSrcweir using ::boost::spirit::str_p; 356*cdf0e10cSrcweir using ::boost::spirit::space_p; 357*cdf0e10cSrcweir using ::boost::spirit::range_p; 358*cdf0e10cSrcweir using ::boost::spirit::lexeme_d; 359*cdf0e10cSrcweir using ::boost::spirit::real_parser; 360*cdf0e10cSrcweir using ::boost::spirit::chseq_p; 361*cdf0e10cSrcweir using ::boost::spirit::ch_p; 362*cdf0e10cSrcweir using ::boost::spirit::int_p; 363*cdf0e10cSrcweir using ::boost::spirit::as_lower_d; 364*cdf0e10cSrcweir using ::boost::spirit::strlit; 365*cdf0e10cSrcweir using ::boost::spirit::inhibit_case; 366*cdf0e10cSrcweir 367*cdf0e10cSrcweir 368*cdf0e10cSrcweir typedef inhibit_case<strlit<> > token_t; 369*cdf0e10cSrcweir token_t COLUMN = as_lower_d[ "column" ]; 370*cdf0e10cSrcweir token_t OR_ = as_lower_d[ "or" ]; 371*cdf0e10cSrcweir token_t AND_ = as_lower_d[ "and" ]; 372*cdf0e10cSrcweir 373*cdf0e10cSrcweir integer = 374*cdf0e10cSrcweir int_p 375*cdf0e10cSrcweir [IntConstantFunctor(self.getContext())]; 376*cdf0e10cSrcweir 377*cdf0e10cSrcweir argument = 378*cdf0e10cSrcweir integer 379*cdf0e10cSrcweir | lexeme_d[ +( range_p('a','z') | range_p('A','Z') | range_p('0','9') ) ] 380*cdf0e10cSrcweir [ ConstantFunctor(self.getContext()) ] 381*cdf0e10cSrcweir ; 382*cdf0e10cSrcweir 383*cdf0e10cSrcweir unaryFunction = 384*cdf0e10cSrcweir (COLUMN >> '(' >> integer >> ')' ) 385*cdf0e10cSrcweir [ UnaryFunctionFunctor( UNARY_FUNC_COLUMN, self.getContext()) ] 386*cdf0e10cSrcweir ; 387*cdf0e10cSrcweir 388*cdf0e10cSrcweir assignment = 389*cdf0e10cSrcweir unaryFunction >> ch_p('=') >> argument 390*cdf0e10cSrcweir [ BinaryFunctionFunctor( ENUM_FUNC_EQUATION, self.getContext()) ] 391*cdf0e10cSrcweir ; 392*cdf0e10cSrcweir 393*cdf0e10cSrcweir andExpression = 394*cdf0e10cSrcweir assignment 395*cdf0e10cSrcweir | ( '(' >> orExpression >> ')' ) 396*cdf0e10cSrcweir | ( assignment >> AND_ >> assignment ) [ BinaryFunctionFunctor( ENUM_FUNC_AND, self.getContext()) ] 397*cdf0e10cSrcweir ; 398*cdf0e10cSrcweir 399*cdf0e10cSrcweir orExpression = 400*cdf0e10cSrcweir andExpression 401*cdf0e10cSrcweir | ( orExpression >> OR_ >> andExpression ) [ BinaryFunctionFunctor( ENUM_FUNC_OR, self.getContext()) ] 402*cdf0e10cSrcweir ; 403*cdf0e10cSrcweir 404*cdf0e10cSrcweir basicExpression = 405*cdf0e10cSrcweir orExpression 406*cdf0e10cSrcweir ; 407*cdf0e10cSrcweir 408*cdf0e10cSrcweir BOOST_SPIRIT_DEBUG_RULE(basicExpression); 409*cdf0e10cSrcweir BOOST_SPIRIT_DEBUG_RULE(unaryFunction); 410*cdf0e10cSrcweir BOOST_SPIRIT_DEBUG_RULE(assignment); 411*cdf0e10cSrcweir BOOST_SPIRIT_DEBUG_RULE(argument); 412*cdf0e10cSrcweir BOOST_SPIRIT_DEBUG_RULE(integer); 413*cdf0e10cSrcweir BOOST_SPIRIT_DEBUG_RULE(orExpression); 414*cdf0e10cSrcweir BOOST_SPIRIT_DEBUG_RULE(andExpression); 415*cdf0e10cSrcweir } 416*cdf0e10cSrcweir 417*cdf0e10cSrcweir const ::boost::spirit::rule< ScannerT >& start() const 418*cdf0e10cSrcweir { 419*cdf0e10cSrcweir return basicExpression; 420*cdf0e10cSrcweir } 421*cdf0e10cSrcweir 422*cdf0e10cSrcweir private: 423*cdf0e10cSrcweir // the constituents of the Spirit arithmetic expression grammar. 424*cdf0e10cSrcweir // For the sake of readability, without 'ma' prefix. 425*cdf0e10cSrcweir ::boost::spirit::rule< ScannerT > basicExpression; 426*cdf0e10cSrcweir ::boost::spirit::rule< ScannerT > unaryFunction; 427*cdf0e10cSrcweir ::boost::spirit::rule< ScannerT > assignment; 428*cdf0e10cSrcweir ::boost::spirit::rule< ScannerT > integer,argument; 429*cdf0e10cSrcweir ::boost::spirit::rule< ScannerT > orExpression,andExpression; 430*cdf0e10cSrcweir }; 431*cdf0e10cSrcweir 432*cdf0e10cSrcweir const ParserContextSharedPtr& getContext() const 433*cdf0e10cSrcweir { 434*cdf0e10cSrcweir return mpParserContext; 435*cdf0e10cSrcweir } 436*cdf0e10cSrcweir 437*cdf0e10cSrcweir private: 438*cdf0e10cSrcweir ParserContextSharedPtr mpParserContext; // might get modified during parsing 439*cdf0e10cSrcweir }; 440*cdf0e10cSrcweir 441*cdf0e10cSrcweir #ifdef BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE 442*cdf0e10cSrcweir const ParserContextSharedPtr& getParserContext() 443*cdf0e10cSrcweir { 444*cdf0e10cSrcweir static ParserContextSharedPtr lcl_parserContext( new ParserContext() ); 445*cdf0e10cSrcweir 446*cdf0e10cSrcweir // clear node stack (since we reuse the static object, that's 447*cdf0e10cSrcweir // the whole point here) 448*cdf0e10cSrcweir while( !lcl_parserContext->maOperandStack.empty() ) 449*cdf0e10cSrcweir lcl_parserContext->maOperandStack.pop(); 450*cdf0e10cSrcweir 451*cdf0e10cSrcweir return lcl_parserContext; 452*cdf0e10cSrcweir } 453*cdf0e10cSrcweir #endif 454*cdf0e10cSrcweir } 455*cdf0e10cSrcweir 456*cdf0e10cSrcweir ExpressionNodeSharedPtr FunctionParser::parseFunction( const ::rtl::OUString& _sFunction) 457*cdf0e10cSrcweir { 458*cdf0e10cSrcweir // TODO(Q1): Check if a combination of the RTL_UNICODETOTEXT_FLAGS_* 459*cdf0e10cSrcweir // gives better conversion robustness here (we might want to map space 460*cdf0e10cSrcweir // etc. to ASCII space here) 461*cdf0e10cSrcweir const ::rtl::OString& rAsciiFunction( 462*cdf0e10cSrcweir rtl::OUStringToOString( _sFunction, RTL_TEXTENCODING_ASCII_US ) ); 463*cdf0e10cSrcweir 464*cdf0e10cSrcweir StringIteratorT aStart( rAsciiFunction.getStr() ); 465*cdf0e10cSrcweir StringIteratorT aEnd( rAsciiFunction.getStr()+rAsciiFunction.getLength() ); 466*cdf0e10cSrcweir 467*cdf0e10cSrcweir ParserContextSharedPtr pContext; 468*cdf0e10cSrcweir 469*cdf0e10cSrcweir #ifdef BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE 470*cdf0e10cSrcweir // static parser context, because the actual 471*cdf0e10cSrcweir // Spirit parser is also a static object 472*cdf0e10cSrcweir pContext = getParserContext(); 473*cdf0e10cSrcweir #else 474*cdf0e10cSrcweir pContext.reset( new ParserContext() ); 475*cdf0e10cSrcweir #endif 476*cdf0e10cSrcweir 477*cdf0e10cSrcweir ExpressionGrammar aExpressionGrammer( pContext ); 478*cdf0e10cSrcweir 479*cdf0e10cSrcweir const ::boost::spirit::parse_info<StringIteratorT> aParseInfo( 480*cdf0e10cSrcweir ::boost::spirit::parse( aStart, 481*cdf0e10cSrcweir aEnd, 482*cdf0e10cSrcweir aExpressionGrammer, 483*cdf0e10cSrcweir ::boost::spirit::space_p ) ); 484*cdf0e10cSrcweir 485*cdf0e10cSrcweir OSL_DEBUG_ONLY(::std::cout.flush()); // needed to keep stdout and cout in sync 486*cdf0e10cSrcweir 487*cdf0e10cSrcweir // input fully congested by the parser? 488*cdf0e10cSrcweir if( !aParseInfo.full ) 489*cdf0e10cSrcweir throw ParseError( "RowFunctionParser::parseFunction(): string not fully parseable" ); 490*cdf0e10cSrcweir 491*cdf0e10cSrcweir // parser's state stack now must contain exactly _one_ ExpressionNode, 492*cdf0e10cSrcweir // which represents our formula. 493*cdf0e10cSrcweir if( pContext->maOperandStack.size() != 1 ) 494*cdf0e10cSrcweir throw ParseError( "RowFunctionParser::parseFunction(): incomplete or empty expression" ); 495*cdf0e10cSrcweir 496*cdf0e10cSrcweir return pContext->maOperandStack.top(); 497*cdf0e10cSrcweir } 498*cdf0e10cSrcweir } 499*cdf0e10cSrcweir 500