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