Beispiel #1
0
 /// <summary>Parses input. One of the unit-of-measure parsers. Of type IsUnitOfMeasureSuffix</summary>
 public static int IsOrdinal(string input)
 {
     input = input.Trim();
     if (input.StartsWith("%") || input.StartsWith("percent"))
     {
         numtype = NumberSubtype.Percent;
         return(1); // TODO this is wrong!
     }
     return(0);
 }
Beispiel #2
0
        /// <summary>Parses input. One of the unit-of-measure parsers. Of type IsUnitOfMeasureSuffix</summary>
        public static int IsPercent(string input)
        {
            string suffix = input.Substring(0, 2);

            if (suffix == "st" || suffix == "nd" || suffix == "rd" || suffix == "th")
            {
                numtype = NumberSubtype.Ordinal;
                return(2);
            }
            return(0);
        }
Beispiel #3
0
 public static StandardType AsStandardType(this NumberSubtype t)
 {
     if (t == NumberSubtype.Percent)
     {
         return(StandardType.percent);
     }
     if (t == NumberSubtype.Ordinal)
     {
         return(StandardType.position);
     }
     return(StandardType.number);
 }
Beispiel #4
0
    /// <summary>Parses input.  Will return the int representation of the number or ordinal passed in:  34, 81st,
    /// "one hundred twenty-two", "thirty-seventh", etc. </summary>
    /// <returns>Null if there isn't some sort of number or ordinal at the beginning of the input.</returns>
    public static long?ParseNumberOrdinalPercent(List <string> input)
    {
        numtype       = NumberSubtype.Cardinal; // assume Cardinal number until proven otherwise
        AteTheWordAnd = false;
        //input = input.TrimStart(new[] { ' ', '\t', '\n', '-' });
        long?retval = Number(input);

        if (retval != null)
        {
            return(retval);
        }
        return(SpelledOutOrdinalToNumber(input));
    }
Beispiel #5
0
    /// <summary>Parses input. One of the unit-of-measure parsers. Of type IsUnitOfMeasureSuffix</summary>
    public static int IsOrdinal(List <string> input, int letterPosition)
    {
        if (input[index].Length >= letterPosition)
        {
            return(0);
        }
        string suffix = input[index].Substring(letterPosition, 2);

        if (suffix == "st" || suffix == "nd" || suffix == "rd" || suffix == "th")
        {
            numtype = NumberSubtype.Ordinal;
            return(2);
        }
        return(0);
    }
Beispiel #6
0
 /// <summary>Parses input. One of the unit-of-measure parsers. Of type IsUnitOfMeasureSuffix</summary>
 public static int IsPercent(List <string> input, int letterPosition)
 {
     if (input[index].Length > letterPosition)
     {
         if (input[index].Substring(letterPosition, 1) != "%")
         {
             return(0);
         }
     }
     else if (index + 1 >= input.Count)
     {
         return(0);
     }
     else if (!input[index + 1].StartsWith("percent"))
     {
         return(0);
     }
     numtype = NumberSubtype.Percent;
     return(1); // TODO this is wrong!
 }
Beispiel #7
0
    /// <summary>Parses spelled-out numbers and ordinals like "thirty two thousand four hundred fifty-first"</summary>
    public static long?SpelledOutOrdinalToNumber(List <string> words)
    {
        long?  total = null;
        string word  = "";
        int    i     = 0;
        char   ch;
        string input = words[index];

getNewWord:                              // I tried a recursive version but it didn't work out.
        AteTheWordAnd = (word == "and"); // initialize & reset
        if (total != null)
        {
            input = words[index++];
        }
        if (numtype == NumberSubtype.TentativelyOrdinal)
        {
            numtype = NumberSubtype.Ordinal;
        }

        // begin
        i = -1;
        do
        {
            i++;
            ch = input.ElementAt(i);
        } while (ch >= 'a' && ch <= 'z' && i < input.Length - 1);
        if (i < 1)
        {
            return(total);
        }
        // if we read it something that wasn't a word, stop already and return what, if anything, we already got.

        word = input.Substring(0, i);

retry:  // if none of the defined words match, we'll modify the word suffix and retry. There's 2 strategies.

        if (ordinals.Contains(word))
        {
            if (total == null)
            {
                total = 0;
            }
            total  += ordinals.IndexOf(word);
            numtype = NumberSubtype.Ordinal;
            goto getNewWord;
        }
        if (spelledOutNumbers.Contains(word))
        {
            if (total == null)
            {
                total = 0;
            }
            total += spelledOutNumbers.IndexOf(word);
            goto getNewWord;
        }
        if (spelledOutTens.Contains(word))
        {
            if (total == null)
            {
                total = 0;
            }
            total += spelledOutTens.IndexOf(word) * 10;
            goto getNewWord;
        }
        if (word == "hundred" || spelledOutPowersOfTen.Contains(word))
        {
            if (total == null)
            {
                total = 1;
            }
            long power = (word == "hundred") ? 100 : (long)Math.Pow(10, 3 * spelledOutPowersOfTen.IndexOf(word));
            if (total < power)
            {
                total *= power;
            }
            else
            {
                long subhundred = total.Value % 100;
                total = total - subhundred + subhundred * power;
            }
            goto getNewWord;
        }

        // If we reach here, we don't know the word.
        // Or do we? Perhaps if we played suffix games, we might recognize it after all.
        if (word.EndsWith("tieth"))
        {
            numtype = NumberSubtype.TentativelyOrdinal;
            word    = word.Replace("tieth", "ty");
            goto retry;
        }
        if (word.EndsWith("th"))
        {
            numtype = NumberSubtype.TentativelyOrdinal;
            word    = word.Substring(0, word.Length - 2);
            goto retry;
        }
        if (word == "and")
        {
            goto getNewWord;
        }

        // If we found at least one numeric word, we keep GOTOing until we eventually finish all the words in the phrase.

        if (AteTheWordAnd)
        {
            index--;            // TODO oops!  backtrack the index over this word!!
        }

        // Maybe it's a unit of measure word? If so, this ends it anyway.
        index += ParseAnyUnitsOfMeasure(words, i);

        if (numtype == NumberSubtype.TentativelyOrdinal)
        {
            numtype = NumberSubtype.Cardinal;
        }
        return(total);
    }