/** @file
Parser: dictionary class impl.
Copyright (c) 2001-2003 ArtLebedev Group (http://www.artlebedev.com)
Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
*/
static const char* IDENT_DICTIONARY_C="$Date: 2003/02/04 10:32:12 $";
#include "pa_dictionary.h"
#include "pa_exception.h"
void Dictionary::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;
self->constructor_line++;
}
Dictionary::Dictionary(TablePtr atable, double amin_ratio):
table(atable),
fmax_ratio(amin_ratio) {
// clear starting_lines
memset(starting_line_of, 0, sizeof(starting_line_of));
// grab first letters of first column of a table
constructor_line=1; table->for_each(add_first, this);
}
#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(0)->cmp(partial, info->src, info->src_size);
return (
partial==0 || // full match
partial==1); // typo left column starts 'src'
}
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);
}
E-mail: