--- parser3/src/main/pa_dictionary.C 2001/08/02 07:00:08 1.2 +++ parser3/src/main/pa_dictionary.C 2003/01/31 12:34:36 1.17.2.4 @@ -1,41 +1,71 @@ /** @file Parser: dictionary class impl. - Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com) - - Author: Alexander Petrosyan (http://design.ru/paf) + Copyright (c) 2001-2003 ArtLebedev Group (http://www.artlebedev.com) + Author: Alexandr Petrosian (http://paf.design.ru) */ -static const char *RCSId="$Id: pa_dictionary.C,v 1.2 2001/08/02 07:00:08 parser Exp $"; + +static const char* IDENT_DICTIONARY_C="$Date: 2003/01/31 12:34:36 $"; #include "pa_dictionary.h" +#include "pa_exception.h" +static void add_first(Table::element_type row, Dictionary* self) { + // get a=>b values + StringPtr a=row->get(0); + StringPtr b=row->get(1); + // empty 'a' check + if(a->is_empty()) { + throw Exception("parser.runtime", + 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; -static void add_first(Array::Item *value, void *info) { - Dictionary& self=*static_cast(info); - self.first[(unsigned char)static_cast(value)->get_string(0)->first_char()]=true; + self->constructor_line++; } +Dictionary::Dictionary(TablePtr atable, double amin_ratio): + table(atable), + fmax_ratio(amin_ratio) { -Dictionary::Dictionary(Table& atable) : Pooled(atable.pool()), table(atable) { - // clear firsts - memset(first, 0, sizeof(first)); + // clear starting_lines + memset(starting_line_of, 0, sizeof(starting_line_of)); // grab first letters of first column of a table - table.for_each(add_first, this); + constructor_line=1; table->for_each(add_first, this); } -static bool starts(Array::Item *value, const void *info) { - Array *row=static_cast(value); - const char *src=static_cast(info); +#ifndef DOXYGEN +struct First_that_starts_info { + int line; + const char* src; size_t src_size; +}; +#endif +static bool starts(Table::element_type row, First_that_starts_info* info) { + // skip irrelevant lines + if(info->line>1) { + --info->line; + return 0; + } int partial; - row->get_string(0)->cmp(partial, src); - return + row->get(0)->cmp(partial, info->src, info->src_size); + return ( partial==0 || // full match - partial==1; // typo left column starts 'src' + partial==1); // typo left column starts 'src' } -void* Dictionary::first_that_starts(const char *src) const { - if(first[(unsigned char)*src]) - return table.first_that(starts, src); - else - return 0; +Table::element_type Dictionary::first_that_starts(const char* src, size_t src_size) const { + First_that_starts_info info; + if(info.line=starting_line_of[(unsigned char)*src]) { + info.src=src; + info.src_size=src_size; + return table->first_that(starts, &info); + } else + return Table::element_type(0); }