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: