ContentToken.C 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  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)
  10. * any later version.
  11. *
  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
  16. * details.
  17. *
  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
  22. */
  23. /* $XConsortium: ContentToken.C /main/2 1996/08/13 13:59:08 drk $ */
  24. // Copyright (c) 1994 James Clark
  25. // See the file COPYING for copying permission.
  26. #ifdef __GNUG__
  27. #pragma implementation
  28. #endif
  29. #include "splib.h"
  30. #include <stdlib.h>
  31. #include "ContentToken.h"
  32. #include "macros.h"
  33. #include "ElementType.h"
  34. #include "Vector.h"
  35. #include "Dtd.h"
  36. #include "MessageArg.h"
  37. #ifdef SP_NAMESPACE
  38. namespace SP_NAMESPACE {
  39. #endif
  40. AndModelGroup::AndModelGroup(NCVector<Owner<ContentToken> > &v,
  41. ContentToken::OccurrenceIndicator oi)
  42. : ModelGroup(v, oi), andDepth_(0), andIndex_(0), andGroupIndex_(0),
  43. andAncestor_(NULL)
  44. {
  45. }
  46. ModelGroup::Connector AndModelGroup::connector() const
  47. {
  48. return andConnector;
  49. }
  50. OrModelGroup::OrModelGroup(NCVector<Owner<ContentToken> > &v,
  51. ContentToken::OccurrenceIndicator oi)
  52. : ModelGroup(v, oi)
  53. {
  54. setOrGroup();
  55. }
  56. ModelGroup::Connector OrModelGroup::connector() const
  57. {
  58. return orConnector;
  59. }
  60. SeqModelGroup::SeqModelGroup(NCVector<Owner<ContentToken> > &v,
  61. ContentToken::OccurrenceIndicator oi)
  62. : ModelGroup(v, oi)
  63. {
  64. }
  65. ModelGroup::Connector SeqModelGroup::connector() const
  66. {
  67. return seqConnector;
  68. }
  69. ModelGroup::ModelGroup(NCVector<Owner<ContentToken> > &v,
  70. OccurrenceIndicator oi)
  71. : ContentToken(oi)
  72. {
  73. members_.swap(v);
  74. }
  75. unsigned long ModelGroup::grpgtcnt() const
  76. {
  77. unsigned long cnt = 1;
  78. for (size_t i = 0; i < members_.size(); i++)
  79. cnt += members_[i]->grpgtcnt();
  80. return cnt;
  81. }
  82. void ModelGroup::setOrGroup()
  83. {
  84. for (size_t i = 0; i < members_.size(); i++)
  85. members_[i]->setOrGroupMember();
  86. }
  87. const ModelGroup *ModelGroup::asModelGroup() const
  88. {
  89. return this;
  90. }
  91. ElementToken::ElementToken(const ElementType *element, OccurrenceIndicator oi)
  92. : LeafContentToken(element, oi)
  93. {
  94. }
  95. ContentToken::ContentToken(OccurrenceIndicator oi)
  96. : occurrenceIndicator_(oi),
  97. inherentlyOptional_(0)
  98. {
  99. }
  100. unsigned long ContentToken::grpgtcnt() const
  101. {
  102. return 1;
  103. }
  104. void ContentToken::setOrGroupMember()
  105. {
  106. }
  107. const ModelGroup *ContentToken::asModelGroup() const
  108. {
  109. return 0;
  110. }
  111. const LeafContentToken *ContentToken::asLeafContentToken() const
  112. {
  113. return 0;
  114. }
  115. LeafContentToken::LeafContentToken(const ElementType *element,
  116. OccurrenceIndicator oi)
  117. : element_(element), ContentToken(oi), isFinal_(0), orGroupMember_(0),
  118. requiredIndex_(size_t(-1)), leafIndex_(0), typeIndex_(0), pcdataTransitionType_(0),
  119. simplePcdataTransition_(NULL)
  120. {
  121. }
  122. Boolean LeafContentToken::isInitial() const
  123. {
  124. return 0;
  125. }
  126. void LeafContentToken::setOrGroupMember()
  127. {
  128. orGroupMember_ = 1;
  129. }
  130. const LeafContentToken *LeafContentToken::asLeafContentToken() const
  131. {
  132. return this;
  133. }
  134. PcdataToken::PcdataToken()
  135. : LeafContentToken(0, rep)
  136. {
  137. }
  138. InitialPseudoToken::InitialPseudoToken()
  139. : LeafContentToken(0, none)
  140. {
  141. }
  142. Boolean InitialPseudoToken::isInitial() const
  143. {
  144. return 1;
  145. }
  146. DataTagGroup::DataTagGroup(NCVector<Owner<ContentToken> > &vec,
  147. OccurrenceIndicator oi)
  148. : SeqModelGroup(vec, oi)
  149. {
  150. }
  151. DataTagElementToken::DataTagElementToken(const ElementType *element,
  152. Vector<Text> &templates,
  153. Text &paddingTemplate)
  154. : ElementToken(element, ContentToken::none),
  155. havePaddingTemplate_(1)
  156. {
  157. templates.swap(templates_);
  158. paddingTemplate.swap(paddingTemplate_);
  159. }
  160. DataTagElementToken::DataTagElementToken(const ElementType *element,
  161. Vector<Text> &templates)
  162. : ElementToken(element, ContentToken::none),
  163. havePaddingTemplate_(0)
  164. {
  165. templates.swap(templates_);
  166. }
  167. ContentToken::~ContentToken()
  168. {
  169. }
  170. struct GroupInfo {
  171. unsigned nextLeafIndex;
  172. PackedBoolean containsPcdata;
  173. unsigned andStateSize;
  174. Vector<unsigned> nextTypeIndex;
  175. GroupInfo(size_t);
  176. };
  177. GroupInfo::GroupInfo(size_t nType)
  178. : nextTypeIndex(nType, 0), nextLeafIndex(0), containsPcdata(0), andStateSize(0)
  179. {
  180. }
  181. CompiledModelGroup::CompiledModelGroup(Owner<ModelGroup> &modelGroup)
  182. : modelGroup_(modelGroup.extract()), andStateSize_(0), containsPcdata_(false)
  183. {
  184. }
  185. void CompiledModelGroup::compile(size_t nElementTypeIndex,
  186. Vector<ContentModelAmbiguity> &ambiguities,
  187. Boolean &pcdataUnreachable)
  188. {
  189. FirstSet first;
  190. LastSet last;
  191. GroupInfo info(nElementTypeIndex);
  192. modelGroup_->analyze(info, 0, 0, first, last);
  193. for (unsigned i = 0; i < last.size(); i++)
  194. last[i]->setFinal();
  195. andStateSize_ = info.andStateSize;
  196. containsPcdata_ = info.containsPcdata;
  197. initial_ = new InitialPseudoToken;
  198. LastSet initialSet(1);
  199. initialSet[0] = initial_.pointer();
  200. ContentToken::addTransitions(initialSet, first, 1, 0, 0);
  201. if (modelGroup_->inherentlyOptional())
  202. initial_->setFinal();
  203. pcdataUnreachable = 0;
  204. Vector<unsigned> minAndDepth(info.nextLeafIndex);
  205. Vector<size_t> elementTransition(nElementTypeIndex);
  206. initial_->finish(minAndDepth, elementTransition, ambiguities,
  207. pcdataUnreachable);
  208. modelGroup_->finish(minAndDepth, elementTransition, ambiguities,
  209. pcdataUnreachable);
  210. if (!containsPcdata_)
  211. pcdataUnreachable = 0;
  212. }
  213. void ModelGroup::finish(Vector<unsigned> &minAndDepth,
  214. Vector<size_t> &elementTransition,
  215. Vector<ContentModelAmbiguity> &ambiguities,
  216. Boolean &pcdataUnreachable)
  217. {
  218. for (unsigned i = 0; i < nMembers(); i++)
  219. member(i).finish(minAndDepth, elementTransition, ambiguities,
  220. pcdataUnreachable);
  221. }
  222. void LeafContentToken::finish(Vector<unsigned> &minAndDepthVec,
  223. Vector<size_t> &elementTransitionVec,
  224. Vector<ContentModelAmbiguity> &ambiguities,
  225. Boolean &pcdataUnreachable)
  226. {
  227. if (andInfo_) {
  228. andFinish(minAndDepthVec, elementTransitionVec, ambiguities,
  229. pcdataUnreachable);
  230. return;
  231. }
  232. Vector<size_t>::iterator elementTransition = elementTransitionVec.begin();
  233. Vector<unsigned>::iterator minAndDepth = minAndDepthVec.begin();
  234. minAndDepthVec.assign(minAndDepthVec.size(), unsigned(-1));
  235. elementTransitionVec.assign(elementTransitionVec.size(), size_t(-1));
  236. pcdataTransitionType_ = 0;
  237. simplePcdataTransition_ = 0;
  238. // follow_ is in decreasing order of andDepth because of how it's
  239. // constructed.
  240. size_t n = follow_.size();
  241. Vector<LeafContentToken *>::iterator follow = follow_.begin();
  242. size_t j = 0;
  243. for (size_t i = 0; i < n; i++) {
  244. unsigned &minDepth = minAndDepth[follow[i]->index()];
  245. if (minDepth) {
  246. minDepth = 0;
  247. if (j != i)
  248. follow[j] = follow[i];
  249. if (i == requiredIndex_)
  250. requiredIndex_ = j;
  251. const ElementType *e = follow[i]->elementType();
  252. unsigned ei;
  253. if (e == 0) {
  254. if (!follow[i]->andInfo_) {
  255. simplePcdataTransition_ = follow[i];
  256. pcdataTransitionType_ = 1;
  257. }
  258. else
  259. pcdataTransitionType_ = 2;
  260. ei = 0;
  261. }
  262. else
  263. ei = e->index();
  264. if (elementTransition[ei] != size_t(-1)) {
  265. const LeafContentToken *prev = follow[elementTransition[ei]];
  266. // This might not be true: consider (a & b?)*; after the
  267. // a there are two different ways to get to the same b,
  268. // with the same and depth.
  269. if (follow[i] != prev) {
  270. ambiguities.resize(ambiguities.size() + 1);
  271. ContentModelAmbiguity &a = ambiguities.back();
  272. a.from = this;
  273. a.to1 = prev;
  274. a.to2 = follow[i];
  275. a.andDepth = 0;
  276. }
  277. }
  278. elementTransition[ei] = j;
  279. j++;
  280. }
  281. }
  282. if (pcdataTransitionType_ == 0)
  283. pcdataUnreachable = 1;
  284. follow_.resize(j);
  285. }
  286. void LeafContentToken::andFinish(Vector<unsigned> &minAndDepthVec,
  287. Vector<size_t> &elementTransitionVec,
  288. Vector<ContentModelAmbiguity> &ambiguities,
  289. Boolean &pcdataUnreachable)
  290. {
  291. // Vector mapping element type index to index of leaf content token
  292. // of that type to which there is a transition, which is the "worst"
  293. // from the point of view of ambiguity.
  294. Vector<size_t>::iterator elementTransition = elementTransitionVec.begin();
  295. // Vector mapping index of leaf content token
  296. // to minimum AND depth of transition to that token.
  297. Vector<unsigned>::iterator minAndDepth = minAndDepthVec.begin();
  298. minAndDepthVec.assign(minAndDepthVec.size(), unsigned(-1));
  299. elementTransitionVec.assign(elementTransitionVec.size(), size_t(-1));
  300. pcdataTransitionType_ = 0;
  301. simplePcdataTransition_ = 0;
  302. unsigned pcdataMinCovered = 0;
  303. // follow_ is in decreasing order of andDepth because of how it's
  304. // constructed.
  305. size_t n = follow_.size();
  306. size_t j = 0;
  307. Vector<Transition>::iterator andFollow = andInfo_->follow.begin();
  308. for (size_t i = 0; i < n; i++) {
  309. unsigned &minDepth = minAndDepth[follow_[i]->index()];
  310. // ignore transitions to the same token with the same and depth.
  311. if (andFollow[i].andDepth < minDepth) {
  312. minDepth = andFollow[i].andDepth;
  313. if (j != i) {
  314. follow_[j] = follow_[i];
  315. andFollow[j] = andFollow[i];
  316. }
  317. if (i == requiredIndex_)
  318. requiredIndex_ = j;
  319. const ElementType *e = follow_[i]->elementType();
  320. unsigned ei;
  321. if (e == 0) {
  322. if (pcdataTransitionType_ == 0) {
  323. const AndModelGroup *andAncestor = andInfo_->andAncestor;
  324. unsigned groupIndex = andInfo_->andGroupIndex;
  325. do {
  326. Boolean hasNonNull = 0;
  327. for (unsigned k = 0; k < andAncestor->nMembers(); k++)
  328. if (k != groupIndex
  329. && !andAncestor->member(k).inherentlyOptional()) {
  330. hasNonNull = 1;
  331. break;
  332. }
  333. if (hasNonNull) {
  334. if (minDepth <= andAncestor->andDepth())
  335. pcdataUnreachable = 1;
  336. break;
  337. }
  338. groupIndex = andAncestor->andGroupIndex();
  339. andAncestor = andAncestor->andAncestor();
  340. } while (andAncestor);
  341. if (andFollow[i].isolated)
  342. pcdataMinCovered = minDepth;
  343. pcdataTransitionType_ = 2;
  344. }
  345. else {
  346. if (pcdataMinCovered > minDepth + 1)
  347. pcdataUnreachable = 1;
  348. pcdataMinCovered = andFollow[i].isolated ? minDepth : 0;
  349. }
  350. ei = 0;
  351. }
  352. else
  353. ei = e->index();
  354. // If we have transitions t1, t2, ... tN to tokens having
  355. // the same element type, with
  356. // and-depths d1, d2, ... dN, where d1 >= d2 >= ... >= dN,
  357. // then there is an ambiguity unless
  358. // d1 > d2 > ... > dN and t1, t2, ... , tN-1 are all isolated.
  359. size_t previ = elementTransition[ei];
  360. if (previ != size_t(-1)) {
  361. const LeafContentToken *prev = follow_[previ];
  362. // This might not be true: consider (a & b?)*; after the
  363. // a there are two different ways to get to the same b,
  364. // with the same and depth.
  365. if (follow_[i] != prev
  366. && (andFollow[previ].andDepth == andFollow[i].andDepth
  367. || !andFollow[previ].isolated)) {
  368. ambiguities.resize(ambiguities.size() + 1);
  369. ContentModelAmbiguity &a = ambiguities.back();
  370. a.from = this;
  371. a.to1 = prev;
  372. a.to2 = follow_[i];
  373. a.andDepth = andFollow[i].andDepth;
  374. }
  375. if (andFollow[previ].isolated)
  376. elementTransition[ei] = j;
  377. }
  378. else
  379. elementTransition[ei] = j;
  380. j++;
  381. }
  382. }
  383. if (pcdataMinCovered > 0 || pcdataTransitionType_ == 0)
  384. pcdataUnreachable = 1;
  385. follow_.resize(j);
  386. andInfo_->follow.resize(j);
  387. }
  388. void ContentToken::analyze(GroupInfo &info,
  389. const AndModelGroup *andAncestor,
  390. unsigned andGroupIndex,
  391. FirstSet &first,
  392. LastSet &last)
  393. {
  394. analyze1(info, andAncestor, andGroupIndex, first, last);
  395. if (occurrenceIndicator_ & opt)
  396. inherentlyOptional_ = 1;
  397. if (inherentlyOptional_)
  398. first.setNotRequired();
  399. if (occurrenceIndicator_ & plus)
  400. addTransitions(last, first, 0,
  401. andIndex(andAncestor), andDepth(andAncestor));
  402. }
  403. void LeafContentToken::analyze1(GroupInfo &info,
  404. const AndModelGroup *andAncestor,
  405. unsigned andGroupIndex,
  406. FirstSet &first,
  407. LastSet &last)
  408. {
  409. leafIndex_ = info.nextLeafIndex++;
  410. typeIndex_ = info.nextTypeIndex[element_ ? element_->index() : 0]++;
  411. if (andAncestor) {
  412. andInfo_ = new AndInfo;
  413. andInfo_->andAncestor = andAncestor;
  414. andInfo_->andGroupIndex = andGroupIndex;
  415. }
  416. first.init(this);
  417. last.assign(1, this);
  418. inherentlyOptional_ = 0;
  419. }
  420. void PcdataToken::analyze1(GroupInfo &info,
  421. const AndModelGroup *andAncestor,
  422. unsigned andGroupIndex,
  423. FirstSet &first,
  424. LastSet &last)
  425. {
  426. info.containsPcdata = 1;
  427. LeafContentToken::analyze1(info, andAncestor, andGroupIndex, first, last);
  428. }
  429. void OrModelGroup::analyze1(GroupInfo &info,
  430. const AndModelGroup *andAncestor,
  431. unsigned andGroupIndex,
  432. FirstSet &first,
  433. LastSet &last)
  434. {
  435. member(0).analyze(info, andAncestor, andGroupIndex, first, last);
  436. first.setNotRequired();
  437. inherentlyOptional_ = member(0).inherentlyOptional();
  438. for (unsigned i = 1; i < nMembers(); i++) {
  439. FirstSet tempFirst;
  440. LastSet tempLast;
  441. member(i).analyze(info, andAncestor, andGroupIndex, tempFirst, tempLast);
  442. first.append(tempFirst);
  443. first.setNotRequired();
  444. last.append(tempLast);
  445. inherentlyOptional_ |= member(i).inherentlyOptional();
  446. }
  447. }
  448. void SeqModelGroup::analyze1(GroupInfo &info,
  449. const AndModelGroup *andAncestor,
  450. unsigned andGroupIndex,
  451. FirstSet &first,
  452. LastSet &last)
  453. {
  454. member(0).analyze(info, andAncestor, andGroupIndex, first, last);
  455. inherentlyOptional_ = member(0).inherentlyOptional();
  456. for (unsigned i = 1; i < nMembers(); i++) {
  457. FirstSet tempFirst;
  458. LastSet tempLast;
  459. member(i).analyze(info, andAncestor, andGroupIndex, tempFirst, tempLast);
  460. addTransitions(last, tempFirst, 1,
  461. andIndex(andAncestor), andDepth(andAncestor));
  462. if (inherentlyOptional_)
  463. first.append(tempFirst);
  464. if (member(i).inherentlyOptional())
  465. last.append(tempLast);
  466. else
  467. tempLast.swap(last);
  468. inherentlyOptional_ &= member(i).inherentlyOptional();
  469. }
  470. }
  471. void AndModelGroup::analyze1(GroupInfo &info,
  472. const AndModelGroup *andAncestor,
  473. unsigned andGroupIndex,
  474. FirstSet &first,
  475. LastSet &last)
  476. {
  477. andDepth_ = ContentToken::andDepth(andAncestor);
  478. andIndex_ = ContentToken::andIndex(andAncestor);
  479. andAncestor_ = andAncestor;
  480. andGroupIndex_ = andGroupIndex;
  481. if (andIndex_ + nMembers() > info.andStateSize)
  482. info.andStateSize = andIndex_ + nMembers();
  483. Vector<FirstSet> firstVec(nMembers());
  484. Vector<LastSet> lastVec(nMembers());
  485. member(0).analyze(info, this, 0, firstVec[0], lastVec[0]);
  486. first = firstVec[0];
  487. first.setNotRequired();
  488. last = lastVec[0];
  489. inherentlyOptional_ = member(0).inherentlyOptional();
  490. unsigned i;
  491. for (i = 1; i < nMembers(); i++) {
  492. member(i).analyze(info, this, i, firstVec[i], lastVec[i]);
  493. first.append(firstVec[i]);
  494. first.setNotRequired();
  495. last.append(lastVec[i]);
  496. inherentlyOptional_ &= member(i).inherentlyOptional();
  497. }
  498. for (i = 0; i < nMembers(); i++) {
  499. for (unsigned j = 0; j < nMembers(); j++)
  500. if (j != i)
  501. addTransitions(lastVec[i], firstVec[j], 0,
  502. andIndex() + nMembers(),
  503. andDepth() + 1,
  504. !member(j).inherentlyOptional(),
  505. andIndex() + j, andIndex() + i);
  506. }
  507. }
  508. void ContentToken::addTransitions(const LastSet &from,
  509. const FirstSet &to,
  510. Boolean maybeRequired,
  511. unsigned andClearIndex,
  512. unsigned andDepth,
  513. Boolean isolated,
  514. unsigned requireClear,
  515. unsigned toSet)
  516. {
  517. size_t length = from.size();
  518. for (unsigned i = 0; i < length; i++)
  519. from[i]->addTransitions(to,
  520. maybeRequired,
  521. andClearIndex,
  522. andDepth,
  523. isolated,
  524. requireClear,
  525. toSet);
  526. }
  527. void LeafContentToken::addTransitions(const FirstSet &to,
  528. Boolean maybeRequired,
  529. unsigned andClearIndex,
  530. unsigned andDepth,
  531. Boolean isolated,
  532. unsigned requireClear,
  533. unsigned toSet)
  534. {
  535. if (maybeRequired && to.requiredIndex() != size_t(-1)) {
  536. ASSERT(requiredIndex_ == size_t(-1));
  537. requiredIndex_ = to.requiredIndex() + follow_.size();
  538. }
  539. size_t length = follow_.size();
  540. size_t n = to.size();
  541. follow_.resize(length + n);
  542. for (size_t i = 0; i < n; i++)
  543. follow_[length + i] = to.token(i);
  544. if (andInfo_) {
  545. andInfo_->follow.resize(length + n);
  546. for (size_t i = 0; i < n; i++) {
  547. Transition &t = andInfo_->follow[length + i];
  548. t.clearAndStateStartIndex = andClearIndex;
  549. t.andDepth = andDepth;
  550. t.isolated = isolated;
  551. t.requireClear = requireClear;
  552. t.toSet = toSet;
  553. }
  554. }
  555. }
  556. AndState::AndState(unsigned n)
  557. : v_(n, PackedBoolean(0)), clearFrom_(0)
  558. {
  559. }
  560. void AndState::clearFrom1(unsigned i)
  561. {
  562. while (clearFrom_ > i)
  563. v_[--clearFrom_] = 0;
  564. }
  565. MatchState::MatchState()
  566. : andState_(0), pos_(NULL), minAndDepth_(0)
  567. {
  568. }
  569. MatchState::MatchState(const CompiledModelGroup *model)
  570. : pos_(model ? model->initial() : 0),
  571. andState_(model ? model->andStateSize() : 0),
  572. minAndDepth_(0)
  573. {
  574. }
  575. const LeafContentToken *MatchState::invalidExclusion(const ElementType *e)
  576. const
  577. {
  578. const LeafContentToken *token = pos_->transitionToken(e, andState_,
  579. minAndDepth_);
  580. if (token && !token->inherentlyOptional() && !token->orGroupMember())
  581. return token;
  582. else
  583. return 0;
  584. }
  585. Boolean MatchState::operator==(const MatchState &state) const
  586. {
  587. return (pos_ == state.pos_ && andState_ == state.andState_
  588. && minAndDepth_ == state.minAndDepth_);
  589. }
  590. Boolean AndState::operator==(const AndState &state) const
  591. {
  592. ASSERT(v_.size() == state.v_.size());
  593. for (size_t i = 0; i < v_.size(); i++) {
  594. if (i >= clearFrom_ && i >= state.clearFrom_)
  595. break;
  596. if (v_[i] != state.v_[i])
  597. return 0;
  598. }
  599. return 1;
  600. }
  601. const LeafContentToken *
  602. LeafContentToken::transitionToken(const ElementType *to,
  603. const AndState &andState,
  604. unsigned minAndDepth) const
  605. {
  606. Vector<LeafContentToken *>::const_iterator p = follow_.begin();
  607. if (!andInfo_) {
  608. for (size_t n = follow_.size(); n > 0; n--, p++)
  609. if ((*p)->elementType() == to)
  610. return *p;
  611. }
  612. else {
  613. Vector<Transition>::const_iterator q = andInfo_->follow.begin();
  614. for (size_t n = follow_.size(); n > 0; n--, p++, q++)
  615. if ((*p)->elementType() == to
  616. && ((q->requireClear == unsigned(Transition::invalidIndex)
  617. || andState.isClear(q->requireClear))
  618. && q->andDepth >= minAndDepth))
  619. return (*p);
  620. }
  621. return 0;
  622. }
  623. Boolean
  624. LeafContentToken::tryTransition(const ElementType *to,
  625. AndState &andState,
  626. unsigned &minAndDepth,
  627. const LeafContentToken *&newpos) const
  628. {
  629. Vector<LeafContentToken *>::const_iterator p = follow_.begin();
  630. if (!andInfo_) {
  631. for (size_t n = follow_.size(); n > 0; n--, p++) {
  632. if ((*p)->elementType() == to) {
  633. newpos = *p;
  634. minAndDepth = newpos->computeMinAndDepth(andState);
  635. return 1;
  636. }
  637. }
  638. }
  639. else {
  640. Vector<Transition>::const_iterator q = andInfo_->follow.begin();
  641. for (size_t n = follow_.size(); n > 0; n--, p++, q++) {
  642. if ((*p)->elementType() == to
  643. && ((q->requireClear == unsigned(Transition::invalidIndex)
  644. || andState.isClear(q->requireClear))
  645. && q->andDepth >= minAndDepth)) {
  646. if (q->toSet != unsigned(Transition::invalidIndex))
  647. andState.set(q->toSet);
  648. andState.clearFrom(q->clearAndStateStartIndex);
  649. newpos = *p;
  650. minAndDepth = newpos->computeMinAndDepth(andState);
  651. return 1;
  652. }
  653. }
  654. }
  655. return 0;
  656. }
  657. void
  658. LeafContentToken::possibleTransitions(const AndState &andState,
  659. unsigned minAndDepth,
  660. Vector<const ElementType *> &v) const
  661. {
  662. Vector<LeafContentToken *>::const_iterator p = follow_.begin();
  663. if (!andInfo_) {
  664. for (size_t n = follow_.size(); n > 0; n--, p++)
  665. v.push_back((*p)->elementType());
  666. }
  667. else {
  668. Vector<Transition>::const_iterator q = andInfo_->follow.begin();
  669. for (size_t n = follow_.size(); n > 0; n--, p++, q++)
  670. if ((q->requireClear == unsigned(Transition::invalidIndex)
  671. || andState.isClear(q->requireClear))
  672. && q->andDepth >= minAndDepth)
  673. v.push_back((*p)->elementType());
  674. }
  675. }
  676. unsigned LeafContentToken::computeMinAndDepth1(const AndState &andState) const
  677. {
  678. ASSERT(andInfo_);
  679. unsigned groupIndex = andInfo_->andGroupIndex;
  680. for (const AndModelGroup *group = andInfo_->andAncestor;
  681. group;
  682. groupIndex = group->andGroupIndex(), group = group->andAncestor())
  683. for (unsigned i = 0; i < group->nMembers(); i++)
  684. if (i != groupIndex && !group->member(i).inherentlyOptional()
  685. && andState.isClear(group->andIndex() + i))
  686. return group->andDepth() + 1;
  687. return 0;
  688. }
  689. const LeafContentToken *
  690. LeafContentToken::impliedStartTag(const AndState &andState,
  691. unsigned minAndDepth) const
  692. {
  693. if (requiredIndex_ != size_t(-1)) {
  694. if (!andInfo_)
  695. return follow_[requiredIndex_];
  696. const Transition &t = andInfo_->follow[requiredIndex_];
  697. if ((t.requireClear == unsigned(Transition::invalidIndex)
  698. || andState.isClear(t.requireClear))
  699. && t.andDepth >= minAndDepth)
  700. return follow_[requiredIndex_];
  701. }
  702. return 0;
  703. }
  704. void LeafContentToken::doRequiredTransition(AndState &andState,
  705. unsigned &minAndDepth,
  706. const LeafContentToken *&newpos)
  707. const
  708. {
  709. ASSERT(requiredIndex_ != size_t(-1));
  710. if (andInfo_) {
  711. const Transition &t = andInfo_->follow[requiredIndex_];
  712. if (t.toSet != unsigned(Transition::invalidIndex))
  713. andState.set(t.toSet);
  714. andState.clearFrom(t.clearAndStateStartIndex);
  715. }
  716. newpos = follow_[requiredIndex_];
  717. minAndDepth = newpos->computeMinAndDepth(andState);
  718. }
  719. FirstSet::FirstSet()
  720. : requiredIndex_(size_t(-1))
  721. {
  722. }
  723. void FirstSet::init(LeafContentToken *p)
  724. {
  725. v_.assign(1, p);
  726. v_.reserve(256);
  727. requiredIndex_ = 0;
  728. }
  729. void FirstSet::append(const FirstSet &set)
  730. {
  731. if (set.requiredIndex_ != size_t(-1)) {
  732. ASSERT(requiredIndex_ == size_t(-1));
  733. requiredIndex_ = set.requiredIndex_ + v_.size();
  734. }
  735. size_t oldSize = v_.size();
  736. v_.resize(v_.size() + set.v_.size());
  737. for (size_t i = 0; i < set.v_.size(); i++)
  738. v_[oldSize + i] = set.v_[i];
  739. }
  740. void LastSet::append(const LastSet &set)
  741. {
  742. size_t oldSize = size();
  743. resize(size() + set.size());
  744. for (size_t i = 0; i < set.size(); i++)
  745. (*this)[oldSize + i] = set[i];
  746. }
  747. #ifdef SP_NAMESPACE
  748. }
  749. #endif