Diff for /parser3/src/main/pa_dictionary.C between versions 1.17.2.2 and 1.31

version 1.17.2.2, 2003/01/24 11:33:03 version 1.31, 2024/09/07 16:30:26
Line 1 Line 1
 /**     @file  /**     @file
         Parser: dictionary class  impl.          Parser: dictionary class  impl.
   
         Copyright (c) 2001, 2003 ArtLebedev Group (http://www.artlebedev.com)          Copyright (c) 2001-2023 Art. Lebedev Studio (http://www.artlebedev.com)
         Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)          Authors: Konstantin Morshnev <moko@design.ru>, Alexandr Petrosian <paf@design.ru>
 */  */
   
 static const char* IDENT_DICTIONARY_C="$Date$";  
   
 #include "pa_dictionary.h"  #include "pa_dictionary.h"
 #include "pa_exception.h"  #include "pa_exception.h"
   
 static void add_first(Table::element_type row, Dictionary* self) {  volatile const char * IDENT_PA_DICTIONARY_C="$Id$" IDENT_PA_DICTIONARY_H;
         // get a=>b values  
         ConstStringPtr a=row->get(0);  Dictionary::Dictionary(Table& atable): substs(atable.count()) {
         ConstStringPtr b=row->get(1);          // clear starting_lines
         // empty 'a' check          memset(starting_line_of, 0, sizeof(starting_line_of));
         if(a->is_empty()) {          // grab first letters of first column of a table
                 throw Exception("parser.runtime",          constructor_line=1;
                         a,   
                         "dictionary table 'from' column elements must not be empty");  
         }  
         unsigned char c=(unsigned char)a->first_char();  
         if(!self->starting_line_of[c])  
                 self->starting_line_of[c]=self->constructor_line;  
   
         double ratio=((double)b->size())/a->size();  
         if(ratio>self->fmax_ratio)  
                 self->fmax_ratio=ratio;  
   
         self->constructor_line++;          for(Array_iterator<ArrayString*> i(atable); i; ) {
                   ArrayString* row=i.next();
   
                   append_subst(
                           row->get(0),
                           (row->count()>1) ? row->get(1) : 0,
                           "dictionary table 'from' column elements must not be empty"
                   );
           }
 }  }
 Dictionary::Dictionary(TablePtr  atable, double amin_ratio):  
         table(atable),   
         fmax_ratio(amin_ratio)  {  
   
   Dictionary::Dictionary(const String& from, const String& to): substs(1) {
         // clear starting_lines          // clear starting_lines
         memset(starting_line_of, 0, sizeof(starting_line_of));          memset(starting_line_of, 0, sizeof(starting_line_of));
         // grab first letters of first column of a table          constructor_line=1;
         constructor_line=1;  table->for_each(add_first, this);  
           append_subst(&from, &to);
   }
   
   
   void Dictionary::append_subst(const String* from, const String* to, const char* exception_cstr) {
           if(from->is_empty())
                   throw Exception(PARSER_RUNTIME,
                           0,
                           exception_cstr ? exception_cstr : "'from' must not be empty");
   
           // record simplier 'from' for quick comparisons in 'starts' extremely-tight-callback
           substs+=Dictionary::Subst(from->cstr(), (to && !to->is_empty()) ? to : 0);
   
           unsigned char c=(unsigned char)from->first_char();
           if(!starting_line_of[c])
                   starting_line_of[c]=constructor_line;
   
           constructor_line++;
 }  }
   
 #ifndef DOXYGEN  #ifndef DOXYGEN
 struct First_that_starts_info {  struct First_that_begins_info {
         int line;          int line;
         const char *src;  size_t src_size;          const char* str;
 };  };
 #endif  #endif
 static bool starts(Table::element_type row, First_that_starts_info* info) {  static bool starts(Dictionary::Subst subst, First_that_begins_info* info) {
         // skip irrelevant lines          // skip irrelevant lines
         if(info->line>1) {          if(info->line>1) {
                 --info->line;                  --info->line;
                 return 0;                  return 0;
         }          }
   
         int partial;          return strncmp(subst.from, info->str, subst.from_length)==0;
         row->get(0)->cmp(partial, info->src, info->src_size);  
         return (  
                 partial==0 || // full match  
                 partial==1); // typo left column starts 'src'  
 }  }
   Dictionary::Subst Dictionary::first_that_begins(const char* str) const {
 Table::element_type Dictionary::first_that_starts(const char *src, size_t src_size) const {          First_that_begins_info info;
         First_that_starts_info info;          if((info.line=starting_line_of[(unsigned char)*str])) {
         if(info.line=starting_line_of[(unsigned char)*src]) {                  info.str=str;
                 info.src=src;                  return substs.first_that(starts, &info);
                 info.src_size=src_size;  
                 return table->first_that(starts, &info);  
         } else          } else
                 return Table::element_type(0);                  return 0;
 }  }

Removed from v.1.17.2.2  
changed lines
  Added in v.1.31


E-mail: