summaryrefslogtreecommitdiff
path: root/connectivity/source/commontools/RowFunctionParser.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'connectivity/source/commontools/RowFunctionParser.cxx')
-rw-r--r--connectivity/source/commontools/RowFunctionParser.cxx501
1 files changed, 0 insertions, 501 deletions
diff --git a/connectivity/source/commontools/RowFunctionParser.cxx b/connectivity/source/commontools/RowFunctionParser.cxx
deleted file mode 100644
index 590cfb6489..0000000000
--- a/connectivity/source/commontools/RowFunctionParser.cxx
+++ /dev/null
@@ -1,501 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright 2000, 2010 Oracle and/or its affiliates.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * This file is part of OpenOffice.org.
- *
- * OpenOffice.org is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 3
- * only, as published by the Free Software Foundation.
- *
- * OpenOffice.org is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License version 3 for more details
- * (a copy is included in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU Lesser General Public License
- * version 3 along with OpenOffice.org. If not, see
- * <http://www.openoffice.org/license.html>
- * for a copy of the LGPLv3 License.
- *
- ************************************************************************/
-
-// MARKER(update_precomp.py): autogen include statement, do not remove
-#include "precompiled_connectivity.hxx"
-
-// Makes parser a static resource,
-// we're synchronized externally.
-// But watch out, the parser might have
-// state not visible to this code!
-#define BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE
-#if defined(VERBOSE) && defined(DBG_UTIL)
-#include <typeinfo>
-#define BOOST_SPIRIT_DEBUG
-#endif
-#include <boost/spirit/include/classic_core.hpp>
-#include "RowFunctionParser.hxx"
-#include <rtl/ustring.hxx>
-#include <tools/fract.hxx>
-
-
-
-#if (OSL_DEBUG_LEVEL > 0)
-#include <iostream>
-#endif
-#include <functional>
-#include <algorithm>
-#include <stack>
-
-namespace connectivity
-{
-using namespace com::sun::star;
-
-namespace
-{
-//////////////////////
-//////////////////////
-// EXPRESSION NODES
-//////////////////////
-//////////////////////
-class ConstantValueExpression : public ExpressionNode
-{
- ORowSetValueDecoratorRef maValue;
-
-public:
-
- ConstantValueExpression( ORowSetValueDecoratorRef rValue ) :
- maValue( rValue )
- {
- }
- virtual ORowSetValueDecoratorRef evaluate(const ODatabaseMetaDataResultSet::ORow& /*_aRow*/ ) const
- {
- return maValue;
- }
- virtual void fill(const ODatabaseMetaDataResultSet::ORow& /*_aRow*/ ) const
- {
- }
- virtual ExpressionFunct getType() const
- {
- return FUNC_CONST;
- }
- virtual ODatabaseMetaDataResultSet::ORow fillNode( std::vector< RowEquation >& /*rEquations*/, ExpressionNode* /* pOptionalArg */, sal_uInt32 /* nFlags */ )
- {
- ODatabaseMetaDataResultSet::ORow aRet;
- return aRet;
- }
-};
-
-
-/** ExpressionNode implementation for unary
- function over two ExpressionNodes
- */
-class BinaryFunctionExpression : public ExpressionNode
-{
- const ExpressionFunct meFunct;
- ExpressionNodeSharedPtr mpFirstArg;
- ExpressionNodeSharedPtr mpSecondArg;
-
-public:
-
- BinaryFunctionExpression( const ExpressionFunct eFunct, const ExpressionNodeSharedPtr& rFirstArg, const ExpressionNodeSharedPtr& rSecondArg ) :
- meFunct( eFunct ),
- mpFirstArg( rFirstArg ),
- mpSecondArg( rSecondArg )
- {
- }
- virtual ORowSetValueDecoratorRef evaluate(const ODatabaseMetaDataResultSet::ORow& _aRow ) const
- {
- ORowSetValueDecoratorRef aRet;
- switch(meFunct)
- {
- case ENUM_FUNC_EQUATION:
- aRet = new ORowSetValueDecorator(sal_Bool(mpFirstArg->evaluate(_aRow )->getValue() == mpSecondArg->evaluate(_aRow )->getValue()) );
- break;
- case ENUM_FUNC_AND:
- aRet = new ORowSetValueDecorator( sal_Bool(mpFirstArg->evaluate(_aRow )->getValue().getBool() && mpSecondArg->evaluate(_aRow )->getValue().getBool()) );
- break;
- case ENUM_FUNC_OR:
- aRet = new ORowSetValueDecorator( sal_Bool(mpFirstArg->evaluate(_aRow )->getValue().getBool() || mpSecondArg->evaluate(_aRow )->getValue().getBool()) );
- break;
- default:
- break;
- }
- return aRet;
- }
- virtual void fill(const ODatabaseMetaDataResultSet::ORow& _aRow ) const
- {
- switch(meFunct)
- {
- case ENUM_FUNC_EQUATION:
- (*mpFirstArg->evaluate(_aRow )) = mpSecondArg->evaluate(_aRow )->getValue();
- break;
- default:
- break;
- }
- }
- virtual ExpressionFunct getType() const
- {
- return meFunct;
- }
- virtual ODatabaseMetaDataResultSet::ORow fillNode( std::vector< RowEquation >& /*rEquations*/, ExpressionNode* /*pOptionalArg*/, sal_uInt32 /*nFlags*/ )
- {
- ODatabaseMetaDataResultSet::ORow aRet;
- return aRet;
- }
-};
-
-
-////////////////////////
-////////////////////////
-// FUNCTION PARSER
-////////////////////////
-////////////////////////
-
-typedef const sal_Char* StringIteratorT;
-
-struct ParserContext
-{
- typedef ::std::stack< ExpressionNodeSharedPtr > OperandStack;
-
- // stores a stack of not-yet-evaluated operands. This is used
- // by the operators (i.e. '+', '*', 'sin' etc.) to pop their
- // arguments from. If all arguments to an operator are constant,
- // the operator pushes a precalculated result on the stack, and
- // a composite ExpressionNode otherwise.
- OperandStack maOperandStack;
-};
-
-typedef ::boost::shared_ptr< ParserContext > ParserContextSharedPtr;
-
-/** Generate apriori constant value
- */
-
-class ConstantFunctor
-{
- ParserContextSharedPtr mpContext;
-
-public:
-
- ConstantFunctor( const ParserContextSharedPtr& rContext ) :
- mpContext( rContext )
- {
- }
- void operator()( StringIteratorT rFirst,StringIteratorT rSecond) const
- {
- rtl::OUString sVal( rFirst, rSecond - rFirst, RTL_TEXTENCODING_UTF8 );
- mpContext->maOperandStack.push( ExpressionNodeSharedPtr( new ConstantValueExpression( new ORowSetValueDecorator( sVal ) ) ) );
- }
-};
-
-/** Generate parse-dependent-but-then-constant value
- */
-class IntConstantFunctor
-{
- ParserContextSharedPtr mpContext;
-
-public:
- IntConstantFunctor( const ParserContextSharedPtr& rContext ) :
- mpContext( rContext )
- {
- }
- void operator()( sal_Int32 n ) const
- {
- mpContext->maOperandStack.push( ExpressionNodeSharedPtr( new ConstantValueExpression( new ORowSetValueDecorator( n ) ) ) );
- }
- void operator()( StringIteratorT rFirst,StringIteratorT rSecond) const
- {
- rtl::OUString sVal( rFirst, rSecond - rFirst, RTL_TEXTENCODING_UTF8 );
- (void)sVal;
- }
-};
-
-/** Implements a binary function over two ExpressionNodes
-
- @tpl Generator
- Generator functor, to generate an ExpressionNode of
- appropriate type
-
- */
-class BinaryFunctionFunctor
-{
- const ExpressionFunct meFunct;
- ParserContextSharedPtr mpContext;
-
-public:
-
- BinaryFunctionFunctor( const ExpressionFunct eFunct, const ParserContextSharedPtr& rContext ) :
- meFunct( eFunct ),
- mpContext( rContext )
- {
- }
-
- void operator()( StringIteratorT, StringIteratorT ) const
- {
- ParserContext::OperandStack& rNodeStack( mpContext->maOperandStack );
-
- if( rNodeStack.size() < 2 )
- throw ParseError( "Not enough arguments for binary operator" );
-
- // retrieve arguments
- ExpressionNodeSharedPtr pSecondArg( rNodeStack.top() );
- rNodeStack.pop();
- ExpressionNodeSharedPtr pFirstArg( rNodeStack.top() );
- rNodeStack.pop();
-
- // create combined ExpressionNode
- ExpressionNodeSharedPtr pNode = ExpressionNodeSharedPtr( new BinaryFunctionExpression( meFunct, pFirstArg, pSecondArg ) );
- // check for constness
- rNodeStack.push( pNode );
- }
-};
-/** ExpressionNode implementation for unary
- function over one ExpressionNode
- */
-class UnaryFunctionExpression : public ExpressionNode
-{
- const ExpressionFunct meFunct;
- ExpressionNodeSharedPtr mpArg;
-
-public:
- UnaryFunctionExpression( const ExpressionFunct eFunct, const ExpressionNodeSharedPtr& rArg ) :
- meFunct( eFunct ),
- mpArg( rArg )
- {
- }
- virtual ORowSetValueDecoratorRef evaluate(const ODatabaseMetaDataResultSet::ORow& _aRow ) const
- {
- return _aRow[mpArg->evaluate(_aRow )->getValue().getInt32()];
- }
- virtual void fill(const ODatabaseMetaDataResultSet::ORow& /*_aRow*/ ) const
- {
- }
- virtual ExpressionFunct getType() const
- {
- return meFunct;
- }
- virtual ODatabaseMetaDataResultSet::ORow fillNode( std::vector< RowEquation >& /*rEquations*/, ExpressionNode* /* pOptionalArg */, sal_uInt32 /* nFlags */ )
- {
- ODatabaseMetaDataResultSet::ORow aRet;
- return aRet;
- }
-};
-
-class UnaryFunctionFunctor
-{
- const ExpressionFunct meFunct;
- ParserContextSharedPtr mpContext;
-
-public :
-
- UnaryFunctionFunctor( const ExpressionFunct eFunct, const ParserContextSharedPtr& rContext ) :
- meFunct( eFunct ),
- mpContext( rContext )
- {
- }
- void operator()( StringIteratorT, StringIteratorT ) const
- {
-
- ParserContext::OperandStack& rNodeStack( mpContext->maOperandStack );
-
- if( rNodeStack.size() < 1 )
- throw ParseError( "Not enough arguments for unary operator" );
-
- // retrieve arguments
- ExpressionNodeSharedPtr pArg( rNodeStack.top() );
- rNodeStack.pop();
-
- rNodeStack.push( ExpressionNodeSharedPtr( new UnaryFunctionExpression( meFunct, pArg ) ) );
- }
-};
-
-/* This class implements the following grammar (more or
- less literally written down below, only slightly
- obfuscated by the parser actions):
-
- basic_expression =
- number |
- '(' additive_expression ')'
-
- unary_expression =
- basic_expression
-
- multiplicative_expression =
- unary_expression ( ( '*' unary_expression )* |
- ( '/' unary_expression )* )
-
- additive_expression =
- multiplicative_expression ( ( '+' multiplicative_expression )* |
- ( '-' multiplicative_expression )* )
-
- */
-class ExpressionGrammar : public ::boost::spirit::grammar< ExpressionGrammar >
-{
-public:
- /** Create an arithmetic expression grammar
-
- @param rParserContext
- Contains context info for the parser
- */
- ExpressionGrammar( const ParserContextSharedPtr& rParserContext ) :
- mpParserContext( rParserContext )
- {
- }
-
- template< typename ScannerT > class definition
- {
- public:
- // grammar definition
- definition( const ExpressionGrammar& self )
- {
- using ::boost::spirit::str_p;
- using ::boost::spirit::space_p;
- using ::boost::spirit::range_p;
- using ::boost::spirit::lexeme_d;
- using ::boost::spirit::real_parser;
- using ::boost::spirit::chseq_p;
- using ::boost::spirit::ch_p;
- using ::boost::spirit::int_p;
- using ::boost::spirit::as_lower_d;
- using ::boost::spirit::strlit;
- using ::boost::spirit::inhibit_case;
-
-
- typedef inhibit_case<strlit<> > token_t;
- token_t COLUMN = as_lower_d[ "column" ];
- token_t OR_ = as_lower_d[ "or" ];
- token_t AND_ = as_lower_d[ "and" ];
-
- integer =
- int_p
- [IntConstantFunctor(self.getContext())];
-
- argument =
- integer
- | lexeme_d[ +( range_p('a','z') | range_p('A','Z') | range_p('0','9') ) ]
- [ ConstantFunctor(self.getContext()) ]
- ;
-
- unaryFunction =
- (COLUMN >> '(' >> integer >> ')' )
- [ UnaryFunctionFunctor( UNARY_FUNC_COLUMN, self.getContext()) ]
- ;
-
- assignment =
- unaryFunction >> ch_p('=') >> argument
- [ BinaryFunctionFunctor( ENUM_FUNC_EQUATION, self.getContext()) ]
- ;
-
- andExpression =
- assignment
- | ( '(' >> orExpression >> ')' )
- | ( assignment >> AND_ >> assignment ) [ BinaryFunctionFunctor( ENUM_FUNC_AND, self.getContext()) ]
- ;
-
- orExpression =
- andExpression
- | ( orExpression >> OR_ >> andExpression ) [ BinaryFunctionFunctor( ENUM_FUNC_OR, self.getContext()) ]
- ;
-
- basicExpression =
- orExpression
- ;
-
- BOOST_SPIRIT_DEBUG_RULE(basicExpression);
- BOOST_SPIRIT_DEBUG_RULE(unaryFunction);
- BOOST_SPIRIT_DEBUG_RULE(assignment);
- BOOST_SPIRIT_DEBUG_RULE(argument);
- BOOST_SPIRIT_DEBUG_RULE(integer);
- BOOST_SPIRIT_DEBUG_RULE(orExpression);
- BOOST_SPIRIT_DEBUG_RULE(andExpression);
- }
-
- const ::boost::spirit::rule< ScannerT >& start() const
- {
- return basicExpression;
- }
-
- private:
- // the constituents of the Spirit arithmetic expression grammar.
- // For the sake of readability, without 'ma' prefix.
- ::boost::spirit::rule< ScannerT > basicExpression;
- ::boost::spirit::rule< ScannerT > unaryFunction;
- ::boost::spirit::rule< ScannerT > assignment;
- ::boost::spirit::rule< ScannerT > integer,argument;
- ::boost::spirit::rule< ScannerT > orExpression,andExpression;
- };
-
- const ParserContextSharedPtr& getContext() const
- {
- return mpParserContext;
- }
-
-private:
- ParserContextSharedPtr mpParserContext; // might get modified during parsing
-};
-
-#ifdef BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE
-const ParserContextSharedPtr& getParserContext()
-{
- static ParserContextSharedPtr lcl_parserContext( new ParserContext() );
-
- // clear node stack (since we reuse the static object, that's
- // the whole point here)
- while( !lcl_parserContext->maOperandStack.empty() )
- lcl_parserContext->maOperandStack.pop();
-
- return lcl_parserContext;
-}
-#endif
-}
-
-ExpressionNodeSharedPtr FunctionParser::parseFunction( const ::rtl::OUString& _sFunction)
-{
- // TODO(Q1): Check if a combination of the RTL_UNICODETOTEXT_FLAGS_*
- // gives better conversion robustness here (we might want to map space
- // etc. to ASCII space here)
- const ::rtl::OString& rAsciiFunction(
- rtl::OUStringToOString( _sFunction, RTL_TEXTENCODING_ASCII_US ) );
-
- StringIteratorT aStart( rAsciiFunction.getStr() );
- StringIteratorT aEnd( rAsciiFunction.getStr()+rAsciiFunction.getLength() );
-
- ParserContextSharedPtr pContext;
-
-#ifdef BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE
- // static parser context, because the actual
- // Spirit parser is also a static object
- pContext = getParserContext();
-#else
- pContext.reset( new ParserContext() );
-#endif
-
- ExpressionGrammar aExpressionGrammer( pContext );
-
- const ::boost::spirit::parse_info<StringIteratorT> aParseInfo(
- ::boost::spirit::parse( aStart,
- aEnd,
- aExpressionGrammer,
- ::boost::spirit::space_p ) );
-
- OSL_DEBUG_ONLY(::std::cout.flush()); // needed to keep stdout and cout in sync
-
- // input fully congested by the parser?
- if( !aParseInfo.full )
- throw ParseError( "RowFunctionParser::parseFunction(): string not fully parseable" );
-
- // parser's state stack now must contain exactly _one_ ExpressionNode,
- // which represents our formula.
- if( pContext->maOperandStack.size() != 1 )
- throw ParseError( "RowFunctionParser::parseFunction(): incomplete or empty expression" );
-
- return pContext->maOperandStack.top();
-}
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */