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

📄 parsedecl.cxx

📁 SP是一个基于GNU C++编译器
💻 CXX
📖 第 1 页 / 共 5 页
字号:
// Copyright (c) 1994, 1995 James Clark// See the file COPYING for copying permission.// Prolog, dtd and declaration parsing.#include "splib.h"#include "Parser.h"#include "Param.h"#include "Markup.h"#include "ParserMessages.h"#include "MessageArg.h"#include "TokenMessageArg.h"#include "token.h"#include "macros.h"#ifdef SP_NAMESPACEnamespace SP_NAMESPACE {#endifstatic const AllowedParams allowMdc(Param::mdc);static const AllowedParams allowName(Param::name);static const AllowedParams allowParamLiteral(Param::paramLiteral);static const AllowedParams allowNameNameGroup(Param::name, Param::nameGroup);static const AllowedParams allowDsoMdc(Param::dso, Param::mdc);static AllowedParams allowNameMdc(Param::name, Param::mdc);static AllowedParams  allowExplicitLinkRuleMdc(Param::mdc,			   Param::name,			   Param::nameGroup,			   Param::indicatedReservedName + Syntax::rIMPLIED);static AllowedParams  allowNameNameGroupMdc(Param::name, Param::nameGroup, Param::mdc);static const AllowedParams  allowLinkSetSpec(Param::name,		   Param::indicatedReservedName + Syntax::rINITIAL,		   Param::indicatedReservedName + Syntax::rEMPTY,		   Param::indicatedReservedName + Syntax::rRESTORE);void Parser::doProlog(){  const unsigned maxTries = 10;  unsigned tries = 0;  do {    if (cancelled()) {      allDone();      return;    }    Token token = getToken(proMode);    switch (token) {    case tokenUnrecognized:      if (reportNonSgmlCharacter())	break;      if (hadDtd()) {	currentInput()->ungetToken();	endProlog();	return;      }      {	StringC gi;	if (lookingAtStartTag(gi)) {	  currentInput()->ungetToken();	  implyDtd(gi);	  return;	}      }	          if (++tries >= maxTries) {	message(ParserMessages::notSgml);	giveUp();	return;      }      message(ParserMessages::prologCharacter, StringMessageArg(currentToken()));      prologRecover();      break;    case tokenEe:      if (hadDtd()) {	endProlog();	return;      }      message(ParserMessages::documentEndProlog);      allDone();      return;    case tokenMdoMdc:      // empty comment      emptyCommentDecl();      break;    case tokenMdoCom:      if (!parseCommentDecl())	prologRecover();      break;    case tokenMdoNameStart:      setPass2Start();      if (startMarkup(eventsWanted().wantPrologMarkup(), currentLocation()))	currentMarkup()->addDelim(Syntax::dMDO);      Syntax::ReservedName name;      if (parseDeclarationName(&name)) {	switch (name) {	case Syntax::rDOCTYPE:	  if (!parseDoctypeDeclStart())	    giveUp();	  return;	case Syntax::rLINKTYPE:	  if (!parseLinktypeDeclStart())	    giveUp();	  return;	case Syntax::rELEMENT:	case Syntax::rATTLIST:	case Syntax::rENTITY:	case Syntax::rNOTATION:	case Syntax::rSHORTREF:	case Syntax::rUSEMAP:	case Syntax::rUSELINK:	case Syntax::rLINK:	case Syntax::rIDLINK:	  message(ParserMessages::prologDeclaration,		  StringMessageArg(syntax().reservedName(name)));	  if (!hadDtd())	    tries++;	  prologRecover();	  break;	default:	  message(ParserMessages::noSuchDeclarationType,		  StringMessageArg(syntax().reservedName(name)));	  prologRecover();	  break;	}      }      else	prologRecover();      break;    case tokenPio:      if (!parseProcessingInstruction())	prologRecover();      break;    case tokenS:      if (eventsWanted().wantPrologMarkup()) {	extendS();	eventHandler().sSep(new (eventAllocator())			    SSepEvent(currentInput()->currentTokenStart(),				      currentInput()->currentTokenLength(),				      currentLocation(),				      1));      }      break;    default:      CANNOT_HAPPEN();    }  } while (eventQueueEmpty());}void Parser::endProlog(){  if (baseDtd().isNull()#if 0      || baseDtd()->documentElementType()->definition()->undefined()#endif      ) {    // We could continue, but there's not a lot of point.    giveUp();    return;  }  if (maybeStartPass2())    setPhase(prologPhase);  else {    if (inputLevel() == 0) {      allDone();      return;    }    if (pass2())      checkEntityStability();    setPhase(instanceStartPhase);    startInstance();    ConstPtr<ComplexLpd> lpd;    Vector<AttributeList> simpleLinkAtts;    Vector<StringC> simpleLinkNames;    for (size_t i = 0; i < nActiveLink(); i++)      if (activeLpd(i).type() == Lpd::simpleLink) {	const SimpleLpd &lpd = (SimpleLpd &)activeLpd(i);	simpleLinkNames.push_back(lpd.name());	simpleLinkAtts.resize(simpleLinkAtts.size() + 1);	simpleLinkAtts.back().init(lpd.attributeDef());	simpleLinkAtts.back().finish(*this);      }      else 	lpd = (ComplexLpd *)&activeLpd(i);    eventHandler().endProlog(new (eventAllocator())			     EndPrologEvent(baseDtd(),					    lpd,					    simpleLinkNames,					    simpleLinkAtts,					    currentLocation()));  }}void Parser::prologRecover(){  unsigned skipCount = 0;  const unsigned skipMax = 250;  for (;;) {    Token token = getToken(proMode);    skipCount++;    if (token == tokenUnrecognized) {      token = getToken(mdMode);      if (token == tokenMdc) {	token = getToken(proMode);	if (token == tokenS)	  return;      }    }    switch (token) {    case tokenUnrecognized:      (void)getChar();      break;    case tokenEe:      return;    case tokenMdoMdc:    case tokenMdoCom:    case tokenMdoNameStart:    case tokenPio:      currentInput()->ungetToken();      return;    case tokenS:      if (currentChar() == syntax().standardFunction(Syntax::fRE)	  && skipCount >= skipMax)	return;    default:      break;    }  }}void Parser::doDeclSubset(){  do {    if (cancelled()) {      allDone();      return;    }    Token token = getToken(currentMode());    unsigned startLevel = inputLevel();    Boolean inDtd = !haveDefLpd();    switch (token) {    case tokenUnrecognized:      if (reportNonSgmlCharacter())	break;      message(ParserMessages::declSubsetCharacter, StringMessageArg(currentToken()));      declSubsetRecover(startLevel);      break;    case tokenEe:      if (inputLevel() == specialParseInputLevel()) {	// FIXME have separate messages for each type of special parse	message(ParserMessages::specialParseEntityEnd);      }      if (eventsWanted().wantPrologMarkup())	eventHandler().entityEnd(new (eventAllocator())				 EntityEndEvent(currentLocation()));      if (inputLevel() == 2) {	const EntityDecl *e	  = currentLocation().origin()->entityDecl();	if (e	    && (e->declType() == EntityDecl::doctype		|| e->declType() == EntityDecl::linktype)) {	  // popInputStack may destroy e	  Boolean fake = e->defLocation().origin().isNull();	  popInputStack();	  if (!(inDtd		? parseDoctypeDeclEnd(fake)		: parseLinktypeDeclEnd()))	    ;			// FIXME recover	  setPhase(prologPhase);	  return;	}      }      if (inputLevel() == 1) {	if (finalPhase() == declSubsetPhase) {	  checkDtd(defDtd());	  endDtd();	}	else	  // Give message before popping stack.	  message(inDtd		  ? ParserMessages::documentEndDtdSubset		  : ParserMessages::documentEndLpdSubset);	popInputStack();	allDone();      }      else	popInputStack();      return;    case tokenDsc:		// end of declaration subset      // FIXME what's the right location?      if (!referenceDsEntity(currentLocation())) {	if (!(inDtd ? parseDoctypeDeclEnd() : parseLinktypeDeclEnd()))	  ;			// FIXME recover	setPhase(prologPhase);      }      return;    case tokenMdoNameStart:	// named markup declaration      if (startMarkup(eventsWanted().wantPrologMarkup(), currentLocation()))	currentMarkup()->addDelim(Syntax::dMDO);      Syntax::ReservedName name;      Boolean result;      if (parseDeclarationName(&name,			       inDtd && !options().errorAfdr)) {	switch (name) {	case Syntax::rANY:	// used for <!AFDR	  result = parseAfdrDecl();	  break;	case Syntax::rELEMENT:	  if (inDtd)	    result = parseElementDecl();	  else {	    message(ParserMessages::lpdSubsetDeclaration,		    StringMessageArg(syntax().reservedName(name)));	    result = 0;	  }	  break;	case Syntax::rATTLIST:	  result = parseAttlistDecl();	  break;	case Syntax::rENTITY:	  result = parseEntityDecl();	  break;	case Syntax::rNOTATION:	  result = parseNotationDecl();	  if (!inDtd && !sd().www())	    message(ParserMessages::lpdSubsetDeclaration,		    StringMessageArg(syntax().reservedName(name)));	  break;	case Syntax::rSHORTREF:	  if (inDtd)	    result = parseShortrefDecl();	  else {	    message(ParserMessages::lpdSubsetDeclaration,		    StringMessageArg(syntax().reservedName(name)));	    result = 0;	  }	  break;	case Syntax::rUSEMAP:	  if (inDtd)	    result = parseUsemapDecl();	  else {	    message(ParserMessages::lpdSubsetDeclaration,		    StringMessageArg(syntax().reservedName(name)));	    result = 0;	  }	  break;	case Syntax::rLINK:	  if (inDtd) {	    message(ParserMessages::dtdSubsetDeclaration,		    StringMessageArg(syntax().reservedName(name)));	    result = 0;	  }	  else	    result = parseLinkDecl();	  break;	case Syntax::rIDLINK:	  if (inDtd) {	    message(ParserMessages::dtdSubsetDeclaration,		    StringMessageArg(syntax().reservedName(name)));	    result = 0;	  }	  else	    result = parseIdlinkDecl();	  break;	case Syntax::rDOCTYPE:	case Syntax::rLINKTYPE:	case Syntax::rUSELINK:	  result = 0;	  message(inDtd		  ? ParserMessages::dtdSubsetDeclaration		  : ParserMessages::lpdSubsetDeclaration,		  StringMessageArg(syntax().reservedName(name)));	  break;	default:	  result = 0;	  message(ParserMessages::noSuchDeclarationType,		  StringMessageArg(syntax().reservedName(name)));	  break;	}      }      else	result = 0;      if (!result)	declSubsetRecover(startLevel);      break;    case tokenMdoMdc:		// empty comment declaration      // empty comment      emptyCommentDecl();      break;    case tokenMdoCom:		// comment declaration      if (!parseCommentDecl())	declSubsetRecover(startLevel);      break;    case tokenMdoDso:		// marked section declaration      if (!parseMarkedSectionDeclStart())	declSubsetRecover(startLevel);      break;    case tokenMscMdc:      handleMarkedSectionEnd();      break;    case tokenPeroGrpo:		// parameter entity reference with name group      message(ParserMessages::peroGrpoProlog);      // fall through    case tokenPeroNameStart:	// parameter entity reference      {	ConstPtr<Entity> entity;	Ptr<EntityOrigin> origin;	if (parseEntityReference(1, token == tokenPeroGrpo, entity, origin)) {	  if (!entity.isNull())	    entity->dsReference(*this, origin);	}	else	  declSubsetRecover(startLevel);      }      break;    case tokenPio:		// processing instruction      if (!parseProcessingInstruction())	declSubsetRecover(startLevel);      break;    case tokenS:		// white space      if (eventsWanted().wantPrologMarkup()) {	extendS();

⌨️ 快捷键说明

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