charconvfw/numbergrouping/Src/RegularExpression.cpp
changeset 0 1fb32624e06b
child 16 56cd22a7a1cb
equal deleted inserted replaced
-1:000000000000 0:1fb32624e06b
       
     1 /*
       
     2 * Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 #include "RegularExpression.h"
       
    19 
       
    20 #define KNumOfRecognisedChars 13
       
    21 
       
    22 // Panic is implemented in NumberGrouping.cpp
       
    23 GLDEF_C void Panic(TNumberGroupingPanic aPanic);
       
    24 
       
    25 CRegularExpression::CRegularExpression()
       
    26 {
       
    27 }
       
    28 
       
    29 CRegularExpression* CRegularExpression::NewL(RPointerArray<TDesC>* aPatterns)
       
    30 {
       
    31 	CRegularExpression* s = NewLC(aPatterns);
       
    32 	CleanupStack::Pop();
       
    33 	return s;
       
    34 }
       
    35 
       
    36 CRegularExpression* CRegularExpression::NewLC(RPointerArray<TDesC>* aPatterns)
       
    37 {
       
    38 	CRegularExpression* s = new(ELeave)CRegularExpression();
       
    39 	CleanupStack::PushL(s);
       
    40 	s->ConstructL(aPatterns);
       
    41 	return s;
       
    42 }
       
    43 
       
    44 void CRegularExpression::ConstructL(RPointerArray<TDesC>* aPatterns)
       
    45 {
       
    46 	GenerateStateTablesL(aPatterns);
       
    47 }
       
    48 
       
    49 CRegularExpression::~CRegularExpression()
       
    50 {
       
    51 	for(TInt i = 0; i < iStateMachines.Count(); i++)
       
    52 		delete iStateMachines[i];
       
    53 	
       
    54 	iStateMachines.Close();
       
    55 }
       
    56 
       
    57 TInt CRegularExpression::Search(const TDesC& aString)
       
    58 {
       
    59 	return SearchFrom(0, aString);
       
    60 }
       
    61 
       
    62 TInt CRegularExpression::SearchFrom(TInt aIndex, const TDesC& aString)
       
    63 {
       
    64 	for(TInt i = aIndex; i < iStateMachines.Count(); ++i)
       
    65 	{
       
    66 		if(iStateMachines[i]->Matches(aString))
       
    67 			return i;
       
    68 	}
       
    69 
       
    70 	return KErrNotFound;
       
    71 }
       
    72 
       
    73 // Do the parsing
       
    74 void CRegularExpression::GenerateStateTablesL(RPointerArray<TDesC>* aPatterns)
       
    75 {	
       
    76 	for(TInt nPatternCount = 0; nPatternCount < aPatterns->Count(); ++nPatternCount)
       
    77 	{
       
    78 		const TDesC& desPattern = *((*aPatterns)[nPatternCount]) ;	// I know it looks horrific, but it makes the
       
    79 																	// rest of the method _so_ much easier to read
       
    80 		
       
    81 		CStateMachine* StateMachine = CStateMachine::NewLC(KNumOfRecognisedChars, desPattern.Length());
       
    82 		iStateMachines.Append(StateMachine);
       
    83 
       
    84 		// parse the desPattern
       
    85 
       
    86 		enum TParseState
       
    87 		{
       
    88 			EAny,
       
    89 			EOpenBracketFound,
       
    90 			EChoiceOrRange,
       
    91 			EChoice,
       
    92 			ERange,
       
    93 			ELookingForCloseBracket
       
    94 		};
       
    95 
       
    96 		TParseState	parseState = EAny;
       
    97 
       
    98 		TInt		nPatternIndex = 0;
       
    99 		TInt		nState = 0;
       
   100 
       
   101 		TBuf<10>	bufChoice;
       
   102 		bufChoice.Zero();
       
   103 
       
   104 		TBuf<20>	bufParsingError = _L("Parsing syntax error");
       
   105 
       
   106 		while(nPatternIndex < desPattern.Length() )
       
   107 		{
       
   108 			TChar cChar = desPattern[nPatternIndex];
       
   109 			TBool bEndOfParse = EFalse;
       
   110 
       
   111 			if(nPatternIndex == desPattern.Length() - 1) // end of the parse
       
   112 				bEndOfParse = ETrue;
       
   113 		
       
   114 			switch(cChar)
       
   115 			{
       
   116 			case '1':
       
   117 			case '2':
       
   118 			case '3':
       
   119 			case '4':
       
   120 			case '5':
       
   121 			case '6':
       
   122 			case '7':
       
   123 			case '8':
       
   124 			case '9':
       
   125 			case '0':
       
   126 				switch(parseState)
       
   127 				{
       
   128 				case EAny:
       
   129 					iStateMachines[nPatternCount]->AddStateTransistionL(cChar, nState, bEndOfParse?
       
   130 																					KStateMatched:
       
   131 																					(nState + 1)); 
       
   132 					++nState;
       
   133 					break;
       
   134 				case EOpenBracketFound:
       
   135 					bufChoice.Append(cChar);
       
   136 					parseState = EChoiceOrRange;					
       
   137 					break;
       
   138 				case EChoiceOrRange:
       
   139 				case EChoice:
       
   140 					bufChoice.Append(cChar);
       
   141 					parseState = EChoice;
       
   142 					break;
       
   143 				case ERange:
       
   144 					bufChoice.Append(cChar);
       
   145 					parseState = ELookingForCloseBracket;
       
   146 					break;
       
   147 				//case ELookingForCloseBracket:						
       
   148 				default:
       
   149 					User::Panic(bufParsingError, KErrSyntaxError);
       
   150 					break;
       
   151 				}
       
   152 				break;
       
   153 			case '[':
       
   154 				switch(parseState)
       
   155 				{
       
   156 				case EAny:						
       
   157 					bufChoice.Zero();
       
   158 					parseState = EOpenBracketFound;
       
   159 					break;
       
   160 				//case EOpenBracketFound:			
       
   161 				//case EChoiceOrRange:			
       
   162 				//case EChoice:					
       
   163 				//case ERange:					
       
   164 				//case ELookingForCloseBracket:	
       
   165 				default:
       
   166 					User::Panic(bufParsingError, KErrSyntaxError);
       
   167 					break;
       
   168 				
       
   169     			}	
       
   170 				break;
       
   171 			case ']':
       
   172 				switch(parseState)
       
   173 				{
       
   174 				case EChoice:
       
   175 					{
       
   176 						for(TInt i = 0; i < bufChoice.Length(); ++i)
       
   177 						{
       
   178 							TChar cChar = bufChoice[i];
       
   179 							
       
   180 							iStateMachines[nPatternCount]->AddStateTransistionL(cChar.GetNumericValue(), 
       
   181 																				nState, 
       
   182 																				bEndOfParse?
       
   183 																					KStateMatched:
       
   184 																					(nState + 1));
       
   185 						}
       
   186 						
       
   187 						++nState;
       
   188 						parseState = EAny;
       
   189 					}
       
   190 					break;
       
   191 				case ELookingForCloseBracket:
       
   192 					{
       
   193 						TChar cTopOfRange = bufChoice[1];
       
   194 						TChar cBottomOfRange = bufChoice[0];
       
   195 
       
   196 						TInt nTopOfRange = cTopOfRange.GetNumericValue();		// if they're not there then something
       
   197 						TInt nBottomOfRange = cBottomOfRange.GetNumericValue();	// is seriously amiss...
       
   198 						
       
   199 						if(nTopOfRange < nBottomOfRange)
       
   200 							User::Panic(bufParsingError, KErrSyntaxError);
       
   201 					
       
   202 						for(TInt i = nBottomOfRange; i <= nTopOfRange; ++i)
       
   203 						{
       
   204 							iStateMachines[nPatternCount]->AddStateTransistionL(i, nState, bEndOfParse?
       
   205 																							KStateMatched:
       
   206 																							(nState + 1));
       
   207 						}
       
   208 						++nState;
       
   209 						parseState = EAny;
       
   210 					}
       
   211 					break;
       
   212 				//case EAny:						
       
   213 				//case EOpenBracketFound:			
       
   214 				//case EChoiceOrRange:			
       
   215 				//case ERange:		
       
   216 				default:
       
   217 					User::Panic(bufParsingError, KErrSyntaxError);
       
   218 					break;
       
   219 				}	
       
   220 				break;
       
   221 			case '-':
       
   222 				switch(parseState)
       
   223 				{
       
   224 				case EChoiceOrRange:			
       
   225 					parseState = ERange;
       
   226 					break;	
       
   227 				//case EAny:						
       
   228 				//case EOpenBracketFound:			
       
   229 				//case ELookingForCloseBracket:	
       
   230 				//case ERange:					
       
   231 				//case EChoice:
       
   232 				default:
       
   233 					User::Panic(bufParsingError, KErrSyntaxError);
       
   234 					break;
       
   235 				}
       
   236 				break;
       
   237 			case '.':
       
   238 			case '+':
       
   239 				switch(parseState)
       
   240 				{
       
   241 				case EAny:						
       
   242 					iStateMachines[nPatternCount]->AddStateTransistionL(cChar, nState, bEndOfParse?
       
   243 																					KStateMatched:
       
   244 																					(nState + 1));
       
   245 					++nState;
       
   246 					break;
       
   247 				//case EOpenBracketFound:			
       
   248 				//case EChoiceOrRange:			
       
   249 				//case ELookingForCloseBracket:	
       
   250 				//case ERange:					
       
   251 				//case EChoice:
       
   252 				default:
       
   253 					User::Panic(bufParsingError, KErrSyntaxError);
       
   254 					break;					
       
   255 				}
       
   256 				break;
       
   257 			default:
       
   258 				User::Panic(bufParsingError, KErrSyntaxError);
       
   259 				break;
       
   260 			}
       
   261 
       
   262 			++nPatternIndex;
       
   263 		}
       
   264 
       
   265 		if(parseState != EAny)
       
   266 			User::Panic(bufParsingError, KErrSyntaxError);
       
   267 					
       
   268 		CleanupStack::Pop(); // iStateMachine[nPatternCount]
       
   269 	}
       
   270 }
       
   271 
       
   272 void CRegularExpression::GetWildcardVersionOfPattern( 
       
   273     TInt aPatternIndex, TText aWildcard, TDes& aWildcardedPattern) const
       
   274     {
       
   275     __ASSERT_ALWAYS( (0 <= aPatternIndex) && (aPatternIndex < iStateMachines.Count()),
       
   276         Panic(ENumberGroupingNoSuchStateMachine) );
       
   277     iStateMachines[aPatternIndex]->GetWildcardVersionOfPattern( aWildcard, aWildcardedPattern );
       
   278     }
       
   279 
       
   280 // End of File