File indexing completed on 2024-05-19 04:49:16
0001 /**************************************************************************************** 0002 * Copyright (c) 2006 Gbor Lehel <illissius@gmail.com> * 0003 * * 0004 * This program is free software; you can redistribute it and/or modify it under * 0005 * the terms of the GNU General Public License as published by the Free Software * 0006 * Foundation; either version 2 of the License, or (at your option) any later * 0007 * version. * 0008 * * 0009 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 0010 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 0011 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 0012 * * 0013 * You should have received a copy of the GNU General Public License along with * 0014 * this program. If not, see <http://www.gnu.org/licenses/>. * 0015 ****************************************************************************************/ 0016 0017 #include "Expression.h" 0018 #include "core/support/Debug.h" 0019 0020 ExpressionParser::ExpressionParser( const QString &expression ) 0021 : m_expression( expression ) 0022 , m_state( ExpectMinus ) 0023 , m_haveGroup( false ) 0024 , m_inQuote( false ) 0025 , m_inOrGroup( false ) 0026 { } 0027 0028 ParsedExpression ExpressionParser::parse() 0029 { 0030 const uint length = m_expression.length(); 0031 for( uint pos = 0; pos < length; ++pos ) 0032 parseChar( m_expression.at( pos ) ); 0033 finishedToken(); 0034 finishedOrGroup(); 0035 0036 return m_parsed; 0037 } 0038 0039 ParsedExpression ExpressionParser::parse( const QString &expression ) //static 0040 { 0041 ExpressionParser p( expression ); 0042 return p.parse(); 0043 } 0044 0045 bool ExpressionParser::isAdvancedExpression( const QString &expression ) //static 0046 { 0047 return ( expression.contains( '"' ) || 0048 expression.contains( ':' ) || 0049 expression.contains( '-' ) || 0050 expression.contains( QLatin1String("AND") ) || 0051 expression.contains( QLatin1String("OR") ) ); 0052 } 0053 0054 /* PRIVATE */ 0055 0056 void ExpressionParser::parseChar( const QChar &c ) 0057 { 0058 if( m_inQuote && c != '"' ) 0059 m_string += c; 0060 else if( c.isSpace() ) 0061 handleSpace( c ); 0062 else if( c == '-' ) 0063 handleMinus( c ); 0064 else if( c == ':' ) 0065 handleColon( c ); 0066 else if( c == '=' || c == '>' || c == '<' ) 0067 handleMod( c ); 0068 else if( c == '"' ) 0069 handleQuote( c ); 0070 else 0071 handleChar( c ); 0072 } 0073 0074 void ExpressionParser::handleSpace( const QChar& ) 0075 { 0076 if( m_state > ExpectMinus ) 0077 finishedToken(); 0078 } 0079 0080 void ExpressionParser::handleMinus( const QChar &c ) 0081 { 0082 if( m_state == ExpectMinus ) 0083 { 0084 m_element.negate = true; 0085 m_state = ExpectField; 0086 } 0087 else 0088 handleChar( c ); 0089 } 0090 0091 void ExpressionParser::handleColon( const QChar &c ) 0092 { 0093 if( m_state <= ExpectField && !m_string.isEmpty() ) 0094 { 0095 m_element.field = m_string; 0096 m_string.clear(); 0097 m_state = ExpectMod; 0098 } 0099 else 0100 handleChar( c ); 0101 } 0102 0103 void ExpressionParser::handleMod( const QChar &c ) 0104 { 0105 if( m_state == ExpectMod ) 0106 { 0107 if( c == '=' ) 0108 m_element.match = expression_element::Equals; 0109 else if( c == '>' ) 0110 m_element.match = expression_element::More; 0111 else if( c == '<' ) 0112 m_element.match = expression_element::Less; 0113 m_state = ExpectText; 0114 } 0115 else 0116 handleChar( c ); 0117 } 0118 0119 void ExpressionParser::handleQuote( const QChar& ) 0120 { 0121 if( m_inQuote ) 0122 { 0123 finishedElement(); 0124 m_inQuote = false; 0125 } 0126 else 0127 { 0128 if( !m_string.isEmpty() ) 0129 finishedToken(); 0130 m_state = ExpectText; 0131 m_inQuote = true; 0132 } 0133 } 0134 0135 void ExpressionParser::handleChar( const QChar &c ) 0136 { 0137 m_string += c; 0138 if( m_state <= ExpectField ) 0139 m_state = ExpectField; 0140 else if( m_state <= ExpectText ) 0141 m_state = ExpectText; 0142 } 0143 0144 void ExpressionParser::finishedToken() 0145 { 0146 enum { And, Or, Neither }; 0147 int s; 0148 if( m_haveGroup || !m_element.field.isEmpty() ) 0149 s = Neither; 0150 else if( m_string == QLatin1String("AND") ) 0151 s = And; 0152 else if( m_string == QLatin1String("OR") ) 0153 s = Or; 0154 else 0155 s = Neither; 0156 0157 if( s == Neither ) 0158 finishedElement(); 0159 else 0160 { 0161 m_haveGroup = true; 0162 0163 if( s == Or ) 0164 m_inOrGroup = true; 0165 else 0166 finishedOrGroup(); 0167 0168 m_string.clear(); 0169 m_state = ExpectMinus; 0170 } 0171 } 0172 0173 void ExpressionParser::finishedElement() 0174 { 0175 if( !m_inOrGroup ) 0176 finishedOrGroup(); 0177 m_inOrGroup = m_haveGroup = false; 0178 m_element.text = m_string; 0179 m_string.clear(); 0180 0181 if( !m_element.text.isEmpty() ) 0182 m_or.append( m_element ); 0183 0184 //m_element = expression_element(); 0185 m_element.field.clear(); 0186 m_element.negate = false; 0187 m_element.match = expression_element::Contains; 0188 m_state = ExpectMinus; 0189 } 0190 0191 void ExpressionParser::finishedOrGroup() 0192 { 0193 if( !m_or.isEmpty() ) 0194 m_parsed.append( m_or ); 0195 m_or.clear(); 0196 m_inOrGroup = false; 0197 } 0198