|
|
|
/*
|
|
|
|
Copyright (c) 2006 Gábor Lehel <illissius@gmail.com>
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU Library General Public
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This library 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
|
|
|
|
Library General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "expression.h"
|
|
|
|
|
|
|
|
ExpressionParser::ExpressionParser( const TQString &expression )
|
|
|
|
: m_expression( expression )
|
|
|
|
, m_state( ExpectMinus )
|
|
|
|
, m_haveGroup( false )
|
|
|
|
, m_inQuote( false )
|
|
|
|
, m_inOrGroup( false )
|
|
|
|
{ }
|
|
|
|
|
|
|
|
ParsedExpression ExpressionParser::parse()
|
|
|
|
{
|
|
|
|
const uint length = m_expression.length();
|
|
|
|
for( uint pos = 0; pos < length; ++pos )
|
|
|
|
parseChar( m_expression.constref( pos ) );
|
|
|
|
finishedToken();
|
|
|
|
finishedOrGroup();
|
|
|
|
return m_parsed;
|
|
|
|
}
|
|
|
|
|
|
|
|
ParsedExpression ExpressionParser::parse( const TQString &expression ) //static
|
|
|
|
{
|
|
|
|
ExpressionParser p( expression );
|
|
|
|
return p.parse();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ExpressionParser::isAdvancedExpression( const TQString &expression ) //static
|
|
|
|
{
|
|
|
|
return ( expression.tqcontains( '"' ) ||
|
|
|
|
expression.tqcontains( ':' ) ||
|
|
|
|
expression.tqcontains( '-' ) ||
|
|
|
|
expression.tqcontains( "AND" ) ||
|
|
|
|
expression.tqcontains( "OR" ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
/* PRIVATE */
|
|
|
|
|
|
|
|
void ExpressionParser::parseChar( const TQChar &c )
|
|
|
|
{
|
|
|
|
if( m_inQuote && c != '"' )
|
|
|
|
m_string += c;
|
|
|
|
else if( c.isSpace() )
|
|
|
|
handleSpace( c );
|
|
|
|
else if( c == '-' )
|
|
|
|
handleMinus( c );
|
|
|
|
else if( c == ':' )
|
|
|
|
handleColon( c );
|
|
|
|
else if( c == '>' || c == '<' )
|
|
|
|
handleMod( c );
|
|
|
|
else if( c == '"' )
|
|
|
|
handleQuote( c );
|
|
|
|
else
|
|
|
|
handleChar( c );
|
|
|
|
}
|
|
|
|
|
|
|
|
void ExpressionParser::handleSpace( const TQChar& )
|
|
|
|
{
|
|
|
|
if( m_state > ExpectMinus )
|
|
|
|
finishedToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ExpressionParser::handleMinus( const TQChar &c )
|
|
|
|
{
|
|
|
|
if( m_state == ExpectMinus )
|
|
|
|
{
|
|
|
|
m_element.negate = true;
|
|
|
|
m_state = ExpectField;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
handleChar( c );
|
|
|
|
}
|
|
|
|
|
|
|
|
void ExpressionParser::handleColon( const TQChar &c )
|
|
|
|
{
|
|
|
|
if( m_state <= ExpectField && !m_string.isEmpty() )
|
|
|
|
{
|
|
|
|
m_element.field = m_string;
|
|
|
|
m_string = TQString();
|
|
|
|
m_state = ExpectMod;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
handleChar( c );
|
|
|
|
}
|
|
|
|
|
|
|
|
void ExpressionParser::handleMod( const TQChar &c )
|
|
|
|
{
|
|
|
|
if( m_state == ExpectMod )
|
|
|
|
{
|
|
|
|
m_element.match = ( c == '>' ) ? expression_element::More : expression_element::Less;
|
|
|
|
m_state = ExpectText;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
handleChar( c );
|
|
|
|
}
|
|
|
|
|
|
|
|
void ExpressionParser::handleQuote( const TQChar& )
|
|
|
|
{
|
|
|
|
if( m_inQuote )
|
|
|
|
{
|
|
|
|
finishedElement();
|
|
|
|
m_inQuote = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if( !m_string.isEmpty() )
|
|
|
|
finishedToken();
|
|
|
|
m_state = ExpectText;
|
|
|
|
m_inQuote = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ExpressionParser::handleChar( const TQChar &c )
|
|
|
|
{
|
|
|
|
m_string += c;
|
|
|
|
if( m_state <= ExpectField )
|
|
|
|
m_state = ExpectField;
|
|
|
|
else if( m_state <= ExpectText )
|
|
|
|
m_state = ExpectText;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ExpressionParser::finishedToken()
|
|
|
|
{
|
|
|
|
enum { And, Or, Neither };
|
|
|
|
int s;
|
|
|
|
if( m_haveGroup || !m_element.field.isEmpty() )
|
|
|
|
s = Neither;
|
|
|
|
else if( m_string == "AND" )
|
|
|
|
s = And;
|
|
|
|
else if( m_string == "OR" )
|
|
|
|
s = Or;
|
|
|
|
else
|
|
|
|
s = Neither;
|
|
|
|
|
|
|
|
if( s == Neither )
|
|
|
|
finishedElement();
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_haveGroup = true;
|
|
|
|
|
|
|
|
if( s == Or )
|
|
|
|
m_inOrGroup = true;
|
|
|
|
else
|
|
|
|
finishedOrGroup();
|
|
|
|
|
|
|
|
m_string = TQString();
|
|
|
|
m_state = ExpectMinus;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ExpressionParser::finishedElement()
|
|
|
|
{
|
|
|
|
if( !m_inOrGroup )
|
|
|
|
finishedOrGroup();
|
|
|
|
m_inOrGroup = m_haveGroup = false;
|
|
|
|
m_element.text = m_string;
|
|
|
|
m_string = TQString();
|
|
|
|
|
|
|
|
if( !m_element.text.isEmpty() || !m_element.field.isEmpty() )
|
|
|
|
m_or.append( m_element );
|
|
|
|
|
|
|
|
m_element = expression_element();
|
|
|
|
m_state = ExpectMinus;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ExpressionParser::finishedOrGroup()
|
|
|
|
{
|
|
|
|
if( !m_or.isEmpty() )
|
|
|
|
m_parsed.append( m_or );
|
|
|
|
m_or.clear();
|
|
|
|
m_inOrGroup = false;
|
|
|
|
}
|
|
|
|
|