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

📄 parseinstance.cxx

📁 SP是一个基于GNU C++编译器
💻 CXX
📖 第 1 页 / 共 3 页
字号:
// Copyright (c) 1994 James Clark// See the file COPYING for copying permission.#include "splib.h"#include "Parser.h"#include "ParserMessages.h"#include "MessageArg.h"#include "TokenMessageArg.h"#include "StringVectorMessageArg.h"#include "token.h"#include "macros.h"#ifdef SP_NAMESPACEnamespace SP_NAMESPACE {#endifvoid Parser::doInstanceStart(){  if (cancelled()) {    allDone();    return;  }  // FIXME check here that we have a valid dtd  compileInstanceModes();  setPhase(contentPhase);  Token token = getToken(currentMode());  switch (token) {  case tokenEe:  case tokenStagoNameStart:  case tokenStagoTagc:  case tokenStagoGrpo:  case tokenEtagoNameStart:  case tokenEtagoTagc:  case tokenEtagoGrpo:    break;  default:    if (sd().omittag()) {      unsigned startImpliedCount = 0;      unsigned attributeListIndex = 0;      IList<Undo> undoList;      IList<Event> eventList;      if (!tryImplyTag(currentLocation(),		       startImpliedCount,		       attributeListIndex,		       undoList,		       eventList))	CANNOT_HAPPEN();      queueElementEvents(eventList);    }    else      message(ParserMessages::instanceStartOmittag);  }  currentInput()->ungetToken();}void Parser::endInstance(){  // Do checking before popping entity stack so that there's a  // current location for error messages.  endAllElements();  while (markedSectionLevel() > 0) {    message(ParserMessages::unclosedMarkedSection,	    currentMarkedSectionStartLocation());    endMarkedSection();  }  checkIdrefs();  popInputStack();  allDone();}void Parser::checkIdrefs(){  IdTableIter iter(idTableIter());  Id *id;  while ((id = iter.next()) != 0) {    for (size_t i = 0; i < id->pendingRefs().size(); i++) {      Messenger::setNextLocation(id->pendingRefs()[i]);      message(ParserMessages::missingId, StringMessageArg(id->name()));    }  }}void Parser::doContent(){  do {    if (cancelled()) {      allDone();      return;    }    Token token = getToken(currentMode());    switch (token) {    case tokenEe:      if (inputLevel() == 1) {	endInstance();	return;      }      if (inputLevel() == specialParseInputLevel()) {	// FIXME have separate messages for each type of special parse	// perhaps force end of marked section or element	message(ParserMessages::specialParseEntityEnd);      }      if (eventsWanted().wantInstanceMarkup())	eventHandler().entityEnd(new (eventAllocator())				 EntityEndEvent(currentLocation()));      if (afterDocumentElement())	message(ParserMessages::afterDocumentElementEntityEnd);      if (sd().integrallyStored()	  && tagLevel()	  && currentElement().index() != currentInputElementIndex())	message(ParserMessages::contentAsyncEntityRef);      popInputStack();      break;    case tokenCroDigit:    case tokenHcroHexDigit:      {	if (afterDocumentElement())	  message(ParserMessages::characterReferenceAfterDocumentElement);	Char ch;	Location loc;	if (parseNumericCharRef(token == tokenHcroHexDigit, ch, loc)) {	  acceptPcdata(loc);	  noteData();	  Boolean isSgmlChar;	  if (!translateNumericCharRef(ch, isSgmlChar))	    break;	  if (!isSgmlChar) {	    eventHandler().nonSgmlChar(new (eventAllocator())	                               NonSgmlCharEvent(ch, loc));	    break;	  }	  eventHandler().data(new (eventAllocator())			      ImmediateDataEvent(Event::characterData,						 &ch, 1, loc, 1));	  break;	}      }      break;    case tokenCroNameStart:      if (afterDocumentElement())	message(ParserMessages::characterReferenceAfterDocumentElement);      parseNamedCharRef();      break;    case tokenEroGrpo:    case tokenEroNameStart:      {	if (afterDocumentElement())	  message(ParserMessages::entityReferenceAfterDocumentElement);	ConstPtr<Entity> entity;	Ptr<EntityOrigin> origin;	if (parseEntityReference(0, token == tokenEroGrpo, entity, origin)) {	  if (!entity.isNull()) {	    if (entity->isCharacterData())	      acceptPcdata(Location(origin.pointer(), 0));	    if (inputLevel() == specialParseInputLevel())	      entity->rcdataReference(*this, origin);	    else	      entity->contentReference(*this, origin);	  }	}      }      break;    case tokenEtagoNameStart:      acceptEndTag(parseEndTag());      break;    case tokenEtagoTagc:      parseEmptyEndTag();      break;    case tokenEtagoGrpo:      parseGroupEndTag();      break;    case tokenMdoNameStart:      if (startMarkup(eventsWanted().wantInstanceMarkup(), currentLocation()))	currentMarkup()->addDelim(Syntax::dMDO);      Syntax::ReservedName name;      Boolean result;      unsigned startLevel;      startLevel = inputLevel();      if (parseDeclarationName(&name)) {	switch (name) {	case Syntax::rUSEMAP:	  if (afterDocumentElement())	    message(ParserMessages::declarationAfterDocumentElement,		    StringMessageArg(syntax().reservedName(name)));	  result = parseUsemapDecl();	  break;	case Syntax::rUSELINK:	  if (afterDocumentElement())	    message(ParserMessages::declarationAfterDocumentElement,		    StringMessageArg(syntax().reservedName(name)));	  result = parseUselinkDecl();	  break;	case Syntax::rDOCTYPE:	case Syntax::rLINKTYPE:	case Syntax::rELEMENT:	case Syntax::rATTLIST:	case Syntax::rENTITY:	case Syntax::rNOTATION:	case Syntax::rSHORTREF:	case Syntax::rLINK:	case Syntax::rIDLINK:	  message(ParserMessages::instanceDeclaration,		  StringMessageArg(syntax().reservedName(name)));	  result = 0;	  break;	default:	  message(ParserMessages::noSuchDeclarationType,		  StringMessageArg(syntax().reservedName(name)));	  result = 0;	  break;	}      }      else	result = 0;      if (!result)	skipDeclaration(startLevel);      noteMarkup();      break;    case tokenMdoMdc:      // empty comment      emptyCommentDecl();      noteMarkup();      break;    case tokenMdoCom:      parseCommentDecl();      noteMarkup();      break;    case tokenMdoDso:      if (afterDocumentElement())	message(ParserMessages::markedSectionAfterDocumentElement);      parseMarkedSectionDeclStart();      noteMarkup();      break;    case tokenMscMdc:      handleMarkedSectionEnd();      noteMarkup();      break;    case tokenNet:      parseNullEndTag();      break;    case tokenPio:      parseProcessingInstruction();      break;    case tokenStagoNameStart:      parseStartTag();      break;    case tokenStagoTagc:      parseEmptyStartTag();      break;    case tokenStagoGrpo:      parseGroupStartTag();      break;    case tokenRe:      acceptPcdata(currentLocation());      queueRe(currentLocation());      break;    case tokenRs:      acceptPcdata(currentLocation());      noteRs();      if (eventsWanted().wantInstanceMarkup())	eventHandler().ignoredRs(new (eventAllocator())				 IgnoredRsEvent(currentChar(),						currentLocation()));      break;    case tokenS:      extendContentS();      if (eventsWanted().wantInstanceMarkup())	eventHandler().sSep(new (eventAllocator())			    SSepEvent(currentInput()->currentTokenStart(),				      currentInput()->currentTokenLength(),				      currentLocation(),				      0));      break;    case tokenIgnoredChar:      extendData();      if (eventsWanted().wantMarkedSections())	eventHandler().ignoredChars(new (eventAllocator())				    IgnoredCharsEvent(currentInput()->currentTokenStart(),						      currentInput()->currentTokenLength(),						      currentLocation(),						      0));      break;    case tokenUnrecognized:      reportNonSgmlCharacter();      parsePcdata();      break;    case tokenCharDelim:      message(ParserMessages::dataCharDelim,	      StringMessageArg(StringC(currentInput()->currentTokenStart(),			  	       currentInput()->currentTokenLength())));      // fall through    case tokenChar:      parsePcdata();      break;    default:      ASSERT(token >= tokenFirstShortref);      handleShortref(token - tokenFirstShortref);      break;    }  } while (eventQueueEmpty());}void Parser::skipDeclaration(unsigned startLevel){  const unsigned skipMax = 250;  unsigned skipCount = 0;  for (;;) {    Token token = getToken(mdMode);    if (inputLevel() == startLevel)      skipCount++;    switch (token) {    case tokenUnrecognized:      (void)getChar();      break;    case tokenEe:      if (inputLevel() <= startLevel)	return;      popInputStack();      return;    case tokenMdc:      if (inputLevel() == startLevel)	return;      break;    case tokenS:      if (inputLevel() == startLevel && skipCount >= skipMax	  && currentChar() == syntax().standardFunction(Syntax::fRE))	return;      break;    default:      break;    }  }}void Parser::handleShortref(int index){  const ConstPtr<Entity> &entity    = currentElement().map()->entity(index);  if (!entity.isNull()) {    Owner<Markup> markupPtr;    if (eventsWanted().wantInstanceMarkup()) {      markupPtr = new Markup;      markupPtr->addShortref(currentInput());    }    Ptr<EntityOrigin> origin      = EntityOrigin::make(internalAllocator(),			   entity,			   currentLocation(),			   currentInput()->currentTokenLength(),			   markupPtr);    entity->contentReference(*this, origin);    return;  }  InputSource *in = currentInput();  size_t length = in->currentTokenLength();  const Char *s = in->currentTokenStart();  size_t i = 0;  if (currentMode() == econMode || currentMode() == econnetMode) {    // FIXME do this in advance (what about B sequence?)    for (i = 0; i < length && syntax().isS(s[i]); i++)      ;    if (i > 0 && eventsWanted().wantInstanceMarkup())      eventHandler().sSep(new (eventAllocator())			  SSepEvent(s, i, currentLocation(), 0));  }  if (i < length) {    Location location(currentLocation());    location += i;    s += i;    length -= i;    acceptPcdata(location);    if (sd().keeprsre()) {      noteData();      eventHandler().data(new (eventAllocator())  			  ImmediateDataEvent(Event::characterData, s, length,					     location, 0));      return;    }     // FIXME speed this up    for (; length > 0; location += 1, length--, s++) {      if (*s == syntax().standardFunction(Syntax::fRS)) {	noteRs();	if (eventsWanted().wantInstanceMarkup())	  eventHandler().ignoredRs(new (eventAllocator())				   IgnoredRsEvent(*s, location));      }      else if (*s == syntax().standardFunction(Syntax::fRE))	queueRe(location);      else {	noteData();	eventHandler().data(new (eventAllocator())			    ImmediateDataEvent(Event::characterData, s, 1,					       location, 0));      }    }  }}void Parser::parsePcdata(){  extendData();  acceptPcdata(currentLocation());  noteData();  eventHandler().data(new (eventAllocator())		      ImmediateDataEvent(Event::characterData,					 currentInput()->currentTokenStart(),					 currentInput()->currentTokenLength(),					 currentLocation(),					 0));}void Parser::parseStartTag(){  InputSource *in = currentInput();  Markup *markup = startMarkup(eventsWanted().wantInstanceMarkup(),			       in->currentLocation());  in->discardInitial();  extendNameToken(syntax().namelen(), ParserMessages::nameLength);  if (markup) {    markup->addDelim(Syntax::dSTAGO);    markup->addName(in);  }  StringC &name = nameBuffer();  getCurrentToken(syntax().generalSubstTable(), name);  ElementType *e = currentDtdNonConst().lookupElementType(name);  if (sd().rank()) {    if (!e)      e = completeRankStem(name);    else if (e->isRankedElement())      handleRankedElement(e);  }  if (!e)    e = lookupCreateUndefinedElement(name, currentLocation(), currentDtdNonConst());  Boolean netEnabling;  AttributeList *attributes = allocAttributeList(e->attributeDef(), 0);  Token closeToken = getToken(tagMode);  if (closeToken == tokenTagc) {    if (name.size() > syntax().taglen())      checkTaglen(markupLocation().index());    attributes->finish(*this);    netEnabling = 0;    if (markup)      markup->addDelim(Syntax::dTAGC);  }  else {    in->ungetToken();    Ptr<AttributeDefinitionList> newAttDef;    if (parseAttributeSpec(0, *attributes, netEnabling, newAttDef)) {      // The difference between the indices will be the difference      // in offsets plus 1 for each named character reference.      if (in->currentLocation().index() - markupLocation().index()	  > syntax().taglen())	checkTaglen(markupLocation().index());    }    else      netEnabling = 0;    if (!newAttDef.isNull()) {      newAttDef->setIndex(currentDtdNonConst().allocAttributeDefinitionListIndex());      e->setAttributeDef(newAttDef);    }  }  acceptStartTag(e,		 new (eventAllocator())		 StartElementEvent(e,				   currentDtdPointer(),				   attributes,				   markupLocation(),				   markup),		 netEnabling);}ElementType *Parser::completeRankStem(const StringC &name){

⌨️ 快捷键说明

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