public TokenSequence(TokenSequence source) : this() { foreach (Token t in source) { sequence.Add(t); } }
/// <summary> /// Tries to math a <see cref="TokenSequence"/> with the rule's /// expressions. /// </summary> /// <param name="sequence"> /// The <see cref="TokenSequence"/> we want to match. /// </param> /// <param name="text"> /// The <see cref="System.String"/> output text produced by the /// expression that matched the input sequence. /// </param> /// <returns> /// <c>true</c> it the sequence was matched correctly, <c>false</c> /// if there were errors. /// </returns> public override bool Match(ref TokenSequence sequence, out string text) { TokenSequence backupSequence = new TokenSequence(sequence); this.LogSentInvoker("Se intentará aplicar la regla «{0}»", this.Label); foreach (SyntacticalExpression expression in expressions) { this.LogSentInvoker("Se intentará aplicar la expresión «" + expression.Label + "»"); string expressionRes; if (expression.Match(ref sequence, out expressionRes)) { // If the matching is successful, we consider // the output valid. text = expressionRes; return(true); } else { sequence = new TokenSequence(backupSequence); SequenceRestoredInvoker(sequence); } } text = ""; return(false); }
private void RelatedSequenceSetInvoker(TokenSequence relatedSequence) { if (RelatedSequenceSet != null) { RelatedSequenceSet(this, new SequenceSetArgs(relatedSequence)); } }
private void SequenceRestoredInvoker(TokenSequence backupSequence) { if (SequenceRestored != null) { SequenceRestored(this, new SequenceSetArgs(backupSequence)); } }
/// <summary> /// Tries to match a given token sequence with this rule. /// </summary> /// <param name="tokens"> /// The tokens we try to group. /// </param> /// <param name="foundToken"> /// The token result of joining the sequence, has a meaning or not. /// </param> /// <returns> /// If a valid token was found. /// </returns> public bool Match(TokenSequence tokens, out Token foundToken) { // We form the expression to be matched. string text = ""; foreach (Token t in tokens) { if (!String.IsNullOrEmpty(t.Type)) { text += String.Format("%%{0}%%", t.Type); } else { text += t.Text; } } if (regularExpressions == null) { // We have to load the expressions. regularExpressions = new List <Regex>(); foreach (string pattern in lexicalExpressions) { // We add the modifiers to apply the regex to all the // text. Regex regex = new Regex(String.Format("^{0}$", pattern), RegexOptions.Compiled | RegexOptions.Singleline); regularExpressions.Add(regex); } } bool found = false; // Now we try to match a rule with the text. foreach (Regex expression in regularExpressions) { Match match = expression.Match(text); if (match.Success) { found = true; break; } } foundToken = Token.Join(tokens, this.ruleName); return(found); }
protected override bool MatchSequence(ref TokenSequence sequence, out string output) { // The actual matching is done by the rule. SyntacticalRule ruleCalled = SyntacticalRulesLibrary.Instance[ruleName]; bool res = ruleCalled.Match(ref sequence, out output); if (res) { output = String.Format(formatString, output); } return(res); }
public override bool Match(ref TokenSequence sequence, out string output) { string sequenceOriginal = sequence.ToString(); MatchingInvoker(); List <string> outputList = new List <string>(); bool res; foreach (ExpressionItem item in items) { string expressionString; res = item.Match(ref sequence, out expressionString); if (!res) { output = ""; LogSentInvoker("La expresión «" + this.Label + "» falló el reconocimiento, restaurando la secuencia (" + sequenceOriginal + ")"); MatchingFinishedInvoker(output); return(false); } outputList.Add(expressionString); } output = String.Format(formatString, outputList.ToArray()); LogSentInvoker("La expresion «" + this.Label + "» tuvo exito al reconocer, se produjo la salida «" + output + "»"); MatchingFinishedInvoker(output); return(true); }
/// <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); }
protected override bool MatchSequence(ref TokenSequence sequence, out string output) { output = ""; List <string> res = new List <string>(); foreach (ExpressionItem item in childrenItems) { string auxOutput; if (item.Match(ref sequence, out auxOutput)) { res.Add(auxOutput); } else { return(false); } } output = String.Format(FormatString, res.ToArray()); return(true); }
/// <summary> /// Tries to match the token's related items. /// </summary> /// <param name="matched"> /// The <see cref="Token"/> matched token. /// </param> /// <param name="sequence"> /// The remaining tokens. /// </param> /// <param name="output"> /// A <see cref="System.String"/> containing the output. /// </param> /// <returns> /// A <see cref="System.Boolean"/> indicating if the matching was /// successfull. /// </returns> private bool MatchRelatedItems(Token matched, ref TokenSequence sequence, out string output) { output = ""; // We return true unless we found a matching error in one of the // related items. bool res = true; // We have to create a list of outputs, so we can apply the // output format string later. List <string> outputs = new List <string>(); // We add the matched token own text as the first element outputs.Add(matched.Text); foreach (ExpressionItem relatedItem in this.relatedItems) { TokenSequence backupSequence = new TokenSequence(sequence); string relatedItemOutput; TokenSequence relatedRemnant = GetRelatedItems(matched, sequence, relatedItem.Position); LogSentInvoker("Reconociendo los items relacionados ({0}) de {1} con el elemento «{2}»", relatedRemnant, matched.Type, relatedItem.ToString()); RelatedSequenceSetInvoker(relatedRemnant); bool matchRes = relatedItem.Match(ref relatedRemnant, out relatedItemOutput); if (matchRes) { outputs.Add(relatedItemOutput); if (relatedRemnant.Count > 0) { // We weren't unable to match all the tokens, // so we have to restore partially. sequence = backupSequence; int i = 0; while (i < sequence.Count) { if (!relatedRemnant.Sequence.Contains(sequence[i])) { sequence.Sequence.Remove(sequence[i]); } else { i++; } } } } else if (!relatedItem.IsCompulsory) { // We can fail, because then we may be removing tokens useful // to later rules; outputs.Add(""); sequence = backupSequence; } else { res = false; break; } } if (res) { output = String.Format(this.formatString, outputs.ToArray()); } return(res); }
/// <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); }
public abstract bool Match(ref TokenSequence sequence, out string text);
protected abstract bool MatchSequence(ref TokenSequence sequence, out string output);
public override bool Match(ref TokenSequence sequence, out string res) { MatchingInvoker(); LogSentInvoker("Se intentará concordar el elemento «" + this.Label + "»"); bool result = true; res = ""; int counter = 0; int initialCount = sequence.Count; string auxOutput; switch (modifier) { case ExpressionItemModifier.Repeating: while (sequence.Count > 0 && this.MatchSequence(ref sequence, out auxOutput)) { counter++; res += auxOutput; } if (counter == 0) { result = false; } break; case ExpressionItemModifier.RepeatingNonCompulsory: while (sequence.Count > 0) { initialCount = sequence.Count; if (this.MatchSequence(ref sequence, out auxOutput)) { counter++; res += auxOutput; } else if (initialCount != sequence.Count) { result = false; break; } else { break; } } break; case ExpressionItemModifier.NonCompulsory: if (sequence.Count > 0) { result = this.MatchSequence(ref sequence, out auxOutput); res = auxOutput; } break; default: if (sequence.Count > 0 && this.MatchSequence(ref sequence, out auxOutput)) { res = auxOutput; } else { result = false; } break; } if (result) { LogSentInvoker("Se logró concordar exitosamente «" + this.Label + "», se sube al elemento padre."); } else { LogSentInvoker("No se pudo concordar «" + this.Label + "», se sube al elemento padre."); } MatchingFinishedInvoker(res); return(result); }
/// <summary> /// Joins several tokens in one token. /// </summary> /// <param name="tokens"> /// A <see cref="TokenSequence"/> /// </param> /// <param name="tokenType"> /// The new token's type. /// </param> /// <returns> /// A <see cref="Token"/> /// </returns> public static Token Join(TokenSequence tokens, string tokenType) { int maxY = -1; int maxX = -1; int minY = int.MaxValue; int minX = int.MaxValue; string newText = ""; // We have to calculate the new image's bounds, and join the // texts. foreach (Token t in tokens) { if (t.y < minY) { minY = t.y; } if (t.y + t.Height > maxY) { maxY = t.y + t.Height; } if (t.x < minX) { minX = t.x; } if (t.x + t.Width > maxX) { maxX = t.x + t.Width; } newText += t.Text; } int height = maxY - minY; int width = maxX - minX; FloatBitmap image = new FloatBitmap(width, height); // We copy the images in the result image. foreach (Token t in tokens) { for (int i = 0; i < t.image.Width; i++) { for (int j = 0; j < t.image.Height; j++) { // We transform the coordinates so we place the // pixel correctly on the new image. int x = i + t.Left - minX; int y = j + t.Top - minY; image[x, y] = t.image[i, j]; } } } Token newToken = new Token(newText, minX, minY, image); newToken.type = tokenType; // We are going to suppose that we are joining a sequence that // shares baseline and bodyline, because all other joined tokens // won't be used. newToken.baseline = tokens.Last.Baseline; newToken.bodyline = tokens.Last.Bodyline; return(newToken); }