2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $XConsortium: ContentToken.h /main/1 1996/07/29 16:48:40 cde-hp $ */
24 // Copyright (c) 1994 James Clark
25 // See the file COPYING for copying permission.
27 #ifndef ContentToken_INCLUDED
28 #define ContentToken_INCLUDED 1
40 namespace SP_NAMESPACE {
43 class LeafContentToken;
45 struct SP_API Transition {
48 enum { invalidIndex = -1 };
49 // When performing this transition, reset all andState with index >= this.
50 unsigned clearAndStateStartIndex;
51 // This transition is possible only if all AND groups whose AND depth
52 // is >= this (and contains the LeafContentToken that this transition is
53 // from) have had all their non-nullable members matched.
55 // If this is 1, then this transition requires that the AND group
56 // whose AND depth is andDepth - 1 have a non-nullable member unmatched,
57 // and thus this transition is not ambiguous with a transition whose
58 // AND depth is < andDepth.
59 PackedBoolean isolated;
60 // Index in andState that must be clear for this transition to be
62 unsigned requireClear;
63 // Index in andState that is to be set after performing this transition.
67 class SP_API FirstSet {
70 void init(LeafContentToken *);
71 void append(const FirstSet &);
73 LeafContentToken *token(size_t i) const;
74 size_t requiredIndex() const;
75 void setNotRequired();
77 Vector<LeafContentToken *> v_;
78 // index of contextually required token or -1 if none
79 size_t requiredIndex_;
82 class SP_API LastSet : public Vector<LeafContentToken *> {
85 LastSet(size_t n) : Vector<LeafContentToken *>(n) { }
86 void append(const LastSet &);
93 struct SP_API ContentModelAmbiguity {
94 ContentModelAmbiguity () { }
95 ~ContentModelAmbiguity () { }
96 const LeafContentToken *from;
97 const LeafContentToken *to1;
98 const LeafContentToken *to2;
104 class SP_API ContentToken {
106 enum OccurrenceIndicator { none = 0, opt = 01, plus = 02, rep = 03 };
107 ContentToken(OccurrenceIndicator);
108 virtual ~ContentToken();
109 OccurrenceIndicator occurrenceIndicator() const;
110 Boolean inherentlyOptional() const;
111 static unsigned andDepth(const AndModelGroup *);
112 static unsigned andIndex(const AndModelGroup *);
113 void analyze(GroupInfo &, const AndModelGroup *, unsigned,
114 FirstSet &, LastSet &);
115 static void addTransitions(const LastSet &from,
117 Boolean maybeRequired,
118 unsigned andClearIndex,
120 Boolean isolated = 0,
121 unsigned requireClear
122 = (unsigned)Transition::invalidIndex,
124 = (unsigned)Transition::invalidIndex);
125 virtual void finish(Vector<unsigned> &minAndDepth,
126 Vector<size_t> &elementTransition,
127 Vector<ContentModelAmbiguity> &,
128 Boolean &pcdataUnreachable) = 0;
129 virtual unsigned long grpgtcnt() const;
130 virtual void setOrGroupMember();
131 unsigned andGroupIndex() const;
132 virtual const ModelGroup *asModelGroup() const;
133 virtual const LeafContentToken *asLeafContentToken() const;
135 PackedBoolean inherentlyOptional_;
137 ContentToken(const ContentToken &); // undefined
138 void operator=(const ContentToken &); // undefined
139 virtual void analyze1(GroupInfo &, const AndModelGroup *, unsigned,
140 FirstSet &, LastSet &) = 0;
141 OccurrenceIndicator occurrenceIndicator_;
144 class SP_API ModelGroup : public ContentToken {
146 enum Connector { andConnector, orConnector, seqConnector };
147 ModelGroup(NCVector<Owner<ContentToken> > &, OccurrenceIndicator);
148 virtual Connector connector() const = 0;
149 unsigned nMembers() const;
150 void finish(Vector<unsigned> &minAndDepth,
151 Vector<size_t> &elementTransition,
152 Vector<ContentModelAmbiguity> &,
153 Boolean &pcdataUnreachable);
154 ContentToken &member(unsigned i);
155 const ContentToken &member(unsigned i) const;
156 unsigned long grpgtcnt() const;
157 const ModelGroup *asModelGroup() const;
161 ModelGroup(const ModelGroup &); // undefined
162 void operator=(const ModelGroup &); // undefined
163 NCVector<Owner<ContentToken> > members_;
166 class AndModelGroup : public ModelGroup {
168 AndModelGroup(NCVector<Owner<ContentToken> > &, OccurrenceIndicator);
169 Connector connector() const;
170 unsigned andDepth() const;
171 unsigned andIndex() const;
172 unsigned andGroupIndex() const;
173 const AndModelGroup *andAncestor() const;
175 AndModelGroup(const AndModelGroup &); // undefined
176 void operator=(const AndModelGroup &); // undefined
177 unsigned andDepth_; // number of and groups that contain this
179 unsigned andGroupIndex_;
180 const AndModelGroup *andAncestor_;
181 void analyze1(GroupInfo &, const AndModelGroup *, unsigned,
182 FirstSet &, LastSet &);
185 class OrModelGroup : public ModelGroup {
187 OrModelGroup(NCVector<Owner<ContentToken> > &, OccurrenceIndicator);
188 Connector connector() const;
190 OrModelGroup(const OrModelGroup &); // undefined
191 void operator=(const OrModelGroup &); // undefined
192 void analyze1(GroupInfo &, const AndModelGroup *, unsigned,
193 FirstSet &, LastSet &);
196 class SeqModelGroup : public ModelGroup {
198 SeqModelGroup(NCVector<Owner<ContentToken> > &, OccurrenceIndicator);
199 Connector connector() const;
201 SeqModelGroup(const SeqModelGroup &); // undefined
202 void operator=(const SeqModelGroup &); // undefined
203 void analyze1(GroupInfo &, const AndModelGroup *, unsigned,
204 FirstSet &, LastSet &);
209 class SP_API AndInfo {
211 AndInfo() : andAncestor(NULL), andGroupIndex(0) { }
212 const AndModelGroup *andAncestor;
213 unsigned andGroupIndex;
214 Vector<Transition> follow;
216 AndInfo(const AndInfo &); // undefined
217 void operator=(const AndInfo &); // undefined
220 // A LeafContentToken is not quite the same as a primitive content token.
221 // A data tag group is a primitive content token but not a LeafContentToken.
223 class SP_API LeafContentToken : public ContentToken {
225 LeafContentToken(const ElementType *, OccurrenceIndicator);
226 unsigned index() const;
227 unsigned typeIndex() const;
228 const ElementType *elementType() const;
229 virtual Boolean isInitial() const;
230 void addTransitions(const FirstSet &to,
231 Boolean maybeRequired,
232 unsigned andClearIndex,
235 unsigned requireClear,
238 void finish(Vector<unsigned> &minAndDepth,
239 Vector<size_t> &elementTransition,
240 Vector<ContentModelAmbiguity> &,
241 Boolean &pcdataUnreachable);
242 Boolean isFinal() const;
243 Boolean tryTransition(const ElementType *, AndState &,
244 unsigned &minAndDepth,
245 const LeafContentToken *&newpos) const;
246 Boolean tryTransitionPcdata(AndState &, unsigned &minAndDepth,
247 const LeafContentToken *&newpos) const;
248 void possibleTransitions(const AndState &, unsigned minAndDepth, Vector<const ElementType *> &) const;
249 const LeafContentToken *impliedStartTag(const AndState &andpos,
250 unsigned minAndDepth) const;
251 const LeafContentToken *transitionToken(const ElementType *to,
252 const AndState &andState,
253 unsigned minAndDepth) const;
254 void doRequiredTransition(AndState &andState,
255 unsigned &minAndDepth,
256 const LeafContentToken *&newpos) const;
257 unsigned computeMinAndDepth(const AndState&) const;
258 Boolean orGroupMember() const;
259 void setOrGroupMember();
260 const AndModelGroup *andAncestor() const;
261 unsigned andDepth() const;
262 const LeafContentToken *asLeafContentToken() const;
264 void analyze1(GroupInfo &, const AndModelGroup *, unsigned,
265 FirstSet &, LastSet &);
266 const ElementType *element_;
268 LeafContentToken(const LeafContentToken &); // undefined
269 void operator=(const LeafContentToken &); // undefined
270 void andFinish(Vector<unsigned> &minAndDepth,
271 Vector<size_t> &elementTransition,
272 Vector<ContentModelAmbiguity> &,
273 Boolean &pcdataUnreachable);
274 unsigned computeMinAndDepth1(const AndState&) const;
277 Vector<LeafContentToken *> follow_;
278 PackedBoolean isFinal_;
279 PackedBoolean orGroupMember_;
280 // 0 none, 1 yes - simple, 2 - compled
281 char pcdataTransitionType_;
282 const LeafContentToken *simplePcdataTransition_;
283 size_t requiredIndex_;
284 Owner<AndInfo> andInfo_;
287 class PcdataToken : public LeafContentToken {
290 void analyze1(GroupInfo &, const AndModelGroup *, unsigned,
291 FirstSet &, LastSet &);
293 PcdataToken(const PcdataToken &); // undefined
294 void operator=(const PcdataToken &); // undefined
297 class InitialPseudoToken : public LeafContentToken {
299 InitialPseudoToken();
300 Boolean isInitial() const;
302 InitialPseudoToken(const InitialPseudoToken &); // undefined
303 void operator=(const InitialPseudoToken &); // undefined
306 class ElementToken : public LeafContentToken {
308 ElementToken(const ElementType *, OccurrenceIndicator);
310 ElementToken(const ElementToken &); // undefined
311 void operator=(const ElementToken &); // undefined
314 class DataTagGroup : public SeqModelGroup {
316 // first content token is a DataTagElementToken, second is PcdataToken
317 DataTagGroup(NCVector<Owner<ContentToken> > &, OccurrenceIndicator);
319 DataTagGroup(const DataTagGroup &); // undefined
320 void operator=(const DataTagGroup &); // undefined
323 class DataTagElementToken : public ElementToken {
325 DataTagElementToken(const ElementType *, Vector<Text> &templates);
326 DataTagElementToken(const ElementType *, Vector<Text> &templates,
327 Text &paddingTemplate);
329 DataTagElementToken(const DataTagElementToken &); // undefined
330 void operator=(const DataTagElementToken &); // undefined
331 Vector<Text> templates_;
332 Boolean havePaddingTemplate_;
333 Text paddingTemplate_;
336 class SP_API CompiledModelGroup {
338 CompiledModelGroup(Owner<ModelGroup> &);
339 void compile(size_t nElementTypeIndex,
340 Vector<ContentModelAmbiguity> &,
341 Boolean &pcdataUnreachable);
342 CompiledModelGroup *copy() const;
343 const LeafContentToken *initial() const;
344 unsigned andStateSize() const;
345 Boolean containsPcdata() const;
346 const ModelGroup *modelGroup() const;
348 CompiledModelGroup(const CompiledModelGroup &); // undefined
349 void operator=(const CompiledModelGroup &); // undefined
350 Owner<ModelGroup> modelGroup_;
351 Owner<LeafContentToken> initial_;
352 unsigned andStateSize_;
353 Boolean containsPcdata_;
356 class SP_API AndState {
359 Boolean isClear(unsigned) const;
360 void clearFrom(unsigned);
362 Boolean operator==(const AndState &) const;
363 Boolean operator!=(const AndState &) const;
365 void clearFrom1(unsigned);
367 Vector<PackedBoolean> v_;
370 class SP_API MatchState {
373 MatchState(const CompiledModelGroup *); // may be 0
374 Boolean tryTransition(const ElementType *);
375 Boolean tryTransitionPcdata();
376 void possibleTransitions(Vector<const ElementType *> &) const;
377 Boolean isFinished() const;
378 const LeafContentToken *impliedStartTag() const;
379 const LeafContentToken *invalidExclusion(const ElementType *) const;
380 void doRequiredTransition();
381 const LeafContentToken *currentPosition() const;
382 Boolean operator==(const MatchState &) const;
383 Boolean operator!=(const MatchState &) const;
385 const LeafContentToken *pos_;
387 unsigned minAndDepth_;
391 ContentToken::OccurrenceIndicator ContentToken::occurrenceIndicator() const
393 return occurrenceIndicator_;
397 unsigned LeafContentToken::index() const
403 unsigned LeafContentToken::typeIndex() const
409 Boolean ContentToken::inherentlyOptional() const
411 return inherentlyOptional_;
415 const ElementType *LeafContentToken::elementType() const
421 unsigned AndModelGroup::andDepth() const
427 unsigned AndModelGroup::andIndex() const
433 unsigned ModelGroup::nMembers() const
435 return members_.size();
439 unsigned ContentToken::andDepth(const AndModelGroup *andAncestor)
441 return andAncestor ? andAncestor->andDepth() + 1 : 0;
445 unsigned ContentToken::andIndex(const AndModelGroup *andAncestor)
448 ? andAncestor->andIndex() + andAncestor->nMembers()
453 ContentToken &ModelGroup::member(unsigned i)
459 const ContentToken &ModelGroup::member(unsigned i) const
465 void LeafContentToken::setFinal()
471 Boolean LeafContentToken::isFinal() const
477 Boolean LeafContentToken::orGroupMember() const
479 return orGroupMember_;
483 unsigned CompiledModelGroup::andStateSize() const
485 return andStateSize_;
489 Boolean CompiledModelGroup::containsPcdata() const
491 return containsPcdata_;
495 const AndModelGroup *AndModelGroup::andAncestor() const
501 unsigned AndModelGroup::andGroupIndex() const
503 return andGroupIndex_;
507 const LeafContentToken *CompiledModelGroup::initial() const
509 return initial_.pointer();
513 const ModelGroup *CompiledModelGroup::modelGroup() const
515 return modelGroup_.pointer();
519 const AndModelGroup *LeafContentToken::andAncestor() const
521 return andInfo_ ? andInfo_->andAncestor : 0;
525 unsigned LeafContentToken::andDepth() const
527 return andInfo_ ? ContentToken::andDepth(andInfo_->andAncestor) : 0;
531 unsigned LeafContentToken::computeMinAndDepth(const AndState &andState) const
533 return andInfo_ ? computeMinAndDepth1(andState) : 0;
537 Boolean LeafContentToken::tryTransitionPcdata(AndState &andState,
538 unsigned &minAndDepth,
539 const LeafContentToken *&newpos)
542 if (pcdataTransitionType_ == 1) {
543 newpos = simplePcdataTransition_;
546 else if (pcdataTransitionType_ == 0)
549 return tryTransition(0, andState, minAndDepth, newpos);
553 Boolean MatchState::tryTransition(const ElementType *to)
555 return pos_->tryTransition(to, andState_, minAndDepth_, pos_);
559 Boolean MatchState::tryTransitionPcdata()
561 return pos_->tryTransitionPcdata(andState_, minAndDepth_, pos_);
565 void MatchState::possibleTransitions(Vector<const ElementType *> &v) const
567 pos_->possibleTransitions(andState_, minAndDepth_, v);
571 Boolean MatchState::isFinished() const
573 return pos_->isFinal() && minAndDepth_ == 0;
577 const LeafContentToken *
578 MatchState::impliedStartTag() const
580 return pos_->impliedStartTag(andState_, minAndDepth_);
584 void MatchState::doRequiredTransition()
586 pos_->doRequiredTransition(andState_, minAndDepth_, pos_);
590 const LeafContentToken *MatchState::currentPosition() const
596 Boolean MatchState::operator!=(const MatchState &state) const
598 return !(*this == state);
602 Boolean AndState::isClear(unsigned i) const
608 void AndState::set(unsigned i)
616 void AndState::clearFrom(unsigned i)
623 Boolean AndState::operator!=(const AndState &state) const
625 return !(*this == state);
630 size_t FirstSet::size() const
636 LeafContentToken *FirstSet::token(size_t i) const
642 size_t FirstSet::requiredIndex() const
644 return requiredIndex_;
648 void FirstSet::setNotRequired()
650 requiredIndex_ = size_t(-1);
657 #endif /* not ContentToken_INCLUDED */