home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 20 / AACD20.BIN / AACD / Programming / Jikes / Source / src / spell.h < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-24  |  3.9 KB  |  139 lines

  1. // $Id: spell.h,v 1.7 2001/01/05 09:13:21 mdejong Exp $
  2. //
  3. // This software is subject to the terms of the IBM Jikes Compiler
  4. // License Agreement available at the following URL:
  5. // http://www.ibm.com/research/jikes.
  6. // Copyright (C) 1996, 1999, International Business Machines Corporation
  7. // and others.  All Rights Reserved.
  8. // You must accept the terms of that agreement to use this software.
  9. //
  10. #ifndef spell_INCLUDED
  11. #define spell_INCLUDED
  12.  
  13. #include "platform.h"
  14. #include "case.h"
  15.  
  16. #ifdef    HAVE_JIKES_NAMESPACE
  17. namespace Jikes {    // Open namespace Jikes block
  18. #endif
  19.  
  20. class Spell
  21. {
  22.     static inline int Min(int x, int y) { return (x < y ? x : y); }
  23.  
  24. public:
  25.     static int Index(wchar_t *str1, wchar_t *str2)
  26.     {
  27.         int len1 = wcslen(str1),
  28.             len2 = wcslen(str2);
  29.  
  30.         wchar_t *s1 = new wchar_t[len1 + 1],
  31.                 *s2 = new wchar_t[len2 + 1];
  32.  
  33.         for (int i = 0; i < len1; i++)
  34.             s1[i] = Case::ToAsciiLower(str1[i]);
  35.         s1[len1] = U_NULL;
  36.  
  37.         for (int j = 0; j < len2; j++)
  38.             s2[j] = Case::ToAsciiLower(str2[j]);
  39.         s2[len2] = U_NULL;
  40.  
  41.         if (len1 == 1 && len2 == 1)
  42.         {
  43.             //
  44.             //  Singleton mispellings:
  45.             //
  46.             //  ;      <---->     ,
  47.             //
  48.             //  ;      <---->     :
  49.             //
  50.             //  .      <---->     ,
  51.             //
  52.             //  '      <---->     "
  53.             //
  54.             if ((s1[0] == U_SEMICOLON    &&  s2[0] == U_COMMA)  ||
  55.                 (s1[0] == U_COMMA        &&  s2[0] == U_SEMICOLON)  ||
  56.                 (s1[0] == U_SEMICOLON    &&  s2[0] == U_COLON)  ||
  57.                 (s1[0] == U_COLON        &&  s2[0] == U_SEMICOLON)  ||
  58.                 (s1[0] == U_DOT          &&  s2[0] == U_COMMA)  ||
  59.                 (s1[0] == U_COMMA        &&  s2[0] == U_DOT)  ||
  60.                 (s1[0] == U_SINGLE_QUOTE &&  s2[0] == U_DOUBLE_QUOTE)  ||
  61.                 (s1[0] == U_DOUBLE_QUOTE &&  s2[0] == U_SINGLE_QUOTE))
  62.                     return 3;
  63.         }
  64.  
  65.         //
  66.         // Scan the two strings. Increment "match" count for each match.
  67.         // When a transposition is encountered, increase "match" count
  68.         // by two but count it as an error. When a typo is found, skip
  69.         // it and count it as an error. Otherwise we have a mismatch; if
  70.         // one of the strings is longer, increment its index, otherwise,
  71.         // increment both indices and continue.
  72.         //
  73.         // This algorithm is an adaptation of a boolean misspelling
  74.         // algorithm proposed by Juergen Uhl.
  75.         //
  76.         int count = 0,
  77.             prefix_length = 0,
  78.             num_errors = 0,
  79.             i1 = 0,
  80.             i2 = 0;
  81.  
  82.         while ((i1 < len1)  &&  (i2 < len2))
  83.         {
  84.             if (s1[i1] == s2[i2])
  85.             {
  86.                 count++;
  87.                 i1++;
  88.                 i2++;
  89.                 if (num_errors == 0)
  90.                     prefix_length++;
  91.             }
  92.             else if (s1[i1 + 1] == s2[i2]  &&  s1[i1] == s2[i2 + 1])
  93.             {
  94.                 count += 2;
  95.                 i1 += 2;
  96.                 i2 += 2;
  97.                 num_errors++;
  98.             }
  99.             else if (s1[i1 + 1] == s2[i2 + 1])
  100.             {
  101.                 i1++;
  102.                 i2++;
  103.                 num_errors++;
  104.             }
  105.             else
  106.             {
  107.                 if ((len1 - i1) > (len2 - i2))
  108.                      i1++;
  109.                 else if ((len2 - i2) > (len1 - i1))
  110.                      i2++;
  111.                 else
  112.                 {
  113.                     i1++;
  114.                     i2++;
  115.                 }
  116.                 num_errors++;
  117.             }
  118.         }
  119.  
  120.         if (i1 < len1  ||  i2 < len2)
  121.             num_errors++;
  122.  
  123.         if (num_errors > (Min(len1, len2) / 6 + 1))
  124.              count = prefix_length;
  125.  
  126.         delete [] s1;
  127.         delete [] s2;
  128.  
  129.         return (count * 10 / (len1 + num_errors));
  130.     }
  131. };
  132.  
  133. #ifdef    HAVE_JIKES_NAMESPACE
  134. }            // Close namespace Jikes block
  135. #endif
  136.  
  137. #endif // #ifndef spell_INCLUDED
  138.  
  139.