示例#1
0
 public TokenSequence(TokenSequence source) : this()
 {
     foreach (Token t in source)
     {
         sequence.Add(t);
     }
 }
示例#2
0
        /// <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);
        }
示例#3
0
 private void RelatedSequenceSetInvoker(TokenSequence relatedSequence)
 {
     if (RelatedSequenceSet != null)
     {
         RelatedSequenceSet(this,
                            new SequenceSetArgs(relatedSequence));
     }
 }
示例#4
0
 private void SequenceRestoredInvoker(TokenSequence backupSequence)
 {
     if (SequenceRestored != null)
     {
         SequenceRestored(this,
                          new SequenceSetArgs(backupSequence));
     }
 }
示例#5
0
        /// <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);
        }
示例#7
0
        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);
        }
示例#8
0
        /// <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);
        }
示例#9
0
        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);
        }
示例#10
0
        /// <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);
        }
示例#11
0
        /// <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);
        }
示例#12
0
 public abstract bool Match(ref TokenSequence sequence, out string text);
示例#13
0
 protected abstract bool MatchSequence(ref TokenSequence sequence, out string output);
示例#14
0
        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);
        }
示例#15
0
        /// <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);
        }