⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 contenttoken.cxx

📁 SP是一个基于GNU C++编译器
💻 CXX
📖 第 1 页 / 共 2 页
字号:
// Copyright (c) 1994 James Clark// See the file COPYING for copying permission.#ifdef __GNUG__#pragma implementation#endif#include "splib.h"#include <stdlib.h>#include "ContentToken.h"#include "macros.h"#include "ElementType.h"#include "Vector.h"#include "Dtd.h"#include "MessageArg.h"#ifdef SP_NAMESPACEnamespace SP_NAMESPACE {#endifAndModelGroup::AndModelGroup(NCVector<Owner<ContentToken> > &v,			     ContentToken::OccurrenceIndicator oi): ModelGroup(v, oi){}ModelGroup::Connector AndModelGroup::connector() const{  return andConnector;}OrModelGroup::OrModelGroup(NCVector<Owner<ContentToken> > &v,			   ContentToken::OccurrenceIndicator oi): ModelGroup(v, oi){  setOrGroup();}ModelGroup::Connector OrModelGroup::connector() const{  return orConnector;}SeqModelGroup::SeqModelGroup(NCVector<Owner<ContentToken> > &v,			     ContentToken::OccurrenceIndicator oi): ModelGroup(v, oi){}ModelGroup::Connector SeqModelGroup::connector() const{  return seqConnector;}ModelGroup::ModelGroup(NCVector<Owner<ContentToken> > &v,		       OccurrenceIndicator oi): ContentToken(oi){  members_.swap(v);}unsigned long ModelGroup::grpgtcnt() const{  unsigned long cnt = 1;  for (size_t i = 0; i < members_.size(); i++)    cnt += members_[i]->grpgtcnt();  return cnt;}void ModelGroup::setOrGroup(){  for (size_t i = 0; i < members_.size(); i++)    members_[i]->setOrGroupMember();}const ModelGroup *ModelGroup::asModelGroup() const{  return this;}ElementToken::ElementToken(const ElementType *element, OccurrenceIndicator oi): LeafContentToken(element, oi){}ContentToken::ContentToken(OccurrenceIndicator oi): occurrenceIndicator_(oi){}unsigned long ContentToken::grpgtcnt() const{  return 1;}void ContentToken::setOrGroupMember(){}const ModelGroup *ContentToken::asModelGroup() const{  return 0;}const LeafContentToken *ContentToken::asLeafContentToken() const{  return 0;}LeafContentToken::LeafContentToken(const ElementType *element,				   OccurrenceIndicator oi): element_(element), ContentToken(oi), isFinal_(0), orGroupMember_(0),  requiredIndex_(size_t(-1)){}Boolean LeafContentToken::isInitial() const{  return 0;}void LeafContentToken::setOrGroupMember(){  orGroupMember_ = 1;}const LeafContentToken *LeafContentToken::asLeafContentToken() const{  return this;}PcdataToken::PcdataToken(): LeafContentToken(0, rep){}InitialPseudoToken::InitialPseudoToken(): LeafContentToken(0, none){}Boolean InitialPseudoToken::isInitial() const{  return 1;}DataTagGroup::DataTagGroup(NCVector<Owner<ContentToken> > &vec,			   OccurrenceIndicator oi): SeqModelGroup(vec, oi){}DataTagElementToken::DataTagElementToken(const ElementType *element,					 Vector<Text> &templates,					 Text &paddingTemplate): ElementToken(element, ContentToken::none),  havePaddingTemplate_(1){  templates.swap(templates_);  paddingTemplate.swap(paddingTemplate_);}DataTagElementToken::DataTagElementToken(const ElementType *element,					 Vector<Text> &templates): ElementToken(element, ContentToken::none),  havePaddingTemplate_(0){  templates.swap(templates_);}ContentToken::~ContentToken(){}struct GroupInfo {  unsigned nextLeafIndex;  PackedBoolean containsPcdata;  unsigned andStateSize;  Vector<unsigned> nextTypeIndex;  GroupInfo(size_t);};GroupInfo::GroupInfo(size_t nType): nextTypeIndex(nType, 0), nextLeafIndex(0), containsPcdata(0), andStateSize(0){}CompiledModelGroup::CompiledModelGroup(Owner<ModelGroup> &modelGroup): modelGroup_(modelGroup.extract()){}void CompiledModelGroup::compile(size_t nElementTypeIndex,				 Vector<ContentModelAmbiguity> &ambiguities,				 Boolean &pcdataUnreachable){  FirstSet first;  LastSet last;  GroupInfo info(nElementTypeIndex);  modelGroup_->analyze(info, 0, 0, first, last);  for (unsigned i = 0; i < last.size(); i++)    last[i]->setFinal();  andStateSize_ = info.andStateSize;  containsPcdata_ = info.containsPcdata;  initial_ = new InitialPseudoToken;  LastSet initialSet(1);  initialSet[0] = initial_.pointer();  ContentToken::addTransitions(initialSet, first, 1, 0, 0);  if (modelGroup_->inherentlyOptional())    initial_->setFinal();  pcdataUnreachable = 0;  Vector<unsigned> minAndDepth(info.nextLeafIndex);  Vector<size_t> elementTransition(nElementTypeIndex);  initial_->finish(minAndDepth, elementTransition, ambiguities,		   pcdataUnreachable);  modelGroup_->finish(minAndDepth, elementTransition, ambiguities,		      pcdataUnreachable);  if (!containsPcdata_)    pcdataUnreachable = 0;}void ModelGroup::finish(Vector<unsigned> &minAndDepth,			Vector<size_t> &elementTransition,			Vector<ContentModelAmbiguity> &ambiguities,			Boolean &pcdataUnreachable){  for (unsigned i = 0; i < nMembers(); i++)    member(i).finish(minAndDepth, elementTransition, ambiguities,		     pcdataUnreachable);}void LeafContentToken::finish(Vector<unsigned> &minAndDepthVec,			      Vector<size_t> &elementTransitionVec,			      Vector<ContentModelAmbiguity> &ambiguities,			      Boolean &pcdataUnreachable){  if (andInfo_) {    andFinish(minAndDepthVec, elementTransitionVec, ambiguities,	      pcdataUnreachable);    return;  }  Vector<size_t>::iterator elementTransition = elementTransitionVec.begin();  Vector<unsigned>::iterator minAndDepth = minAndDepthVec.begin();  minAndDepthVec.assign(minAndDepthVec.size(), unsigned(-1));  elementTransitionVec.assign(elementTransitionVec.size(), size_t(-1));  pcdataTransitionType_ = 0;  simplePcdataTransition_ = 0;  // follow_ is in decreasing order of andDepth because of how it's  // constructed.  size_t n = follow_.size();  Vector<LeafContentToken *>::iterator follow = follow_.begin();  size_t j = 0;  for (size_t i = 0; i < n; i++) {    unsigned &minDepth = minAndDepth[follow[i]->index()];    if (minDepth) {      minDepth = 0;      if (j != i)	follow[j] = follow[i];      if (i == requiredIndex_)	requiredIndex_ = j;      const ElementType *e = follow[i]->elementType();      unsigned ei;      if (e == 0) {	if (follow[i]->andInfo_ == 0) {	  simplePcdataTransition_ = follow[i];	  pcdataTransitionType_ = 1;	}	else	  pcdataTransitionType_ = 2;	ei = 0;      }      else	ei = e->index();      if (elementTransition[ei] != size_t(-1)) {	const LeafContentToken *prev = follow[elementTransition[ei]];	// This might not be true: consider (a & b?)*; after the	// a there are two different ways to get to the same b,	// with the same and depth.	if (follow[i] != prev) {	  ambiguities.resize(ambiguities.size() + 1);	  ContentModelAmbiguity &a = ambiguities.back();	  a.from = this;	  a.to1 = prev;	  a.to2 = follow[i];	  a.andDepth = 0;	}      }      elementTransition[ei] = j;      j++;    }  }  if (pcdataTransitionType_ == 0)    pcdataUnreachable = 1;  follow_.resize(j);}void LeafContentToken::andFinish(Vector<unsigned> &minAndDepthVec,				 Vector<size_t> &elementTransitionVec,				 Vector<ContentModelAmbiguity> &ambiguities,				 Boolean &pcdataUnreachable){  // Vector mapping element type index to index of leaf content token  // of that type to which there is a transition, which is the "worst"  // from the point of view of ambiguity.  Vector<size_t>::iterator elementTransition = elementTransitionVec.begin();  // Vector mapping index of leaf content token  // to minimum AND depth of transition to that token.  Vector<unsigned>::iterator minAndDepth = minAndDepthVec.begin();  minAndDepthVec.assign(minAndDepthVec.size(), unsigned(-1));  elementTransitionVec.assign(elementTransitionVec.size(), size_t(-1));  pcdataTransitionType_ = 0;  simplePcdataTransition_ = 0;  unsigned pcdataMinCovered = 0;    // follow_ is in decreasing order of andDepth because of how it's  // constructed.  size_t n = follow_.size();  size_t j = 0;  Vector<Transition>::iterator andFollow = andInfo_->follow.begin();  for (size_t i = 0; i < n; i++) {    unsigned &minDepth = minAndDepth[follow_[i]->index()];    // ignore transitions to the same token with the same and depth.    if (andFollow[i].andDepth < minDepth) {      minDepth = andFollow[i].andDepth;      if (j != i) {	follow_[j] = follow_[i];	andFollow[j] = andFollow[i];      }      if (i == requiredIndex_)	requiredIndex_ = j;      const ElementType *e = follow_[i]->elementType();      unsigned ei;      if (e == 0) {	if (pcdataTransitionType_ == 0) {	  const AndModelGroup *andAncestor = andInfo_->andAncestor;	  unsigned groupIndex = andInfo_->andGroupIndex;	  do {	    Boolean hasNonNull = 0;	    for (unsigned k = 0; k < andAncestor->nMembers(); k++)	      if (k != groupIndex		  && !andAncestor->member(k).inherentlyOptional()) {		hasNonNull = 1;		break;	      }	    if (hasNonNull) {	      if (minDepth <= andAncestor->andDepth())		pcdataUnreachable = 1;	      break;	    }	    groupIndex = andAncestor->andGroupIndex();	    andAncestor = andAncestor->andAncestor();	  } while (andAncestor);	  if (andFollow[i].isolated)	    pcdataMinCovered = minDepth;	  pcdataTransitionType_ = 2;	}	else {	  if (pcdataMinCovered > minDepth + 1)	    pcdataUnreachable = 1;	  pcdataMinCovered = andFollow[i].isolated ? minDepth : 0;	}	ei = 0;      }      else	ei = e->index();      // If we have transitions t1, t2, ... tN to tokens having      // the same element type, with      // and-depths d1, d2, ... dN, where d1 >= d2 >= ... >= dN,      // then there is an ambiguity unless      // d1 > d2 > ... > dN and t1, t2, ... , tN-1 are all isolated.      size_t previ = elementTransition[ei];      if (previ != size_t(-1)) {	const LeafContentToken *prev = follow_[previ];	// This might not be true: consider (a & b?)*; after the	// a there are two different ways to get to the same b,	// with the same and depth.	if (follow_[i] != prev	    && (andFollow[previ].andDepth == andFollow[i].andDepth		|| !andFollow[previ].isolated)) {	  ambiguities.resize(ambiguities.size() + 1);	  ContentModelAmbiguity &a = ambiguities.back();	  a.from = this;	  a.to1 = prev;	  a.to2 = follow_[i];	  a.andDepth = andFollow[i].andDepth;	}	if (andFollow[previ].isolated)	  elementTransition[ei] = j;      }      else	elementTransition[ei] = j;      j++;    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -