25#define BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE
27#if OSL_DEBUG_LEVEL >= 2 && defined(DBG_UTIL)
29#define BOOST_SPIRIT_DEBUG
31#include <boost/spirit/include/classic_core.hpp>
33#include <rtl/ustring.hxx>
36#if (OSL_DEBUG_LEVEL > 0)
54class ConstantValueExpression :
public ExpressionNode
77class BinaryFunctionExpression :
public ExpressionNode
85 BinaryFunctionExpression(
const ExpressionFunct eFunct, std::shared_ptr<ExpressionNode> xFirstArg, std::shared_ptr<ExpressionNode> xSecondArg ) :
97 aRet =
new ORowSetValueDecorator( ORowSetValue(
mpFirstArg->evaluate(_aRow )->getValue() ==
mpSecondArg->evaluate(_aRow )->getValue()) );
100 aRet =
new ORowSetValueDecorator( ORowSetValue(
mpFirstArg->evaluate(_aRow )->getValue().getBool() &&
mpSecondArg->evaluate(_aRow )->getValue().getBool()) );
103 aRet =
new ORowSetValueDecorator( ORowSetValue(
mpFirstArg->evaluate(_aRow )->getValue().getBool() ||
mpSecondArg->evaluate(_aRow )->getValue().getBool()) );
127typedef const char* StringIteratorT;
131 typedef std::stack< std::shared_ptr<ExpressionNode> > OperandStack;
141typedef std::shared_ptr< ParserContext > ParserContextSharedPtr;
152 explicit ConstantFunctor( ParserContextSharedPtr xContext ) :
156 void operator()( StringIteratorT rFirst,StringIteratorT rSecond)
const
158 OUString sVal( rFirst, rSecond - rFirst, RTL_TEXTENCODING_UTF8 );
159 mpContext->maOperandStack.push( std::make_shared<ConstantValueExpression>(
new ORowSetValueDecorator( sVal ) ) );
165class IntConstantFunctor
170 explicit IntConstantFunctor( ParserContextSharedPtr xContext ) :
174 void operator()( sal_Int32 n )
const
176 mpContext->maOperandStack.push( std::make_shared<ConstantValueExpression>(
new ORowSetValueDecorator( n ) ) );
187class BinaryFunctionFunctor
194 BinaryFunctionFunctor(
const ExpressionFunct eFunct, ParserContextSharedPtr xContext ) :
200 void operator()( StringIteratorT, StringIteratorT )
const
202 ParserContext::OperandStack& rNodeStack(
mpContext->maOperandStack );
204 if( rNodeStack.size() < 2 )
205 throw ParseError(
"Not enough arguments for binary operator" );
208 std::shared_ptr<ExpressionNode> pSecondArg( std::move(rNodeStack.top()) );
210 std::shared_ptr<ExpressionNode> pFirstArg( std::move(rNodeStack.top()) );
214 auto pNode = std::make_shared<BinaryFunctionExpression>(
meFunct, pFirstArg, pSecondArg );
216 rNodeStack.push( pNode );
222class UnaryFunctionExpression :
public ExpressionNode
224 std::shared_ptr<ExpressionNode>
mpArg;
227 explicit UnaryFunctionExpression( std::shared_ptr<ExpressionNode> xArg ) :
233 return _aRow[
mpArg->evaluate(_aRow )->getValue().getUInt32()];
240class UnaryFunctionFunctor
246 explicit UnaryFunctionFunctor(ParserContextSharedPtr xContext)
250 void operator()( StringIteratorT, StringIteratorT )
const
253 ParserContext::OperandStack& rNodeStack(
mpContext->maOperandStack );
255 if( rNodeStack.empty() )
256 throw ParseError(
"Not enough arguments for unary operator" );
259 std::shared_ptr<ExpressionNode> pArg( std::move(rNodeStack.top()) );
262 rNodeStack.push( std::make_shared<UnaryFunctionExpression>( pArg ) );
286class ExpressionGrammar :
public ::boost::spirit::classic::grammar< ExpressionGrammar >
294 explicit ExpressionGrammar( ParserContextSharedPtr xParserContext ) :
299 template<
typename ScannerT >
class definition
303 explicit definition(
const ExpressionGrammar& self )
305 using ::boost::spirit::classic::space_p;
306 using ::boost::spirit::classic::range_p;
307 using ::boost::spirit::classic::lexeme_d;
308 using ::boost::spirit::classic::ch_p;
309 using ::boost::spirit::classic::int_p;
310 using ::boost::spirit::classic::as_lower_d;
311 using ::boost::spirit::classic::strlit;
312 using ::boost::spirit::classic::inhibit_case;
315 typedef inhibit_case<strlit<> > token_t;
316 token_t
COLUMN = as_lower_d[
"column" ];
317 token_t
OR_ = as_lower_d[
"or" ];
318 token_t
AND_ = as_lower_d[
"and" ];
322 [IntConstantFunctor(self.getContext())];
326 | lexeme_d[ +( range_p(
'a',
'z') | range_p(
'A',
'Z') | range_p(
'0',
'9') ) ]
327 [ ConstantFunctor(self.getContext()) ]
332 [ UnaryFunctionFunctor( self.getContext()) ]
359 BOOST_SPIRIT_DEBUG_RULE(
integer);
364 const ::boost::spirit::classic::rule< ScannerT >&
start()
const
379 const ParserContextSharedPtr& getContext()
const
388const ParserContextSharedPtr& getParserContext()
390 static ParserContextSharedPtr lcl_parserContext = std::make_shared<ParserContext>();
394 while( !lcl_parserContext->maOperandStack.empty() )
395 lcl_parserContext->maOperandStack.pop();
397 return lcl_parserContext;
407 const OString& rAsciiFunction(
410 StringIteratorT aStart( rAsciiFunction.getStr() );
411 StringIteratorT aEnd( rAsciiFunction.getStr()+rAsciiFunction.getLength() );
415 ParserContextSharedPtr pContext = getParserContext();
417 ExpressionGrammar aExpressionGrammer( pContext );
419 const ::boost::spirit::classic::parse_info<StringIteratorT> aParseInfo(
420 ::boost::spirit::classic::parse( aStart,
423 ::boost::spirit::classic::space_p ) );
425#if (OSL_DEBUG_LEVEL > 0)
430 if( !aParseInfo.full )
431 throw ParseError(
"RowFunctionParser::parseFunction(): string not fully parseable" );
435 if( pContext->maOperandStack.size() != 1 )
436 throw ParseError(
"RowFunctionParser::parseFunction(): incomplete or empty expression" );
438 return pContext->maOperandStack.top();
::boost::spirit::classic::rule< ScannerT > integer
::boost::spirit::classic::rule< ScannerT > assignment
ParserContextSharedPtr mpParserContext
const ExpressionFunct meFunct
OperandStack maOperandStack
ORowSetValueDecoratorRef maValue
::boost::spirit::classic::rule< ScannerT > orExpression
::boost::spirit::classic::rule< ScannerT > andExpression
std::shared_ptr< ExpressionNode > mpFirstArg
::boost::spirit::classic::rule< ScannerT > argument
ParserContextSharedPtr mpContext
std::shared_ptr< ExpressionNode > mpArg
::boost::spirit::classic::rule< ScannerT > basicExpression
std::shared_ptr< ExpressionNode > mpSecondArg
::boost::spirit::classic::rule< ScannerT > unaryFunction
static std::shared_ptr< ExpressionNode > const & parseFunction(const OUString &_sFunction)
Parse a string.
::rtl::Reference< ORowSetValueDecorator > ORowSetValueDecoratorRef
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
This exception is thrown, when the arithmetic expression parser failed to parse a string.