/* * CDE - Common Desktop Environment * * Copyright (c) 1993-2012, The Open Group. All rights reserved. * * These libraries and programs are free software; you can * redistribute them and/or modify them under the terms of the GNU * Lesser General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * These libraries and programs are distributed in the hope that * they will be useful, but WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public * License along with these libraries and programs; if not, write * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth * Floor, Boston, MA 02110-1301 USA */ /* $XConsortium: parseParam.C /main/1 1996/07/29 17:09:31 cde-hp $ */ // 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_NAMESPACE namespace SP_NAMESPACE { #endif Boolean 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; 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: { ConstPtr entity; Ptr 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 >) { for (;;) { Token token = getToken(grpMode); switch (token) { case tokenEe: if (inputLevel() <= groupInputLevel) { message(ParserMessages::groupLevel); if (inputLevel() <= declInputLevel) return 0; } else message(ParserMessages::groupEntityEnd); if (currentMarkup()) currentMarkup()->addEntityEnd(); popInputStack(); break; case tokenPeroGrpo: if (!inInstance()) message(ParserMessages::peroGrpoProlog); // fall through case tokenPeroNameStart: { ConstPtr entity; Ptr 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: message(ParserMessages::groupEntityReference); 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); return 0; } gc.type = GroupConnector::seqGC; if (currentMarkup()) currentMarkup()->addDelim(Syntax::dSEQ); return 1; case tokenOr: if (!allow.groupConnector(GroupConnector::orGC)) { groupConnectorInvalidToken(tokenOr, allow); return 0; } gc.type = GroupConnector::orGC; if (currentMarkup()) currentMarkup()->addDelim(Syntax::dOR); return 1; case tokenDtgc: if (!allow.groupConnector(GroupConnector::dtgcGC)) { groupConnectorInvalidToken(tokenDtgc, allow); return 0; } gc.type = GroupConnector::dtgcGC; if (inputLevel() > groupInputLevel) message(ParserMessages::groupParameterEntityNotEnded); if (currentMarkup()) currentMarkup()->addDelim(Syntax::dDTGC); return 1; case tokenGrpc: if (!allow.groupConnector(GroupConnector::grpcGC)) { groupConnectorInvalidToken(tokenGrpc, allow); return 0; } gc.type = GroupConnector::grpcGC; if (inputLevel() > groupInputLevel) message(ParserMessages::groupParameterEntityNotEnded); if (currentMarkup()) currentMarkup()->addDelim(Syntax::dGRPC); return 1; default: groupConnectorInvalidToken(token, allow); return 0; } } } void Parser::groupConnectorInvalidToken(Token token, const AllowedGroupConnectors &allow) { message(ParserMessages::connectorInvalidToken, TokenMessageArg(token, grpMode, syntaxPointer(), sdPointer()), AllowedGroupConnectorsMessageArg(allow, syntaxPointer())); } Boolean Parser::parseElementNameGroup(unsigned declInputLevel, Param &parm) { if (!parseNameGroup(declInputLevel, parm)) return 0; parm.elementVector.resize(parm.nameTokenVector.size()); for (size_t i = 0; i < parm.nameTokenVector.size(); i++) parm.elementVector[i] = lookupCreateElement(parm.nameTokenVector[i].name); return 1; } Boolean Parser::parseEntityReferenceNameGroup(Boolean &ignore) { Param parm; if (!parseNameGroup(inputLevel(), parm)) return 0; if (inInstance()) { for (size_t i = 0; i < parm.nameTokenVector.size(); i++) { const Lpd *lpd = lookupLpd(parm.nameTokenVector[i].name).pointer(); if (lpd && lpd->active()) { ignore = 0; return 1; } } } ignore = 1; return 1; } Boolean Parser::parseTagNameGroup(Boolean &active) { Param parm; if (!parseNameGroup(inputLevel(), parm)) return 0; active = 0; return 1; } Boolean Parser::parseNameGroup(unsigned declInputLevel, Param &parm) { static AllowedGroupTokens allowName(GroupToken::name); return parseGroup(allowName, declInputLevel, parm); } Boolean Parser::parseNameTokenGroup(unsigned declInputLevel, Param &parm) { static AllowedGroupTokens allowNameToken(GroupToken::nameToken); return parseGroup(allowNameToken, declInputLevel, parm); } static Boolean groupContains(const Vector &vec, const StringC &str) { for (size_t i = 0; i < vec.size(); i++) if (vec[i].name == str) return 1; return 0; } Boolean Parser::parseGroup(const AllowedGroupTokens &allowToken, unsigned declInputLevel, Param &parm) { unsigned groupInputLevel = inputLevel(); int nDuplicates = 0; Vector &vec = parm.nameTokenVector; vec.clear(); GroupConnector::Type connector = GroupConnector::grpcGC; GroupToken gt; for (;;) { if (!parseGroupToken(allowToken, 0, declInputLevel, groupInputLevel, gt)) return 0; if (groupContains(vec, gt.token)) { nDuplicates++; message(ParserMessages::duplicateGroupToken, StringMessageArg(gt.token)); } else { vec.resize(vec.size() + 1); gt.token.swap(vec.back().name); getCurrentToken(vec.back().origName); vec.back().loc = currentLocation(); } GroupConnector gc; static AllowedGroupConnectors allowAnyConnectorGrpc(GroupConnector::orGC, GroupConnector::andGC, GroupConnector::seqGC, GroupConnector::grpcGC); if (!parseGroupConnector(allowAnyConnectorGrpc, declInputLevel, groupInputLevel, gc)) return 0; if (gc.type == GroupConnector::grpcGC) break; if (connector == GroupConnector::grpcGC) connector = gc.type; else if (gc.type != connector) { if (options().warnShould) message(ParserMessages::mixedConnectors); connector = gc.type; } } if (nDuplicates + vec.size() > syntax().grpcnt()) message(ParserMessages::groupCount, NumberMessageArg(syntax().grpcnt())); return 1; } Boolean Parser::parseDataTagGroup(unsigned nestingLevel, unsigned declInputLevel, GroupToken &result) { if (nestingLevel - 1 == syntax().grplvl()) message(ParserMessages::grplvl, NumberMessageArg(syntax().grplvl())); unsigned groupInputLevel = inputLevel(); GroupToken gt; static AllowedGroupTokens allowName(GroupToken::name); if (!parseGroupToken(allowName, nestingLevel, declInputLevel, groupInputLevel, gt)) return 0; const ElementType *element = lookupCreateElement(gt.token); GroupConnector gc; static AllowedGroupConnectors allowSeq(GroupConnector::seqGC); if (!parseGroupConnector(allowSeq, declInputLevel, groupInputLevel, gc)) return 0; static AllowedGroupTokens allowDataTagLiteralDataTagTemplateGroup(GroupToken::dataTagLiteral, GroupToken::dataTagTemplateGroup); if (!parseGroupToken(allowDataTagLiteralDataTagTemplateGroup, nestingLevel, declInputLevel, groupInputLevel, gt)) return 0; Vector templates; if (gt.type == GroupToken::dataTagTemplateGroup) gt.textVector.swap(templates); else { templates.resize(1); gt.text.swap(templates[0]); } static AllowedGroupConnectors allowSeqDtgc(GroupConnector::seqGC, GroupConnector::dtgcGC); if (!parseGroupConnector(allowSeqDtgc, declInputLevel, groupInputLevel, gc)) return 0; NCVector > vec(2); vec[1] = new PcdataToken; if (gc.type != GroupConnector::dtgcGC) { static AllowedGroupTokens allowDataTagLiteral(GroupToken::dataTagLiteral); if (!parseGroupToken(allowDataTagLiteral, nestingLevel, declInputLevel, groupInputLevel, gt)) return 0; vec[0] = new DataTagElementToken(element, templates, gt.text); static AllowedGroupConnectors allowDtgc(GroupConnector::dtgcGC); if (!parseGroupConnector(allowDtgc, declInputLevel, groupInputLevel, gc)) return 0; } else vec[0] = new DataTagElementToken(element, templates); ContentToken::OccurrenceIndicator oi = getOccurrenceIndicator(grpMode); result.contentToken = new DataTagGroup(vec, oi); result.type = GroupToken::dataTagGroup; return 1; } Boolean Parser::parseDataTagTemplateGroup(unsigned nestingLevel, unsigned declInputLevel, GroupToken &result) { if (nestingLevel - 1 == syntax().grplvl()) message(ParserMessages::grplvl, NumberMessageArg(syntax().grplvl())); unsigned groupInputLevel = inputLevel(); Vector &vec = result.textVector; for (;;) { GroupToken gt; static AllowedGroupTokens allowDataTagLiteral(GroupToken::dataTagLiteral); if (!parseGroupToken(allowDataTagLiteral, nestingLevel, declInputLevel, groupInputLevel, gt)) return 0; if (vec.size() == syntax().grpcnt()) message(ParserMessages::groupCount, NumberMessageArg(syntax().grpcnt())); vec.resize(vec.size() + 1); gt.text.swap(vec.back()); static AllowedGroupConnectors allowOrGrpc(GroupConnector::orGC, GroupConnector::grpcGC); GroupConnector gc; if (!parseGroupConnector(allowOrGrpc, declInputLevel, groupInputLevel, gc)) return 0; if (gc.type == GroupConnector::grpcGC) break; } return 1; } Boolean Parser::parseModelGroup(unsigned nestingLevel, unsigned declInputLevel, ModelGroup *&group, Mode oiMode) { if (nestingLevel - 1 == syntax().grplvl()) message(ParserMessages::grplvl, NumberMessageArg(syntax().grplvl())); unsigned groupInputLevel = inputLevel(); GroupToken gt; NCVector > tokenVector; GroupConnector::Type connector = GroupConnector::grpcGC; static AllowedGroupTokens allowContentToken(GroupToken::pcdata, GroupToken::dataTagGroup, GroupToken::elementToken, GroupToken::modelGroup); static AllowedGroupConnectors allowAnyConnectorGrpc(GroupConnector::orGC, GroupConnector::andGC, GroupConnector::seqGC, GroupConnector::grpcGC); static AllowedGroupConnectors allowOrGrpc(GroupConnector::orGC, GroupConnector::grpcGC); static AllowedGroupConnectors allowAndGrpc(GroupConnector::andGC, GroupConnector::grpcGC); static AllowedGroupConnectors allowSeqGrpc(GroupConnector::seqGC, GroupConnector::grpcGC); const AllowedGroupConnectors *connectorp = &allowAnyConnectorGrpc; GroupConnector gc; do { if (!parseGroupToken(allowContentToken, nestingLevel, declInputLevel, groupInputLevel, gt)) return 0; ContentToken *contentToken; if (gt.type == GroupToken::modelGroup) contentToken = gt.model.extract(); else contentToken = gt.contentToken.extract(); if (tokenVector.size() == syntax().grpcnt()) message(ParserMessages::groupCount, NumberMessageArg(syntax().grpcnt())); tokenVector.resize(tokenVector.size() + 1); tokenVector.back() = contentToken; if (!parseGroupConnector(*connectorp, declInputLevel, groupInputLevel, gc)) return 0; if (tokenVector.size() == 1) { connector = gc.type; switch (gc.type) { case GroupConnector::orGC: connectorp = &allowOrGrpc; break; case GroupConnector::seqGC: connectorp = &allowSeqGrpc; break; case GroupConnector::andGC: connectorp = &allowAndGrpc; break; default: break; } } } while (gc.type != GroupConnector::grpcGC); ContentToken::OccurrenceIndicator oi = getOccurrenceIndicator(oiMode); switch (connector) { case GroupConnector::orGC: group = new OrModelGroup(tokenVector, oi); break; case GroupConnector::grpcGC: case GroupConnector::seqGC: group = new SeqModelGroup(tokenVector, oi); break; case GroupConnector::andGC: group = new AndModelGroup(tokenVector, oi); break; default: break; } return 1; } ContentToken::OccurrenceIndicator Parser::getOccurrenceIndicator(Mode oiMode) { Token token = getToken(oiMode); switch (token) { case tokenPlus: if (currentMarkup()) currentMarkup()->addDelim(Syntax::dPLUS); return ContentToken::plus; case tokenOpt: if (currentMarkup()) currentMarkup()->addDelim(Syntax::dOPT); return ContentToken::opt; case tokenRep: if (currentMarkup()) currentMarkup()->addDelim(Syntax::dREP); return ContentToken::rep; default: currentInput()->ungetToken(); return ContentToken::none; } } Boolean Parser::parseMinimumLiteral(Boolean lita, Text &text) { return parseLiteral(lita ? mlitaMode : mlitMode, mlitMode, Syntax::referenceQuantity(Syntax::qLITLEN), ParserMessages::minimumLiteralLength, literalSingleSpace|literalMinimumData |(eventsWanted().wantPrologMarkup() ? literalDelimInfo : 0), text); } Boolean Parser::parseSystemIdentifier(Boolean lita, Text &text) { return parseLiteral(lita ? slitaMode : slitMode, slitMode, syntax().litlen(), ParserMessages::systemIdentifierLength, (eventsWanted().wantPrologMarkup() ? literalDelimInfo : 0), text); } Boolean Parser::parseParameterLiteral(Boolean lita, Text &text) { return parseLiteral(lita ? plitaMode : plitMode, pliteMode, syntax().litlen(), ParserMessages::parameterLiteralLength, (eventsWanted().wantPrologMarkup() ? literalDelimInfo : 0), text); } Boolean Parser::parseDataTagParameterLiteral(Boolean lita, Text &text) { return parseLiteral(lita ? plitaMode : plitMode, pliteMode, syntax().dtemplen(), ParserMessages::dataTagPatternLiteralLength, literalDataTag | (eventsWanted().wantPrologMarkup() ? literalDelimInfo : 0), text); } Boolean Parser::parseIndicatedReservedName(const AllowedParams &allow, Param &parm) { Syntax::ReservedName rn; if (!getIndicatedReservedName(&rn)) return 0; if (!allow.reservedName(rn)) { message(ParserMessages::invalidReservedName, StringMessageArg(currentToken())); return 0; } parm.type = Param::indicatedReservedName + rn; return 1; } Boolean Parser::parseReservedName(const AllowedParams &allow, Param &parm) { Syntax::ReservedName rn; if (!getReservedName(&rn)) return 0; if (!allow.reservedName(rn)) { message(ParserMessages::invalidReservedName, StringMessageArg(syntax().reservedName(rn))); return 0; } parm.type = Param::reservedName + rn; return 1; } Boolean Parser::parseAttributeValueParam(Param &parm) { extendNameToken(syntax().litlen() > syntax().normsep() ? syntax().litlen() - syntax().normsep() : 0, ParserMessages::attributeValueLength); parm.type = Param::attributeValue; Text text; text.addChars(currentInput()->currentTokenStart(), currentInput()->currentTokenLength(), currentLocation()); text.swap(parm.literalText); if (currentMarkup()) currentMarkup()->addAttributeValue(currentInput()); return 1; } Boolean Parser::getIndicatedReservedName(Syntax::ReservedName *result) { if (currentMarkup()) currentMarkup()->addDelim(Syntax::dRNI); InputSource *in = currentInput(); in->startToken(); if (!syntax().isNameStartCharacter(in->tokenChar(messenger()))) { message(ParserMessages::rniNameStart); return 0; } extendNameToken(syntax().namelen(), ParserMessages::nameLength); StringC &buffer = nameBuffer(); getCurrentToken(syntax().generalSubstTable(), buffer); if (!syntax().lookupReservedName(buffer, result)) { // Hack, hack if (!options().errorAfdr && buffer == sd().execToDoc("ALL")) *result = Syntax::rANY; else { message(ParserMessages::noSuchReservedName, StringMessageArg(buffer)); return 0; } } if (currentMarkup()) currentMarkup()->addReservedName(*result, currentInput()); return 1; } Boolean Parser::getReservedName(Syntax::ReservedName *result) { extendNameToken(syntax().namelen(), ParserMessages::nameLength); StringC &buffer = nameBuffer(); getCurrentToken(syntax().generalSubstTable(), buffer); if (!syntax().lookupReservedName(buffer, result)) { message(ParserMessages::noSuchReservedName, StringMessageArg(buffer)); return 0; } if (currentMarkup()) currentMarkup()->addReservedName(*result, currentInput()); return 1; } #ifdef SP_NAMESPACE } #endif