crashanalysercmd/PerfToolsSharedLibraries/Engine/SymBuildParsingLib/Token/SymTokenBalancerNodes.cs
changeset 0 818e61de6cd1
equal deleted inserted replaced
-1:000000000000 0:818e61de6cd1
       
     1 /*
       
     2 * Copyright (c) 2004-2008 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 using System;
       
    19 using System.Text;
       
    20 using System.Collections;
       
    21 using SymBuildParsingLib.Tree;
       
    22 using SymBuildParsingLib.Token;
       
    23 using SymBuildParsingLib.Common.Objects;
       
    24 using SymbianTree;
       
    25 
       
    26 namespace SymBuildParsingLib.Token
       
    27 {
       
    28 	#region SymTokenBalancerDocument
       
    29 	public class SymTokenBalancerDocument : SymTokenDocument
       
    30 	{
       
    31 		#region Constructors & destructor
       
    32 		public SymTokenBalancerDocument()
       
    33 		{
       
    34 		}
       
    35 		#endregion
       
    36 
       
    37 		#region Internal framework API
       
    38 		protected override void ExtractToContainer( SymNode aNode, SymTokenContainer aContainer )
       
    39 		{
       
    40 			if	( aNode is SymTokenBalancerNodeEmittedElement )
       
    41 			{
       
    42 				SymTokenBalancerNodeEmittedElement node = (SymTokenBalancerNodeEmittedElement) aNode;
       
    43 				node.AddToContainerIfEmittable( aContainer );
       
    44 			}
       
    45 		}
       
    46 
       
    47 		protected override void ExtractToDocument( SymNode aNode, SymTokenDocument aDocument )
       
    48 		{
       
    49 			if	( aNode is SymTokenBalancerNodeEmittedElement )
       
    50 			{
       
    51 				SymTokenBalancerNodeEmittedElement node = (SymTokenBalancerNodeEmittedElement) aNode;
       
    52 				node.AddToDocumentIfEmittable( aDocument );
       
    53 			}
       
    54 		}
       
    55 
       
    56 		protected override bool NodeIsExtractable( SymNode aNode )
       
    57 		{
       
    58 			bool ret = false;
       
    59 			//
       
    60 			if	( aNode is SymTokenBalancerNodeEmittedElement )
       
    61 			{
       
    62 				SymTokenBalancerNodeEmittedElement node = (SymTokenBalancerNodeEmittedElement) aNode;
       
    63 				ret = node.Emit;
       
    64 			}
       
    65 			//
       
    66 			return ret;
       
    67 		}
       
    68 		#endregion
       
    69 	}
       
    70 	#endregion
       
    71 
       
    72 	#region SymTokenBalancerNode
       
    73 	public class SymTokenBalancerNode : SymNodeToken
       
    74 	{
       
    75 		#region Constructors & destructor
       
    76 		public SymTokenBalancerNode( SymToken aToken )
       
    77 			: base( aToken )
       
    78 		{
       
    79 		}
       
    80 		#endregion
       
    81 	}
       
    82 	#endregion
       
    83 
       
    84 	#region SymTokenBalancerMarkerNode
       
    85 	public class SymTokenBalancerMarkerNode : SymNodeAddAsChild
       
    86 	{
       
    87 		#region Constructors & destructor
       
    88 		public SymTokenBalancerMarkerNode( SymTokenBalancerMatchCriteria aMatchCriteria )
       
    89 		{
       
    90 			iMatchCriteria = aMatchCriteria;
       
    91 		}
       
    92 		#endregion
       
    93 
       
    94 		#region Properties
       
    95 		public SymTokenBalancerMatchCriteria MatchCriteria
       
    96 		{
       
    97 			get { return iMatchCriteria; }
       
    98 		}
       
    99 		#endregion
       
   100 
       
   101 		#region Data members
       
   102 		private readonly SymTokenBalancerMatchCriteria iMatchCriteria;
       
   103 		#endregion
       
   104 	}
       
   105 	#endregion
       
   106 
       
   107 	#region SymTokenBalancerMarkerLevelNode
       
   108 	public class SymTokenBalancerMarkerLevelNode : SymTokenBalancerMarkerNode
       
   109 	{
       
   110 		#region Constructors & destructor
       
   111 		public SymTokenBalancerMarkerLevelNode( SymTokenBalancerMatchCriteria aMatchCriteria )
       
   112 			: base( aMatchCriteria )
       
   113 		{
       
   114 		}
       
   115 		#endregion
       
   116 
       
   117 		#region From SymNode		
       
   118 		public override void Replace( SymNode aReplacement )
       
   119 		{
       
   120 			if	( HasPrevious && Previous is SymTokenBalancerNodeEmittedElement )
       
   121 			{
       
   122 				Previous.Remove();
       
   123 			}
       
   124 			if	( HasNext && Next is SymTokenBalancerNodeEmittedElement )
       
   125 			{
       
   126 				Next.Remove();
       
   127 			}
       
   128 
       
   129 			base.Replace( aReplacement );
       
   130 		}
       
   131 		#endregion
       
   132 
       
   133 		#region API
       
   134 		public SymArgumentSubLevel AsArgumentSubLevel( bool aRecurse )
       
   135 		{
       
   136 			SymArgumentSubLevel ret = new SymArgumentSubLevel( this );
       
   137 			//
       
   138 			if	( aRecurse )
       
   139 			{
       
   140 				foreach( SymNode child in ret )
       
   141 				{
       
   142 					if	( child is SymTokenBalancerMarkerLevelNode )
       
   143 					{
       
   144 						SymTokenBalancerMarkerLevelNode markerNode = (SymTokenBalancerMarkerLevelNode) child;
       
   145 						SymArgumentSubLevel subLevel = markerNode.AsArgumentSubLevel( aRecurse );
       
   146 						ret.InsertChild( subLevel, markerNode );
       
   147 						markerNode.Remove();
       
   148 					}
       
   149 				}
       
   150 			}
       
   151 			//
       
   152 			return ret;
       
   153 		}
       
   154 
       
   155 		public void ConvertEmittedElementsToRealTokenNodes( bool aRecurse )
       
   156 		{
       
   157 			int i = ChildCount;
       
   158 			//
       
   159 			while( i > 0 )
       
   160 			{
       
   161 				SymNode child = this[ --i ];
       
   162 				//
       
   163 				if	( child is SymTokenBalancerNodeEmittedElement )
       
   164 				{
       
   165 					SymTokenBalancerNodeEmittedElement emittedElement = (SymTokenBalancerNodeEmittedElement) child;
       
   166 					if	( emittedElement.Emit )
       
   167 					{
       
   168 						SymNodeToken replacement = new SymNodeToken( emittedElement.Token ); 
       
   169 						InsertChild( replacement, child );
       
   170 					}
       
   171 					child.Remove();
       
   172 				}
       
   173 				else if ( child is SymTokenBalancerMarkerLevelNode && aRecurse )
       
   174 				{
       
   175 					SymTokenBalancerMarkerLevelNode childLevel = (SymTokenBalancerMarkerLevelNode) child;
       
   176 					childLevel.ConvertEmittedElementsToRealTokenNodes( aRecurse );
       
   177 				}
       
   178 			}
       
   179 		}
       
   180 
       
   181 		public int CountTokenByType( SymToken.TClass aClass )
       
   182 		{
       
   183 			int count = 0;
       
   184 			//
       
   185 			foreach( SymNode n in this )
       
   186 			{
       
   187 				if	( n is SymNodeToken )
       
   188 				{
       
   189 					bool isSpecial = ( n is SymTokenBalancerNode );
       
   190 					//
       
   191 					if	( isSpecial == false )
       
   192 					{
       
   193 						SymToken t = ((SymNodeToken) n).Token;
       
   194 						//
       
   195 						if	( t.Class == aClass )
       
   196 						{
       
   197 							++count;
       
   198 						}
       
   199 					}
       
   200 				}
       
   201 			}
       
   202 			//
       
   203 			return count;
       
   204 		}
       
   205 
       
   206 		public void Subsume()
       
   207 		{
       
   208 			System.Diagnostics.Debug.Assert( IsComplete );
       
   209 			//
       
   210 			SymTokenBalancerNodeEmittedElement previous = EmittedElementPrevious;
       
   211 			SymTokenBalancerNodeEmittedElement next = EmittedElementNext;
       
   212 
       
   213 			// Insert all my children as siblings of myself (i.e. make my parent's
       
   214 			// grandchildren its direct children - i.e. promote them up the tree
       
   215 			// by one level).
       
   216 			SymNode parent = Parent;
       
   217 			ArrayList parentsChildren = Parent.Children;
       
   218 			parent.InsertChildrenFrom( this /* my children */, previous.Previous /* move them before the opening bracket */);
       
   219 
       
   220 			// Remove the opening bracket token
       
   221 			previous.Remove();
       
   222 
       
   223 			// Remove the closing bracket token.
       
   224 			next.Remove();
       
   225 
       
   226 			// Remove the level marker token, i.e myself
       
   227 			Remove();
       
   228 		}
       
   229 		#endregion
       
   230 
       
   231 		#region Properties
       
   232 		public bool CanBeSubsumed
       
   233 		{
       
   234 			get
       
   235 			{
       
   236 				bool canBeSubsumed = false;
       
   237 				//
       
   238 				if	( IsComplete )
       
   239 				{
       
   240 					if	( AreLocalEmittedNodesDiametricallyOposite )
       
   241 					{
       
   242 						bool isSimple = IsSimple;
       
   243 						//
       
   244 						if	( isSimple )
       
   245 						{
       
   246 							// Deal with the case whereby we have something like this: ([SOMETHINGELSE])
       
   247 							if	( ( Parent is SymTokenBalancerMarkerLevelNode) && ChildCountLevelNodes == 0 )
       
   248 							{
       
   249 								// We don't have any child level nodes and our parent is a level (it always sound be in any case).
       
   250 								SymTokenBalancerMarkerLevelNode parent = (SymTokenBalancerMarkerLevelNode) Parent;
       
   251 								if	( parent.IsComplete )
       
   252 								{
       
   253 									// Check whether the parent is a function. If it is, then we don't want to subsume the children.
       
   254 									bool isFunc = parent.IsFunction;
       
   255 									if	( isFunc == false )
       
   256 									{
       
   257 										// The parent is complete, which means we can compare this level's open and closing tokens
       
   258 										// with the parents.
       
   259 										canBeSubsumed = ( parent.EmittedElementPrevious.Token.Equals( EmittedElementPrevious.Token ) && 
       
   260 											parent.EmittedElementNext.Token.Equals( EmittedElementNext.Token ) );
       
   261 									}
       
   262 								}
       
   263 								else
       
   264 								{
       
   265 									canBeSubsumed = true;
       
   266 								}
       
   267 								
       
   268 							}
       
   269 							else
       
   270 							{
       
   271 								canBeSubsumed = true;
       
   272 							}
       
   273 						}
       
   274 						else
       
   275 						{
       
   276 							// Check whether our children contains at least a single argument separator node.
       
   277 							// If it does, we can't allow it to be subsumed.
       
   278 							if	( ChildCountArgumentNodes == 0 )
       
   279 							{
       
   280 								if	( Parent is SymTokenBalancerMarkerLevelNode )
       
   281 								{
       
   282 									SymTokenBalancerMarkerLevelNode parent = (SymTokenBalancerMarkerLevelNode) Parent;
       
   283 									bool parentIsSimple = parent.IsSimple;
       
   284 									canBeSubsumed = parentIsSimple;
       
   285 								}
       
   286 							}
       
   287 						}
       
   288 					}
       
   289 				}
       
   290 				//
       
   291 				return canBeSubsumed;
       
   292 			}
       
   293 		}
       
   294 
       
   295 		public bool IsFunction
       
   296 		{
       
   297 			get
       
   298 			{
       
   299 				#region Example
       
   300 				//
       
   301 				// [FUNC_NAME] [(] [*] [)] 
       
   302 				//                  |
       
   303 				//        [alpha_numeric_child]
       
   304 				//
       
   305 				#endregion
       
   306 				
       
   307 				bool bracketsAreCorrect = false;
       
   308 				bool hasFunctionName = false;
       
   309 				bool childIsValid = false;
       
   310 				//
       
   311 				if	( AreLocalEmittedNodesDiametricallyOposite )
       
   312 				{
       
   313 					// Check that the previous node is a function name
       
   314 					if	( Previous.HasPrevious )
       
   315 					{
       
   316 						SymNode previousPrevious = Previous.Previous;
       
   317 						if	( previousPrevious is SymNodeToken )
       
   318 						{
       
   319 							SymNodeToken nodeToken = (SymNodeToken) previousPrevious;
       
   320 							hasFunctionName = (nodeToken.Token.Class == SymToken.TClass.EClassAlphaNumeric );
       
   321 						}
       
   322 					}
       
   323 
       
   324 					// Check that the brackets are ( and )
       
   325 					bracketsAreCorrect = ( EmittedElementPrevious.Token.Value == "(" && EmittedElementNext.Token.Value == ")" );
       
   326 
       
   327 					// Check that the level node has but one child and that it
       
   328 					// is alphanumeric in nature.
       
   329 					if	( ChildCountByType( typeof(SymNodeToken) ) > 0 )
       
   330 					{
       
   331 						foreach( SymNode child in this )
       
   332 						{
       
   333 							if	( child is SymNodeToken )
       
   334 							{
       
   335 								SymNodeToken tokenNode = (SymNodeToken) child;
       
   336 								//
       
   337 								if	( tokenNode.Token.Class == SymToken.TClass.EClassAlphaNumeric )
       
   338 								{
       
   339 									childIsValid = true;
       
   340 									break;
       
   341 								}
       
   342 							}
       
   343 						}
       
   344 					}
       
   345 				}
       
   346 
       
   347 				bool isFunction = (bracketsAreCorrect && hasFunctionName && childIsValid );
       
   348 				return isFunction;
       
   349 			}
       
   350 		}
       
   351 
       
   352 		public bool IsSimple
       
   353 		{
       
   354 			get
       
   355 			{
       
   356 				bool isSimple = false;
       
   357 				//
       
   358 				if	( IsFunction )
       
   359 				{
       
   360 					isSimple = false;
       
   361 				}
       
   362 				else if	( ChildCountNonWhiteSpace == 1 )
       
   363 				{
       
   364 					// My child is but a single node...
       
   365 					isSimple = true;
       
   366 				}
       
   367 				else if ( ChildCountWhiteSpace == ChildCount )
       
   368 				{
       
   369 					// My children are just whitespace
       
   370 					isSimple = true;
       
   371 				}
       
   372 				else if ( ChildCountLevelNodes == 1 )
       
   373 				{
       
   374 					int childCountLevelAndAssociatedEmittedNodes = ChildCountLevelAndAssociatedEmittedNodes;
       
   375 					int childCount = ChildCount;
       
   376 					int whiteSpaceCount = ChildCountWhiteSpace;
       
   377 					//
       
   378 					if	( (childCount - whiteSpaceCount) == childCountLevelAndAssociatedEmittedNodes )
       
   379 					{
       
   380 						// Ignoring the whitespace nodes, all we had was a single level node plus its
       
   381 						// two associated emitted elements...
       
   382 						isSimple = true;
       
   383 					}
       
   384 				}
       
   385 				//
       
   386 				return isSimple;
       
   387 			}
       
   388 		}
       
   389 
       
   390 		public bool IsComplete
       
   391 		{
       
   392 			get
       
   393 			{
       
   394 				bool complete = false;
       
   395 
       
   396 				// Must have a next and a previous node. Next and previous must be
       
   397 				// emitted element nodes
       
   398 				if	( HasNext && HasPrevious )
       
   399 				{
       
   400 					complete = ( Previous is SymTokenBalancerNodeEmittedElement && Next is SymTokenBalancerNodeEmittedElement );
       
   401 				}
       
   402 
       
   403 				return complete;
       
   404 			}
       
   405 		}
       
   406 
       
   407 		public bool AreLocalEmittedNodesDiametricallyOposite
       
   408 		{
       
   409 			get
       
   410 			{
       
   411 				bool ret = false;
       
   412 				//
       
   413 				if	( IsComplete )
       
   414 				{
       
   415 					SymTokenBalancerNodeEmittedElement previous = (SymTokenBalancerNodeEmittedElement) Previous;
       
   416 					SymTokenBalancerNodeEmittedElement next = (SymTokenBalancerNodeEmittedElement) Next;
       
   417 					//
       
   418 					if	( previous.MatchCriteria.DiametricToken.Equals( next.Token ) )
       
   419 					{
       
   420 						// Paranoid
       
   421 						ret = ( next.MatchCriteria.DiametricToken.Equals( previous.Token ) );
       
   422 					}
       
   423 				}
       
   424 				//
       
   425 				return ret;
       
   426 			}
       
   427 		}
       
   428 
       
   429 		public SymNodeToken FunctionName
       
   430 		{
       
   431 			get
       
   432 			{
       
   433 				if	( IsFunction == false )
       
   434 				{
       
   435 					throw new ArgumentException( "Level node is not a function node" );
       
   436 				}
       
   437 
       
   438 				System.Diagnostics.Debug.Assert( Previous.HasPrevious );
       
   439 				System.Diagnostics.Debug.Assert( Previous.Previous is SymNodeToken );
       
   440 				SymNodeToken functionNameToken = (SymNodeToken) Previous.Previous;
       
   441 				return functionNameToken;
       
   442 			}
       
   443 		}
       
   444 
       
   445 		public SymTokenContainer ChildTokens
       
   446 		{
       
   447 			get
       
   448 			{
       
   449 				SymTokenContainer ret = new SymTokenContainer();
       
   450 				//
       
   451 				foreach( SymNode c in this )
       
   452 				{
       
   453 					if	( c is SymNodeToken )
       
   454 					{
       
   455 						SymNodeToken t = (SymNodeToken) c;
       
   456 						ret.Append( t.Token );
       
   457 					}
       
   458 				}
       
   459 				//
       
   460 				return ret;
       
   461 			}
       
   462 		}
       
   463 
       
   464 		public int ChildCountWhiteSpace
       
   465 		{
       
   466 			get
       
   467 			{
       
   468 				return CountTokenByType( SymToken.TClass.EClassWhiteSpace );
       
   469 			}
       
   470 		}
       
   471 
       
   472 		public int ChildCountNonWhiteSpace
       
   473 		{
       
   474 			get
       
   475 			{
       
   476 				return ChildCount - ChildCountWhiteSpace;
       
   477 			}
       
   478 		}
       
   479 
       
   480 		public int ChildCountLevelNodes
       
   481 		{
       
   482 			get
       
   483 			{
       
   484 				int count = ChildCountByType( typeof(SymTokenBalancerMarkerLevelNode) );
       
   485 				return count;
       
   486 			}
       
   487 		}
       
   488 
       
   489 		public int ChildCountLevelAndAssociatedEmittedNodes
       
   490 		{
       
   491 			get
       
   492 			{
       
   493 				int count = 0;
       
   494 				//
       
   495 				int index = 0;
       
   496 				object childLevelNodeObject = ChildByType( typeof(SymTokenBalancerMarkerLevelNode), ref index );
       
   497 				while( childLevelNodeObject != null )
       
   498 				{
       
   499 					// Count is incremented by one each time we find a level node
       
   500 					SymTokenBalancerMarkerLevelNode childLevelNode = (SymTokenBalancerMarkerLevelNode) childLevelNodeObject;
       
   501 					++count;
       
   502 
       
   503 					// It should always have a previous token.
       
   504 					System.Diagnostics.Debug.Assert( childLevelNode.HasPrevious );
       
   505 					if	( childLevelNode.Previous is SymTokenBalancerNodeEmittedElement )
       
   506 					{
       
   507 						++count;
       
   508 					}
       
   509 
       
   510 					// It may have a next node, assuming its complete...
       
   511 					if	( childLevelNode.HasNext )
       
   512 					{
       
   513 						if	( childLevelNode.Next is SymTokenBalancerNodeEmittedElement )
       
   514 						{
       
   515 							++count;
       
   516 						}
       
   517 					}
       
   518 
       
   519 					// Move to next child level node
       
   520 					++index;
       
   521 					childLevelNodeObject = ChildByType( typeof(SymTokenBalancerMarkerLevelNode), ref index );
       
   522 				}
       
   523 				//
       
   524 				return count;
       
   525 			}
       
   526 		}
       
   527 
       
   528 		public int ChildCountArgumentNodes
       
   529 		{
       
   530 			get
       
   531 			{
       
   532 				int count = ChildCountByType( typeof(SymTokenBalancerMarkerArgumentNode) );
       
   533 				return count;
       
   534 			}
       
   535 		}
       
   536 
       
   537 		public SymTokenBalancerNodeEmittedElement EmittedElementPrevious
       
   538 		{
       
   539 			get
       
   540 			{
       
   541 				return (SymTokenBalancerNodeEmittedElement) Previous;
       
   542 			}
       
   543 		}
       
   544 
       
   545 		public SymTokenBalancerNodeEmittedElement EmittedElementNext
       
   546 		{
       
   547 			get
       
   548 			{
       
   549 				return (SymTokenBalancerNodeEmittedElement) Next;
       
   550 			}
       
   551 		}
       
   552 
       
   553 		#endregion
       
   554 
       
   555 		#region Internal methods
       
   556 		#endregion
       
   557 	}
       
   558 	#endregion
       
   559 
       
   560 	#region SymTokenBalancerMarkerArgumentNode
       
   561 	public class SymTokenBalancerMarkerArgumentNode : SymTokenBalancerMarkerNode
       
   562 	{
       
   563 		#region Constructors & destructor
       
   564 		public SymTokenBalancerMarkerArgumentNode( SymTokenBalancerMatchCriteria aMatchCriteria )
       
   565 			: base( aMatchCriteria )
       
   566 		{
       
   567 		}
       
   568 		#endregion
       
   569 	}
       
   570 	#endregion
       
   571 
       
   572 	#region SymTokenBalancerNodeEmittedElement
       
   573 	public class SymTokenBalancerNodeEmittedElement : SymTokenBalancerMarkerNode
       
   574 	{
       
   575 		#region Constructors & destructor
       
   576 		public SymTokenBalancerNodeEmittedElement( SymToken aToken, SymTokenBalancerMatchCriteria aMatchCriteria )
       
   577 			: base( aMatchCriteria )
       
   578 		{
       
   579 			iToken = aToken;
       
   580 		}
       
   581 		#endregion
       
   582 
       
   583 		#region API
       
   584 		public void AddToDocumentIfEmittable( SymDocument aDocument )
       
   585 		{
       
   586 			if	( Emit )
       
   587 			{
       
   588 				SymNodeToken node = new SymNodeToken( Token );
       
   589 				aDocument.CurrentNode.Add( node );
       
   590 			}
       
   591 		}
       
   592 
       
   593 		public void AddToContainerIfEmittable( SymTokenContainer aContainer )
       
   594 		{
       
   595 			if	( Emit )
       
   596 			{
       
   597 				aContainer.Append( Token );
       
   598 			}
       
   599 		}
       
   600 		#endregion
       
   601 
       
   602 		#region Properties
       
   603 		public SymToken Token
       
   604 		{
       
   605 			get { return iToken; }
       
   606 		}
       
   607 
       
   608 		public bool Emit
       
   609 		{
       
   610 			get { return MatchCriteria.Emit; }
       
   611 		}
       
   612 		#endregion
       
   613 
       
   614 		#region Data members
       
   615 		private readonly SymToken iToken;
       
   616 		#endregion
       
   617 	}
       
   618 	#endregion
       
   619 }