crashanalysercmd/PerfToolsSharedLibraries/Engine/SymBuildParsingLib/Token/SymTokenBalancerNodes.cs
changeset 0 818e61de6cd1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/crashanalysercmd/PerfToolsSharedLibraries/Engine/SymBuildParsingLib/Token/SymTokenBalancerNodes.cs	Thu Feb 11 15:50:58 2010 +0200
@@ -0,0 +1,619 @@
+/*
+* Copyright (c) 2004-2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+
+using System;
+using System.Text;
+using System.Collections;
+using SymBuildParsingLib.Tree;
+using SymBuildParsingLib.Token;
+using SymBuildParsingLib.Common.Objects;
+using SymbianTree;
+
+namespace SymBuildParsingLib.Token
+{
+	#region SymTokenBalancerDocument
+	public class SymTokenBalancerDocument : SymTokenDocument
+	{
+		#region Constructors & destructor
+		public SymTokenBalancerDocument()
+		{
+		}
+		#endregion
+
+		#region Internal framework API
+		protected override void ExtractToContainer( SymNode aNode, SymTokenContainer aContainer )
+		{
+			if	( aNode is SymTokenBalancerNodeEmittedElement )
+			{
+				SymTokenBalancerNodeEmittedElement node = (SymTokenBalancerNodeEmittedElement) aNode;
+				node.AddToContainerIfEmittable( aContainer );
+			}
+		}
+
+		protected override void ExtractToDocument( SymNode aNode, SymTokenDocument aDocument )
+		{
+			if	( aNode is SymTokenBalancerNodeEmittedElement )
+			{
+				SymTokenBalancerNodeEmittedElement node = (SymTokenBalancerNodeEmittedElement) aNode;
+				node.AddToDocumentIfEmittable( aDocument );
+			}
+		}
+
+		protected override bool NodeIsExtractable( SymNode aNode )
+		{
+			bool ret = false;
+			//
+			if	( aNode is SymTokenBalancerNodeEmittedElement )
+			{
+				SymTokenBalancerNodeEmittedElement node = (SymTokenBalancerNodeEmittedElement) aNode;
+				ret = node.Emit;
+			}
+			//
+			return ret;
+		}
+		#endregion
+	}
+	#endregion
+
+	#region SymTokenBalancerNode
+	public class SymTokenBalancerNode : SymNodeToken
+	{
+		#region Constructors & destructor
+		public SymTokenBalancerNode( SymToken aToken )
+			: base( aToken )
+		{
+		}
+		#endregion
+	}
+	#endregion
+
+	#region SymTokenBalancerMarkerNode
+	public class SymTokenBalancerMarkerNode : SymNodeAddAsChild
+	{
+		#region Constructors & destructor
+		public SymTokenBalancerMarkerNode( SymTokenBalancerMatchCriteria aMatchCriteria )
+		{
+			iMatchCriteria = aMatchCriteria;
+		}
+		#endregion
+
+		#region Properties
+		public SymTokenBalancerMatchCriteria MatchCriteria
+		{
+			get { return iMatchCriteria; }
+		}
+		#endregion
+
+		#region Data members
+		private readonly SymTokenBalancerMatchCriteria iMatchCriteria;
+		#endregion
+	}
+	#endregion
+
+	#region SymTokenBalancerMarkerLevelNode
+	public class SymTokenBalancerMarkerLevelNode : SymTokenBalancerMarkerNode
+	{
+		#region Constructors & destructor
+		public SymTokenBalancerMarkerLevelNode( SymTokenBalancerMatchCriteria aMatchCriteria )
+			: base( aMatchCriteria )
+		{
+		}
+		#endregion
+
+		#region From SymNode		
+		public override void Replace( SymNode aReplacement )
+		{
+			if	( HasPrevious && Previous is SymTokenBalancerNodeEmittedElement )
+			{
+				Previous.Remove();
+			}
+			if	( HasNext && Next is SymTokenBalancerNodeEmittedElement )
+			{
+				Next.Remove();
+			}
+
+			base.Replace( aReplacement );
+		}
+		#endregion
+
+		#region API
+		public SymArgumentSubLevel AsArgumentSubLevel( bool aRecurse )
+		{
+			SymArgumentSubLevel ret = new SymArgumentSubLevel( this );
+			//
+			if	( aRecurse )
+			{
+				foreach( SymNode child in ret )
+				{
+					if	( child is SymTokenBalancerMarkerLevelNode )
+					{
+						SymTokenBalancerMarkerLevelNode markerNode = (SymTokenBalancerMarkerLevelNode) child;
+						SymArgumentSubLevel subLevel = markerNode.AsArgumentSubLevel( aRecurse );
+						ret.InsertChild( subLevel, markerNode );
+						markerNode.Remove();
+					}
+				}
+			}
+			//
+			return ret;
+		}
+
+		public void ConvertEmittedElementsToRealTokenNodes( bool aRecurse )
+		{
+			int i = ChildCount;
+			//
+			while( i > 0 )
+			{
+				SymNode child = this[ --i ];
+				//
+				if	( child is SymTokenBalancerNodeEmittedElement )
+				{
+					SymTokenBalancerNodeEmittedElement emittedElement = (SymTokenBalancerNodeEmittedElement) child;
+					if	( emittedElement.Emit )
+					{
+						SymNodeToken replacement = new SymNodeToken( emittedElement.Token ); 
+						InsertChild( replacement, child );
+					}
+					child.Remove();
+				}
+				else if ( child is SymTokenBalancerMarkerLevelNode && aRecurse )
+				{
+					SymTokenBalancerMarkerLevelNode childLevel = (SymTokenBalancerMarkerLevelNode) child;
+					childLevel.ConvertEmittedElementsToRealTokenNodes( aRecurse );
+				}
+			}
+		}
+
+		public int CountTokenByType( SymToken.TClass aClass )
+		{
+			int count = 0;
+			//
+			foreach( SymNode n in this )
+			{
+				if	( n is SymNodeToken )
+				{
+					bool isSpecial = ( n is SymTokenBalancerNode );
+					//
+					if	( isSpecial == false )
+					{
+						SymToken t = ((SymNodeToken) n).Token;
+						//
+						if	( t.Class == aClass )
+						{
+							++count;
+						}
+					}
+				}
+			}
+			//
+			return count;
+		}
+
+		public void Subsume()
+		{
+			System.Diagnostics.Debug.Assert( IsComplete );
+			//
+			SymTokenBalancerNodeEmittedElement previous = EmittedElementPrevious;
+			SymTokenBalancerNodeEmittedElement next = EmittedElementNext;
+
+			// Insert all my children as siblings of myself (i.e. make my parent's
+			// grandchildren its direct children - i.e. promote them up the tree
+			// by one level).
+			SymNode parent = Parent;
+			ArrayList parentsChildren = Parent.Children;
+			parent.InsertChildrenFrom( this /* my children */, previous.Previous /* move them before the opening bracket */);
+
+			// Remove the opening bracket token
+			previous.Remove();
+
+			// Remove the closing bracket token.
+			next.Remove();
+
+			// Remove the level marker token, i.e myself
+			Remove();
+		}
+		#endregion
+
+		#region Properties
+		public bool CanBeSubsumed
+		{
+			get
+			{
+				bool canBeSubsumed = false;
+				//
+				if	( IsComplete )
+				{
+					if	( AreLocalEmittedNodesDiametricallyOposite )
+					{
+						bool isSimple = IsSimple;
+						//
+						if	( isSimple )
+						{
+							// Deal with the case whereby we have something like this: ([SOMETHINGELSE])
+							if	( ( Parent is SymTokenBalancerMarkerLevelNode) && ChildCountLevelNodes == 0 )
+							{
+								// We don't have any child level nodes and our parent is a level (it always sound be in any case).
+								SymTokenBalancerMarkerLevelNode parent = (SymTokenBalancerMarkerLevelNode) Parent;
+								if	( parent.IsComplete )
+								{
+									// Check whether the parent is a function. If it is, then we don't want to subsume the children.
+									bool isFunc = parent.IsFunction;
+									if	( isFunc == false )
+									{
+										// The parent is complete, which means we can compare this level's open and closing tokens
+										// with the parents.
+										canBeSubsumed = ( parent.EmittedElementPrevious.Token.Equals( EmittedElementPrevious.Token ) && 
+											parent.EmittedElementNext.Token.Equals( EmittedElementNext.Token ) );
+									}
+								}
+								else
+								{
+									canBeSubsumed = true;
+								}
+								
+							}
+							else
+							{
+								canBeSubsumed = true;
+							}
+						}
+						else
+						{
+							// Check whether our children contains at least a single argument separator node.
+							// If it does, we can't allow it to be subsumed.
+							if	( ChildCountArgumentNodes == 0 )
+							{
+								if	( Parent is SymTokenBalancerMarkerLevelNode )
+								{
+									SymTokenBalancerMarkerLevelNode parent = (SymTokenBalancerMarkerLevelNode) Parent;
+									bool parentIsSimple = parent.IsSimple;
+									canBeSubsumed = parentIsSimple;
+								}
+							}
+						}
+					}
+				}
+				//
+				return canBeSubsumed;
+			}
+		}
+
+		public bool IsFunction
+		{
+			get
+			{
+				#region Example
+				//
+				// [FUNC_NAME] [(] [*] [)] 
+				//                  |
+				//        [alpha_numeric_child]
+				//
+				#endregion
+				
+				bool bracketsAreCorrect = false;
+				bool hasFunctionName = false;
+				bool childIsValid = false;
+				//
+				if	( AreLocalEmittedNodesDiametricallyOposite )
+				{
+					// Check that the previous node is a function name
+					if	( Previous.HasPrevious )
+					{
+						SymNode previousPrevious = Previous.Previous;
+						if	( previousPrevious is SymNodeToken )
+						{
+							SymNodeToken nodeToken = (SymNodeToken) previousPrevious;
+							hasFunctionName = (nodeToken.Token.Class == SymToken.TClass.EClassAlphaNumeric );
+						}
+					}
+
+					// Check that the brackets are ( and )
+					bracketsAreCorrect = ( EmittedElementPrevious.Token.Value == "(" && EmittedElementNext.Token.Value == ")" );
+
+					// Check that the level node has but one child and that it
+					// is alphanumeric in nature.
+					if	( ChildCountByType( typeof(SymNodeToken) ) > 0 )
+					{
+						foreach( SymNode child in this )
+						{
+							if	( child is SymNodeToken )
+							{
+								SymNodeToken tokenNode = (SymNodeToken) child;
+								//
+								if	( tokenNode.Token.Class == SymToken.TClass.EClassAlphaNumeric )
+								{
+									childIsValid = true;
+									break;
+								}
+							}
+						}
+					}
+				}
+
+				bool isFunction = (bracketsAreCorrect && hasFunctionName && childIsValid );
+				return isFunction;
+			}
+		}
+
+		public bool IsSimple
+		{
+			get
+			{
+				bool isSimple = false;
+				//
+				if	( IsFunction )
+				{
+					isSimple = false;
+				}
+				else if	( ChildCountNonWhiteSpace == 1 )
+				{
+					// My child is but a single node...
+					isSimple = true;
+				}
+				else if ( ChildCountWhiteSpace == ChildCount )
+				{
+					// My children are just whitespace
+					isSimple = true;
+				}
+				else if ( ChildCountLevelNodes == 1 )
+				{
+					int childCountLevelAndAssociatedEmittedNodes = ChildCountLevelAndAssociatedEmittedNodes;
+					int childCount = ChildCount;
+					int whiteSpaceCount = ChildCountWhiteSpace;
+					//
+					if	( (childCount - whiteSpaceCount) == childCountLevelAndAssociatedEmittedNodes )
+					{
+						// Ignoring the whitespace nodes, all we had was a single level node plus its
+						// two associated emitted elements...
+						isSimple = true;
+					}
+				}
+				//
+				return isSimple;
+			}
+		}
+
+		public bool IsComplete
+		{
+			get
+			{
+				bool complete = false;
+
+				// Must have a next and a previous node. Next and previous must be
+				// emitted element nodes
+				if	( HasNext && HasPrevious )
+				{
+					complete = ( Previous is SymTokenBalancerNodeEmittedElement && Next is SymTokenBalancerNodeEmittedElement );
+				}
+
+				return complete;
+			}
+		}
+
+		public bool AreLocalEmittedNodesDiametricallyOposite
+		{
+			get
+			{
+				bool ret = false;
+				//
+				if	( IsComplete )
+				{
+					SymTokenBalancerNodeEmittedElement previous = (SymTokenBalancerNodeEmittedElement) Previous;
+					SymTokenBalancerNodeEmittedElement next = (SymTokenBalancerNodeEmittedElement) Next;
+					//
+					if	( previous.MatchCriteria.DiametricToken.Equals( next.Token ) )
+					{
+						// Paranoid
+						ret = ( next.MatchCriteria.DiametricToken.Equals( previous.Token ) );
+					}
+				}
+				//
+				return ret;
+			}
+		}
+
+		public SymNodeToken FunctionName
+		{
+			get
+			{
+				if	( IsFunction == false )
+				{
+					throw new ArgumentException( "Level node is not a function node" );
+				}
+
+				System.Diagnostics.Debug.Assert( Previous.HasPrevious );
+				System.Diagnostics.Debug.Assert( Previous.Previous is SymNodeToken );
+				SymNodeToken functionNameToken = (SymNodeToken) Previous.Previous;
+				return functionNameToken;
+			}
+		}
+
+		public SymTokenContainer ChildTokens
+		{
+			get
+			{
+				SymTokenContainer ret = new SymTokenContainer();
+				//
+				foreach( SymNode c in this )
+				{
+					if	( c is SymNodeToken )
+					{
+						SymNodeToken t = (SymNodeToken) c;
+						ret.Append( t.Token );
+					}
+				}
+				//
+				return ret;
+			}
+		}
+
+		public int ChildCountWhiteSpace
+		{
+			get
+			{
+				return CountTokenByType( SymToken.TClass.EClassWhiteSpace );
+			}
+		}
+
+		public int ChildCountNonWhiteSpace
+		{
+			get
+			{
+				return ChildCount - ChildCountWhiteSpace;
+			}
+		}
+
+		public int ChildCountLevelNodes
+		{
+			get
+			{
+				int count = ChildCountByType( typeof(SymTokenBalancerMarkerLevelNode) );
+				return count;
+			}
+		}
+
+		public int ChildCountLevelAndAssociatedEmittedNodes
+		{
+			get
+			{
+				int count = 0;
+				//
+				int index = 0;
+				object childLevelNodeObject = ChildByType( typeof(SymTokenBalancerMarkerLevelNode), ref index );
+				while( childLevelNodeObject != null )
+				{
+					// Count is incremented by one each time we find a level node
+					SymTokenBalancerMarkerLevelNode childLevelNode = (SymTokenBalancerMarkerLevelNode) childLevelNodeObject;
+					++count;
+
+					// It should always have a previous token.
+					System.Diagnostics.Debug.Assert( childLevelNode.HasPrevious );
+					if	( childLevelNode.Previous is SymTokenBalancerNodeEmittedElement )
+					{
+						++count;
+					}
+
+					// It may have a next node, assuming its complete...
+					if	( childLevelNode.HasNext )
+					{
+						if	( childLevelNode.Next is SymTokenBalancerNodeEmittedElement )
+						{
+							++count;
+						}
+					}
+
+					// Move to next child level node
+					++index;
+					childLevelNodeObject = ChildByType( typeof(SymTokenBalancerMarkerLevelNode), ref index );
+				}
+				//
+				return count;
+			}
+		}
+
+		public int ChildCountArgumentNodes
+		{
+			get
+			{
+				int count = ChildCountByType( typeof(SymTokenBalancerMarkerArgumentNode) );
+				return count;
+			}
+		}
+
+		public SymTokenBalancerNodeEmittedElement EmittedElementPrevious
+		{
+			get
+			{
+				return (SymTokenBalancerNodeEmittedElement) Previous;
+			}
+		}
+
+		public SymTokenBalancerNodeEmittedElement EmittedElementNext
+		{
+			get
+			{
+				return (SymTokenBalancerNodeEmittedElement) Next;
+			}
+		}
+
+		#endregion
+
+		#region Internal methods
+		#endregion
+	}
+	#endregion
+
+	#region SymTokenBalancerMarkerArgumentNode
+	public class SymTokenBalancerMarkerArgumentNode : SymTokenBalancerMarkerNode
+	{
+		#region Constructors & destructor
+		public SymTokenBalancerMarkerArgumentNode( SymTokenBalancerMatchCriteria aMatchCriteria )
+			: base( aMatchCriteria )
+		{
+		}
+		#endregion
+	}
+	#endregion
+
+	#region SymTokenBalancerNodeEmittedElement
+	public class SymTokenBalancerNodeEmittedElement : SymTokenBalancerMarkerNode
+	{
+		#region Constructors & destructor
+		public SymTokenBalancerNodeEmittedElement( SymToken aToken, SymTokenBalancerMatchCriteria aMatchCriteria )
+			: base( aMatchCriteria )
+		{
+			iToken = aToken;
+		}
+		#endregion
+
+		#region API
+		public void AddToDocumentIfEmittable( SymDocument aDocument )
+		{
+			if	( Emit )
+			{
+				SymNodeToken node = new SymNodeToken( Token );
+				aDocument.CurrentNode.Add( node );
+			}
+		}
+
+		public void AddToContainerIfEmittable( SymTokenContainer aContainer )
+		{
+			if	( Emit )
+			{
+				aContainer.Append( Token );
+			}
+		}
+		#endregion
+
+		#region Properties
+		public SymToken Token
+		{
+			get { return iToken; }
+		}
+
+		public bool Emit
+		{
+			get { return MatchCriteria.Emit; }
+		}
+		#endregion
+
+		#region Data members
+		private readonly SymToken iToken;
+		#endregion
+	}
+	#endregion
+}