/// <summary>
		/// Retrives the related items for a token from the remaining items list.
		/// </summary>
		/// <param name="matched">
		/// The <see cref="Token"/> the items we are looking for are related to.
		/// </param>
		/// <param name="remainingItems">
		/// A <see cref="TokenSequence"/> containing the yet to be matched items.
		/// </param>
		/// <param name="position">
		/// A <see cref="ExpressionItemPosition"/> the position of the related item.
		/// </param>
		/// <returns>
		/// A <see cref="TokenSequence"/> containing the items related to the
		/// matched item found in the given position.
		/// </returns>
		protected TokenSequence GetRelatedItems(Token matched,
		                                        TokenSequence remainingItems, 
		                                        ExpressionItemPosition position)
		{
			TokenSequence sequence = new TokenSequence();
			
			string remainingItemsString = remainingItems.ToString();
			
			int i= 0;
			while (i < remainingItems.Count)
			{
				Token checkedItem = remainingItems[i];
				
				if(CheckTokenInRelatedSequence(matched, checkedItem, position))
				{
					sequence.Append(checkedItem);
					remainingItems.RemoveAt(i);
				}
				else if(!SpecialPosition(matched, checkedItem))
				{
					LogSentInvoker("Encontrado {0}, cancelando la creación de la secuencia de items «{1}» {2}",
					               checkedItem.Text,
					               position,
					               matched.Type);
					break;
				}
				else
				{
					i++;
				}
			}
			
			LogSentInvoker("Extraida la secuencia ({0}) en posicion «{1}» de entre los elementos de ({2})",
			               sequence,
			               position,
			               remainingItemsString);
			
			return sequence;
		}
		/// <summary>
		/// Matches a given token sequence into one or more Tokens.
		/// </summary>
		/// <param name="sequence">
		/// The token sequence (possibly) containing tokens.
		/// </param>
		private void MatchTokens(SequenceNode node)
		{			
			
			TokenSequence discarded = new TokenSequence();
			
			TokenSequence accepted = new TokenSequence();
			SequenceNode acceptedNode = new SequenceNode(accepted, view);
			SequenceNode discardedNode = new SequenceNode(discarded, view);
			TokenSequence sequence = node.Sequence;
			
			node.AddChildSequence(acceptedNode);
			
			foreach (Token t in sequence) 
			{
				accepted.Append(t);
			}
			
			NodeBeingProcessedInvoker(node);
			SuspendByStep();
			
			bool found = false;
			Token foundToken = null;		
			
			bool discardedNodeAdded = false;
			
			MessageLogSentInvoker("===== Tratando la secuencia {0} =====", 
			                      node.NodeName);
			
			while(accepted.Count > 0 && !found)
			{
				
				
				foreach (LexicalRule rule in lexicalRules) 
				{
					found = rule.Match(accepted, out foundToken);
				
					MessageLogSentInvoker("¿La regla «{0}» acepta la secuencia ({1})?: {2}", 
					                      rule.Name,
					                      accepted.ToString(),
					                      found?"Sí":"No");
					
					SequenceBeingMatchedInvoker(foundToken, rule, found);
					SuspendByStep();
					
					if(found)
					{
						// We search no more.
						break;
					}				
					Thread.Sleep(50);
				}
				
				// We check if a token was found
				if(!found)
				{
					// We remove the token from the input sequence and add it
					// at the beggining of the discarded set.
					int lastIndex = accepted.Count -1;
					if(!discardedNodeAdded)
					{
						// If we haven't done so, we add the discarded sequence.
						node.AddChildSequence(discardedNode);
						discardedNodeAdded = true;
					}
					
					this.MatchingFailedInvoker();
					
					MessageLogSentInvoker("Se elimina el último símbolo de la secuencia {0} para seguir probando.",
					                      accepted.ToString());
						
					discarded.Prepend(accepted[lastIndex]);
					
					accepted.RemoveAt(lastIndex);				
					
				}
				else
				{
					// We found a token, so we stop searching and add
					// the token to the result.
					acceptedNode.FoundToken = foundToken;
				}
			}
			
		
			
			if(found && discarded.Count > 0)
			{
				MessageLogSentInvoker("Se tratará la secuencia de símbolos descartados.");
				// We follow the recursive path.
				MatchTokens(discardedNode);
			}
			else if(found && discarded.Count ==0)
			{
				// Only one token was found, we assimilate the acceptedNode
				// with its parent.
				node.FoundToken = foundToken;
				node.RemoveSequenceChildren();
			}
			else
			{
				// If nothing was found, we remove the children.
				node.RemoveSequenceChildren();
				
				MessageLogSentInvoker("No se pudo reconocer la secuencia {0}.",
					                   node.Sequence.ToString());
			}
			
			StepDoneInvoker();
			SuspendByNode();
		}
		/// <summary>
		/// Tries to match the expetect token with one from the given sequence.
		/// </summary>
		/// <param name="sequence">
		/// A <see cref="TokenSequence"/> containing the items not yet matched.
		/// </param>
		/// <param name="output">
		/// The output in a <see cref="System.String"/>.
		/// </param>
		/// <returns>
		/// A <see cref="System.Boolean"/> that tells if the matching process
		/// was successful.
		/// </returns>
		protected override bool MatchSequence (ref TokenSequence sequence, 
		                                       out string output)
		{
			
			output ="";
			int idx = 0;
			
			// We tell the controller we are trying to match this token.			
			TokenMatchingInvoker(this.TokenType);
			
			if(forceTokenSearch)
			{
				idx = sequence.SearchToken(this.tokenType);
				LogSentInvoker("Forzada búsqueda de {0}, posición {1}",
				               this.tokenType,
				               idx);
			}		
			
			
			// By default, we say we had a success
			bool res = true;
			Token matched = null;
			
			
			
			if(idx==-1)
			{
				LogSentInvoker("El item esperado {0} no fue encontrado.", this.tokenType);
				res = !IsCompulsory;
			}			
			else
			{
				bool different;
			
				// If the token type is a literal, we compare with the text
				// instead of the type.
				if(this.tokenType.StartsWith("'")
				   && this.tokenType.EndsWith("'"))
				{
					string expectedText = tokenType.Substring(1,
					                                          this.tokenType.Length -2) ;
					different =expectedText != sequence[idx].Text;
				}
				else
				{
					different = tokenType != sequence[idx].Type;
				}
				
				if(different)
				{
					LogSentInvoker("El item esperado {0} no fue encontrado.", this.tokenType);
					res = !IsCompulsory;
				}
				else
				{
					matched = sequence.RemoveAt(idx);				
					if(this.relatedItems.Count ==0)
					{
						output= String.Format(formatString, matched.Text);
					}
					else
					{
						res = MatchRelatedItems(matched, ref sequence, out output);
						if(!res)
						{
							matched = null;
						}
						
						RelatedSequenceSetInvoker(sequence);
					}
				}
				
				
				
			}
			
			
						
			// We tell the controller we finished matching the token.
			TokenMatchingFinishedInvoker(matched, this.tokenType);
			
			return res;
			
		}
Esempio n. 4
0
        /// <summary>
        /// Matches a given token sequence into one or more Tokens.
        /// </summary>
        /// <param name="sequence">
        /// The token sequence (possibly) containing tokens.
        /// </param>
        private void MatchTokens(SequenceNode node)
        {
            TokenSequence discarded = new TokenSequence();

            TokenSequence accepted      = new TokenSequence();
            SequenceNode  acceptedNode  = new SequenceNode(accepted, view);
            SequenceNode  discardedNode = new SequenceNode(discarded, view);
            TokenSequence sequence      = node.Sequence;

            node.AddChildSequence(acceptedNode);

            foreach (Token t in sequence)
            {
                accepted.Append(t);
            }

            NodeBeingProcessedInvoker(node);
            SuspendByStep();

            bool  found      = false;
            Token foundToken = null;

            bool discardedNodeAdded = false;

            MessageLogSentInvoker("===== Tratando la secuencia {0} =====",
                                  node.NodeName);

            while (accepted.Count > 0 && !found)
            {
                foreach (LexicalRule rule in lexicalRules)
                {
                    found = rule.Match(accepted, out foundToken);

                    MessageLogSentInvoker("¿La regla «{0}» acepta la secuencia ({1})?: {2}",
                                          rule.Name,
                                          accepted.ToString(),
                                          found?"Sí":"No");

                    SequenceBeingMatchedInvoker(foundToken, rule, found);
                    SuspendByStep();

                    if (found)
                    {
                        // We search no more.
                        break;
                    }
                    Thread.Sleep(50);
                }

                // We check if a token was found
                if (!found)
                {
                    // We remove the token from the input sequence and add it
                    // at the beggining of the discarded set.
                    int lastIndex = accepted.Count - 1;
                    if (!discardedNodeAdded)
                    {
                        // If we haven't done so, we add the discarded sequence.
                        node.AddChildSequence(discardedNode);
                        discardedNodeAdded = true;
                    }

                    this.MatchingFailedInvoker();

                    MessageLogSentInvoker("Se elimina el último símbolo de la secuencia {0} para seguir probando.",
                                          accepted.ToString());

                    discarded.Prepend(accepted[lastIndex]);

                    accepted.RemoveAt(lastIndex);
                }
                else
                {
                    // We found a token, so we stop searching and add
                    // the token to the result.
                    acceptedNode.FoundToken = foundToken;
                }
            }



            if (found && discarded.Count > 0)
            {
                MessageLogSentInvoker("Se tratará la secuencia de símbolos descartados.");
                // We follow the recursive path.
                MatchTokens(discardedNode);
            }
            else if (found && discarded.Count == 0)
            {
                // Only one token was found, we assimilate the acceptedNode
                // with its parent.
                node.FoundToken = foundToken;
                node.RemoveSequenceChildren();
            }
            else
            {
                // If nothing was found, we remove the children.
                node.RemoveSequenceChildren();

                MessageLogSentInvoker("No se pudo reconocer la secuencia {0}.",
                                      node.Sequence.ToString());
            }

            StepDoneInvoker();
            SuspendByNode();
        }