Initial import of the CDE 2.1.30 sources from the Open Group.
[oweals/cde.git] / cde / programs / nsgmls / Recognizer.C
1 /* $XConsortium: Recognizer.C /main/1 1996/07/29 17:02:40 cde-hp $ */
2 // Copyright (c) 1994 James Clark
3 // See the file COPYING for copying permission.
4
5 #ifdef __GNUG__
6 #pragma implementation
7 #endif
8 #include "splib.h"
9 #include "Resource.h"
10 #include "Trie.h"
11 #include "Owner.h"
12 #include "XcharMap.h"
13 #include "Recognizer.h"
14 #include "InputSource.h"
15
16 #ifdef SP_NAMESPACE
17 namespace SP_NAMESPACE {
18 #endif
19
20 Recognizer::Recognizer(Trie *trie, const XcharMap<EquivCode> &map)
21 : trie_(trie), map_(map), multicode_(0)
22 {
23 }
24
25 Recognizer::Recognizer(Trie *trie, const XcharMap<EquivCode> &map,
26                        Vector<Token> &suppressTokens)
27 : trie_(trie), map_(map), multicode_(1)
28 {
29   suppressTokens.swap(suppressTokens_);
30 }
31
32 Token Recognizer::recognize(InputSource *in, Messenger &mgr) const
33 {
34   if (multicode_) {
35     in->startToken();
36     if (in->scanSuppress())
37       return suppressTokens_[map_[in->tokenChar(mgr)]];
38   }
39   else
40     in->startTokenNoMulticode();
41   register const Trie *pos = trie_.pointer();
42   do {
43     pos = pos->next(map_[in->tokenChar(mgr)]);
44   } while (pos->hasNext());
45   if (!pos->blank()) {
46     in->endToken(pos->tokenLength());
47     return pos->token();
48   }
49   const BlankTrie *b = pos->blank();
50   const Trie *newPos = b;
51   size_t maxBlanks = b->maxBlanksToScan();
52   size_t nBlanks;
53   for (nBlanks = 0; nBlanks < maxBlanks; nBlanks++) {
54     EquivCode code = map_[in->tokenChar(mgr)];
55     if (!b->codeIsBlank(code)) {
56       if (newPos->hasNext())
57         newPos = newPos->next(code);
58       break;
59     }
60   }
61   while (newPos->hasNext())
62     newPos = newPos->next(map_[in->tokenChar(mgr)]);
63   if (newPos->token() != 0) {
64     in->endToken(newPos->tokenLength() + b->additionalLength() + nBlanks);
65     return newPos->token();
66   }
67   else {
68     in->endToken(pos->tokenLength() + (pos->includeBlanks() ? nBlanks : 0));
69     return pos->token();
70   }
71 }
72
73
74 #ifdef SP_NAMESPACE
75 }
76 #endif