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

📄 parseparam.cxx

📁 SP是一个基于GNU C++编译器
💻 CXX
📖 第 1 页 / 共 2 页
字号:
// Copyright (c) 1994 James Clark// See the file COPYING for copying permission.#include "splib.h"#include "Parser.h"#include "Param.h"#include "Group.h"#include "Markup.h"#include "ParserMessages.h"#include "MessageArg.h"#include "TokenMessageArg.h"#include "token.h"#include "macros.h"#ifdef SP_NAMESPACEnamespace SP_NAMESPACE {#endifBoolean Parser::parseParam(const AllowedParams &allow,			   unsigned declInputLevel,			   Param &parm){  for (;;) {    Token token = getToken(allow.mainMode());    switch (token) {    case tokenUnrecognized:      if (reportNonSgmlCharacter())	break;      {	message(ParserMessages::markupDeclarationCharacter,		StringMessageArg(currentToken()),		AllowedParamsMessageArg(allow, syntaxPointer()));      }      return 0;    case tokenEe:      if (inputLevel() <= declInputLevel) {	message(ParserMessages::declarationLevel);	return 0;      }      if (currentMarkup())	currentMarkup()->addEntityEnd();      popInputStack();      break;    case tokenCom:      if (!parseComment(comMode))	return 0;      if (options().warnPsComment)	message(ParserMessages::psComment);      break;    case tokenDso:      if (!allow.dso()) {	paramInvalidToken(tokenDso, allow);	return 0;      }      if (currentMarkup())	currentMarkup()->addDelim(Syntax::dDSO);      parm.type = Param::dso;      return 1;    case tokenGrpo:      if (currentMarkup())	currentMarkup()->addDelim(Syntax::dGRPO);      switch (allow.group()) {      case Param::invalid:	paramInvalidToken(tokenGrpo, allow);	return 0;      case Param::modelGroup:	{	  ModelGroup *group;	  if (!parseModelGroup(1, declInputLevel, group, grpsufMode))	    return 0;	  parm.type = Param::modelGroup;	  parm.modelGroupPtr = group;	}	break;      case Param::nameGroup:	if (!parseNameGroup(declInputLevel, parm))	  return 0;	break;      case Param::nameTokenGroup:	if (!parseNameTokenGroup(declInputLevel, parm))	  return 0;	break;      default:	CANNOT_HAPPEN();      }      parm.type = allow.group();      return 1;    case tokenLita:    case tokenLit:      parm.type = allow.literal();      parm.lita = token == tokenLita;      switch (allow.literal()) {      case Param::invalid:	paramInvalidToken(token, allow);	return 0;      case Param::minimumLiteral:	if (!parseMinimumLiteral(parm.lita, parm.literalText))	  return 0;	break;      case Param::attributeValueLiteral:	if (!parseAttributeValueLiteral(parm.lita, parm.literalText))	  return 0;	break;      case Param::tokenizedAttributeValueLiteral:	if (!parseTokenizedAttributeValueLiteral(parm.lita, parm.literalText))	  return 0;	break;      case Param::systemIdentifier:	if (!parseSystemIdentifier(parm.lita, parm.literalText))	  return 0;	break;      case Param::paramLiteral:	if (!parseParameterLiteral(parm.lita, parm.literalText))	  return 0;	break;      }      if (currentMarkup())	currentMarkup()->addLiteral(parm.literalText);      return 1;    case tokenMdc:      if (!allow.mdc()) {	paramInvalidToken(tokenMdc, allow);	return 0;      }      if (inputLevel() > declInputLevel)	message(ParserMessages::parameterEntityNotEnded);      if (currentMarkup())	currentMarkup()->addDelim(Syntax::dMDC);      parm.type = Param::mdc;      return 1;    case tokenMinus:      parm.type = Param::minus;      if (currentMarkup())	currentMarkup()->addDelim(Syntax::dMINUS);      return 1;    case tokenMinusGrpo:      if (!allow.exclusions()) {	paramInvalidToken(tokenMinusGrpo, allow);	return 0;      }      if (currentMarkup()) {	currentMarkup()->addDelim(Syntax::dMINUS);	currentMarkup()->addDelim(Syntax::dGRPO);      }      parm.type = Param::exclusions;      return parseElementNameGroup(declInputLevel, parm);    case tokenPero:      parm.type = Param::pero;      if (currentMarkup())	currentMarkup()->addDelim(Syntax::dPERO);      return 1;    case tokenPeroGrpo:      if (!inInstance())	message(ParserMessages::peroGrpoProlog);      // fall through    case tokenPeroNameStart:      {	if (inInstance()) {	  if (options().warnInstanceParamEntityRef)	    message(ParserMessages::instanceParamEntityRef);	}	else {	  if (options().warnInternalSubsetPsParamEntityRef && inputLevel() == 1)	    message(ParserMessages::internalSubsetPsParamEntityRef);	}	ConstPtr<Entity> entity;	Ptr<EntityOrigin> origin;	if (!parseEntityReference(1, token == tokenPeroGrpo, entity, origin))	  return 0;	if (!entity.isNull())	  entity->declReference(*this, origin);      }      break;    case tokenPlusGrpo:      if (!allow.inclusions()) {	paramInvalidToken(tokenPlusGrpo, allow);	return 0;      }      if (currentMarkup()) {	currentMarkup()->addDelim(Syntax::dPLUS);	currentMarkup()->addDelim(Syntax::dGRPO);      }      parm.type = Param::inclusions;      return parseElementNameGroup(declInputLevel, parm);    case tokenRni:      if (!allow.rni()) {	paramInvalidToken(tokenRni, allow);	return 0;      }      return parseIndicatedReservedName(allow, parm);    case tokenS:      if (currentMarkup())	currentMarkup()->addS(currentChar());      break;    case tokenNameStart:      switch (allow.nameStart()) {      case Param::invalid:	paramInvalidToken(tokenNameStart, allow);	return 0;      case Param::reservedName:	return parseReservedName(allow, parm);      case Param::name:	extendNameToken(syntax().namelen(), ParserMessages::nameLength);	parm.type = Param::name;	getCurrentToken(syntax().generalSubstTable(), parm.token);	if (currentMarkup())	  currentMarkup()->addName(currentInput());	return 1;      case Param::entityName:	extendNameToken(syntax().namelen(), ParserMessages::nameLength);	parm.type = Param::entityName;	getCurrentToken(syntax().entitySubstTable(), parm.token);	if (currentMarkup())	  currentMarkup()->addName(currentInput());	return 1;      case Param::paramEntityName:	extendNameToken(syntax().penamelen(),			ParserMessages::parameterEntityNameLength);	parm.type = Param::paramEntityName;	getCurrentToken(syntax().entitySubstTable(), parm.token);	if (currentMarkup())	  currentMarkup()->addName(currentInput());	return 1;      case Param::attributeValue:	return parseAttributeValueParam(parm);      }      break;    case tokenDigit:      switch (allow.digit()) {      case Param::invalid:	paramInvalidToken(tokenDigit, allow);	return 0;      case Param::number:	extendNumber(syntax().namelen(), ParserMessages::numberLength);	parm.type = Param::number;	getCurrentToken(parm.token);	if (currentMarkup())	  currentMarkup()->addNumber(currentInput());	return 1;      case Param::attributeValue:	return parseAttributeValueParam(parm);      }      break;    case tokenLcUcNmchar:      switch (allow.nmchar()) {      case Param::invalid:	paramInvalidToken(tokenLcUcNmchar, allow);	return 0;      case Param::attributeValue:	return parseAttributeValueParam(parm);      }      break;    default:      CANNOT_HAPPEN();    }  }}void Parser::paramInvalidToken(Token token, const AllowedParams &allow){  message(ParserMessages::paramInvalidToken,	  TokenMessageArg(token, allow.mainMode(),			  syntaxPointer(), sdPointer()),	  AllowedParamsMessageArg(allow, syntaxPointer()));}Boolean Parser::parseGroupToken(const AllowedGroupTokens &allow,				unsigned nestingLevel,				unsigned declInputLevel,				unsigned groupInputLevel,				GroupToken &gt){  for (;;) {    Token token = getToken(grpMode);    switch (token) {    case tokenEe:      if (inputLevel() <= groupInputLevel) {	message(ParserMessages::groupLevel);	if (inputLevel() <= declInputLevel)	  return 0;      }      else if (!sd().www())	message(ParserMessages::groupEntityEnd);      if (currentMarkup())	currentMarkup()->addEntityEnd();      popInputStack();      break;    case tokenPeroGrpo:      if (!inInstance())	message(ParserMessages::peroGrpoProlog);      // fall through    case tokenPeroNameStart:      {	if (options().warnInternalSubsetTsParamEntityRef && inputLevel() == 1)	  message(ParserMessages::internalSubsetTsParamEntityRef);	ConstPtr<Entity> entity;	Ptr<EntityOrigin> origin;	if (!parseEntityReference(1, token == tokenPeroGrpo, entity, origin))	  return 0;	if (!entity.isNull())	  entity->declReference(*this, origin);      }      break;    case tokenUnrecognized:      if (reportNonSgmlCharacter())	break;      {	message(ParserMessages::groupCharacter,		StringMessageArg(currentToken()),		AllowedGroupTokensMessageArg(allow, syntaxPointer()));      }      return 0;    case tokenDtgo:      if (!allow.groupToken(GroupToken::dataTagGroup)) {	groupTokenInvalidToken(tokenDtgo, allow);	return 0;      }      if (sd().datatag())	message(ParserMessages::datatagNotImplemented);      if (currentMarkup())	currentMarkup()->addDelim(Syntax::dDTGO);      return parseDataTagGroup(nestingLevel + 1, declInputLevel, gt);    case tokenGrpo:      if (currentMarkup())	currentMarkup()->addDelim(Syntax::dGRPO);      switch (allow.group()) {      case GroupToken::modelGroup:	{	  ModelGroup *modelGroup;	  if (!parseModelGroup(nestingLevel + 1, declInputLevel, modelGroup,			       grpMode))	    return 0;	  gt.model = modelGroup;	  gt.type = GroupToken::modelGroup;	  return 1;	}      case GroupToken::dataTagTemplateGroup:	return parseDataTagTemplateGroup(nestingLevel + 1, declInputLevel, gt);      default:	groupTokenInvalidToken(tokenGrpo, allow);	return 0;      }      break;    case tokenRni:      if (!allow.groupToken(GroupToken::pcdata)) {	groupTokenInvalidToken(tokenRni, allow);	return 0;      }      Syntax::ReservedName rn;      if (!getIndicatedReservedName(&rn))	return 0;      if (rn != Syntax::rPCDATA) {	StringC token(syntax().delimGeneral(Syntax::dRNI));	token += syntax().reservedName(Syntax::rPCDATA);	message(ParserMessages::invalidToken, StringMessageArg(token));	return 0;      }      gt.type = GroupToken::pcdata;      gt.contentToken = new PcdataToken;      return 1;    case tokenS:      if (currentMarkup()) {	extendS();	currentMarkup()->addS(currentInput());      }      break;    case tokenNameStart:      switch (allow.nameStart()) {      case GroupToken::elementToken:	{	  extendNameToken(syntax().namelen(), ParserMessages::nameLength);	  gt.type = GroupToken::elementToken;	  StringC &buffer = nameBuffer();	  getCurrentToken(syntax().generalSubstTable(), buffer);	  if (currentMarkup())	    currentMarkup()->addName(currentInput());	  const ElementType *e = lookupCreateElement(buffer);	  ContentToken::OccurrenceIndicator oi	    = getOccurrenceIndicator(grpMode);	  gt.contentToken = new ElementToken(e, oi);	  return 1;	}      case GroupToken::name:      case GroupToken::nameToken:	extendNameToken(syntax().namelen(),			token == GroupToken::name			? ParserMessages::nameLength			: ParserMessages::nameTokenLength);	getCurrentToken(syntax().generalSubstTable(), gt.token);	gt.type = allow.nameStart();	if (currentMarkup()) {	  if (gt.type == GroupToken::nameToken)	    currentMarkup()->addNameToken(currentInput());	  else	    currentMarkup()->addName(currentInput());	}	return 1;      default:	groupTokenInvalidToken(tokenNameStart, allow);	return 0;      }    case tokenDigit:    case tokenLcUcNmchar:      if (!allow.groupToken(GroupToken::nameToken)) {	groupTokenInvalidToken(token, allow);	return 0;      }      extendNameToken(syntax().namelen(), ParserMessages::nameTokenLength);      getCurrentToken(syntax().generalSubstTable(), gt.token);      gt.type = GroupToken::nameToken;      if (currentMarkup())	currentMarkup()->addNameToken(currentInput());      return 1;    case tokenLit:    case tokenLita:      // parameter literal in data tag pattern      if (!allow.groupToken(GroupToken::dataTagLiteral)) {	groupTokenInvalidToken(token, allow);	return 0;      }      if (!parseDataTagParameterLiteral(token == tokenLita, gt.text))	return 0;      gt.type = GroupToken::dataTagLiteral;      if (currentMarkup())	currentMarkup()->addLiteral(gt.text);      return 1;    case tokenAnd:    case tokenSeq:    case tokenOr:    case tokenDtgc:    case tokenGrpc:    case tokenOpt:    case tokenPlus:    case tokenRep:      groupTokenInvalidToken(token, allow);      return 0;    }  }}void Parser::groupTokenInvalidToken(Token token, const AllowedGroupTokens &allow){  message(ParserMessages::groupTokenInvalidToken,	  TokenMessageArg(token, grpMode, syntaxPointer(), sdPointer()),	  AllowedGroupTokensMessageArg(allow, syntaxPointer()));}Boolean Parser::parseGroupConnector(const AllowedGroupConnectors &allow,				    unsigned declInputLevel,				    unsigned groupInputLevel,				    GroupConnector &gc){  for (;;) {    Token token = getToken(grpMode);    switch (token) {    case tokenEe:      if (inputLevel() <= groupInputLevel) {	message(ParserMessages::groupLevel);	if (inputLevel() <= declInputLevel)	  return 0;      }      if (currentMarkup())	currentMarkup()->addEntityEnd();      popInputStack();      break;    case tokenS:      if (currentMarkup()) {	extendS();	currentMarkup()->addS(currentInput());      }      break;    case tokenPeroGrpo:      if (inInstance()) {	message(ParserMessages::peroGrpoProlog);	break;      }      // fall through    case tokenPeroNameStart:      if (!sd().www())	message(ParserMessages::groupEntityReference);      else {	ConstPtr<Entity> entity;	Ptr<EntityOrigin> origin;	if (!parseEntityReference(1, token == tokenPeroGrpo, entity, origin))	  return 0;	if (!entity.isNull())	  entity->declReference(*this, origin);      }      break;    case tokenUnrecognized:      if (reportNonSgmlCharacter())	break;      {	message(ParserMessages::groupCharacter,		StringMessageArg(currentToken()),		AllowedGroupConnectorsMessageArg(allow, syntaxPointer()));      }      return 0;    case tokenAnd:      if (!allow.groupConnector(GroupConnector::andGC)) {	groupConnectorInvalidToken(tokenAnd, allow);	return 0;      }      gc.type = GroupConnector::andGC;      if (currentMarkup())	currentMarkup()->addDelim(Syntax::dAND);      return 1;    case tokenSeq:      if (!allow.groupConnector(GroupConnector::seqGC)) {	groupConnectorInvalidToken(tokenSeq, allow);

⌨️ 快捷键说明

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