Annotation of parser3/src/main/pa_dictionary.C, revision 1.23

1.1       parser      1: /**    @file
                      2:        Parser: dictionary class  impl.
                      3: 
1.23    ! paf         4:        Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com)
1.12      paf         5:        Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
1.15      paf         6: */
1.1       parser      7: 
1.23    ! paf         8: static const char * const IDENT_DICTIONARY_C="$Date: 2004/02/11 15:33:15 $";
1.1       parser      9: 
                     10: #include "pa_dictionary.h"
1.4       parser     11: #include "pa_exception.h"
1.1       parser     12: 
1.18      paf        13: // could not make this static: gcc complains "prev decl was extern"
                     14: void pa_dictionary_add_first(Table::element_type row, Dictionary* self) {
1.4       parser     15:        // get a=>b values
1.18      paf        16:        const String* a=row->get(0);
1.4       parser     17:        // empty 'a' check
1.18      paf        18:        if(a->is_empty()) {
1.14      paf        19:                throw Exception("parser.runtime",
1.18      paf        20:                        0, //&a, 
1.4       parser     21:                        "dictionary table 'from' column elements must not be empty");
                     22:        }
1.19      paf        23:        const String* b;
                     24:        if(row->count()>1) { // are there any b?
                     25:                b=row->get(1);
                     26:                if(b->is_empty())
                     27:                        b=0;
                     28:        } else
                     29:                b=0;
                     30: 
                     31:        // record simplier 'a' for quick comparisons in 'starts' extremely-tight-callback
                     32:        self->substs+=Dictionary::Subst(a->cstr(), b);
                     33: 
1.18      paf        34:        unsigned char c=(unsigned char)a->first_char();
                     35:        if(!self->starting_line_of[c])
                     36:                self->starting_line_of[c]=self->constructor_line;
1.4       parser     37: 
1.18      paf        38:        self->constructor_line++;
1.1       parser     39: }
1.19      paf        40: Dictionary::Dictionary(Table& atable): substs(atable.count()) {
1.4       parser     41:        // clear starting_lines
                     42:        memset(starting_line_of, 0, sizeof(starting_line_of));
1.1       parser     43:        // grab first letters of first column of a table
1.19      paf        44:        constructor_line=1;  atable.for_each(pa_dictionary_add_first, this);
1.1       parser     45: }
                     46: 
1.4       parser     47: #ifndef DOXYGEN
1.18      paf        48: struct First_that_begins_info {
1.4       parser     49:        int line;
1.18      paf        50:        const char* str;
1.4       parser     51: };
                     52: #endif
1.19      paf        53: static bool starts(Dictionary::Subst subst, First_that_begins_info* info) {
1.4       parser     54:        // skip irrelevant lines
1.18      paf        55:        if(info->line>1) {
                     56:                --info->line;
1.4       parser     57:                return 0;
                     58:        }
1.1       parser     59: 
1.19      paf        60:        return strncmp(subst.from, info->str, subst.from_length)==0;
1.1       parser     61: }
1.19      paf        62: Dictionary::Subst Dictionary::first_that_begins(const char* str) const {
1.18      paf        63:        First_that_begins_info info;
1.21      paf        64:        if((info.line=starting_line_of[(unsigned char)*str])) {
1.18      paf        65:                info.str=str;
1.19      paf        66:                return substs.first_that(starts, &info);
1.4       parser     67:        } else
1.19      paf        68:                return 0;
1.1       parser     69: }

E-mail: