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

1.1       parser      1: /**    @file
                      2:        Parser: dictionary class  impl.
                      3: 
1.32    ! moko        4:        Copyright (c) 2001-2024 Art. Lebedev Studio (http://www.artlebedev.com)
1.30      moko        5:        Authors: Konstantin Morshnev <moko@design.ru>, Alexandr Petrosian <paf@design.ru>
1.15      paf         6: */
1.1       parser      7: 
                      8: #include "pa_dictionary.h"
1.4       parser      9: #include "pa_exception.h"
1.1       parser     10: 
1.32    ! moko       11: volatile const char * IDENT_PA_DICTIONARY_C="$Id: pa_dictionary.C,v 1.31 2024/09/07 16:30:26 moko Exp $" IDENT_PA_DICTIONARY_H;
1.26      moko       12: 
1.25      misha      13: Dictionary::Dictionary(Table& atable): substs(atable.count()) {
                     14:        // clear starting_lines
                     15:        memset(starting_line_of, 0, sizeof(starting_line_of));
                     16:        // grab first letters of first column of a table
                     17:        constructor_line=1;
1.19      paf        18: 
1.31      moko       19:        for(Array_iterator<ArrayString*> i(atable); i; ) {
1.25      misha      20:                ArrayString* row=i.next();
1.19      paf        21: 
1.25      misha      22:                append_subst(
                     23:                        row->get(0),
                     24:                        (row->count()>1) ? row->get(1) : 0,
                     25:                        "dictionary table 'from' column elements must not be empty"
                     26:                );
                     27:        }
                     28: }
1.4       parser     29: 
1.25      misha      30: Dictionary::Dictionary(const String& from, const String& to): substs(1) {
1.4       parser     31:        // clear starting_lines
                     32:        memset(starting_line_of, 0, sizeof(starting_line_of));
1.25      misha      33:        constructor_line=1;
                     34: 
                     35:        append_subst(&from, &to);
                     36: }
                     37: 
                     38: 
                     39: void Dictionary::append_subst(const String* from, const String* to, const char* exception_cstr) {
                     40:        if(from->is_empty())
                     41:                throw Exception(PARSER_RUNTIME,
                     42:                        0,
                     43:                        exception_cstr ? exception_cstr : "'from' must not be empty");
                     44: 
                     45:        // record simplier 'from' for quick comparisons in 'starts' extremely-tight-callback
                     46:        substs+=Dictionary::Subst(from->cstr(), (to && !to->is_empty()) ? to : 0);
                     47: 
                     48:        unsigned char c=(unsigned char)from->first_char();
                     49:        if(!starting_line_of[c])
                     50:                starting_line_of[c]=constructor_line;
                     51: 
                     52:        constructor_line++;
1.1       parser     53: }
                     54: 
1.4       parser     55: #ifndef DOXYGEN
1.18      paf        56: struct First_that_begins_info {
1.4       parser     57:        int line;
1.18      paf        58:        const char* str;
1.4       parser     59: };
                     60: #endif
1.19      paf        61: static bool starts(Dictionary::Subst subst, First_that_begins_info* info) {
1.4       parser     62:        // skip irrelevant lines
1.18      paf        63:        if(info->line>1) {
                     64:                --info->line;
1.4       parser     65:                return 0;
                     66:        }
1.1       parser     67: 
1.19      paf        68:        return strncmp(subst.from, info->str, subst.from_length)==0;
1.1       parser     69: }
1.19      paf        70: Dictionary::Subst Dictionary::first_that_begins(const char* str) const {
1.18      paf        71:        First_that_begins_info info;
1.21      paf        72:        if((info.line=starting_line_of[(unsigned char)*str])) {
1.18      paf        73:                info.str=str;
1.19      paf        74:                return substs.first_that(starts, &info);
1.4       parser     75:        } else
1.19      paf        76:                return 0;
1.1       parser     77: }

E-mail: