|
Packit |
8a864e |
// Copyright (c) 1994 James Clark
|
|
Packit |
8a864e |
// See the file COPYING for copying permission.
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
#include "splib.h"
|
|
Packit |
8a864e |
#include "Parser.h"
|
|
Packit |
8a864e |
#include "Param.h"
|
|
Packit |
8a864e |
#include "Group.h"
|
|
Packit |
8a864e |
#include "Markup.h"
|
|
Packit |
8a864e |
#include "ParserMessages.h"
|
|
Packit |
8a864e |
#include "MessageArg.h"
|
|
Packit |
8a864e |
#include "TokenMessageArg.h"
|
|
Packit |
8a864e |
#include "token.h"
|
|
Packit |
8a864e |
#include "macros.h"
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
#ifdef SP_NAMESPACE
|
|
Packit |
8a864e |
namespace SP_NAMESPACE {
|
|
Packit |
8a864e |
#endif
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
Boolean Parser::parseParam(const AllowedParams &allow,
|
|
Packit |
8a864e |
unsigned declInputLevel,
|
|
Packit |
8a864e |
Param &parm)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
for (;;) {
|
|
Packit |
8a864e |
Token token = getToken(allow.mainMode());
|
|
Packit |
8a864e |
switch (token) {
|
|
Packit |
8a864e |
case tokenUnrecognized:
|
|
Packit |
8a864e |
if (reportNonSgmlCharacter())
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
message(ParserMessages::markupDeclarationCharacter,
|
|
Packit |
8a864e |
StringMessageArg(currentToken()),
|
|
Packit |
8a864e |
AllowedParamsMessageArg(allow, syntaxPointer()));
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
case tokenEe:
|
|
Packit |
8a864e |
if (inputLevel() <= declInputLevel) {
|
|
Packit |
8a864e |
message(ParserMessages::declarationLevel);
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
if (currentMarkup())
|
|
Packit |
8a864e |
currentMarkup()->addEntityEnd();
|
|
Packit |
8a864e |
popInputStack();
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
case tokenCom:
|
|
Packit |
8a864e |
if (!parseComment(comMode))
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
if (options().warnPsComment)
|
|
Packit |
8a864e |
message(ParserMessages::psComment);
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
case tokenDso:
|
|
Packit |
8a864e |
if (!allow.dso()) {
|
|
Packit |
8a864e |
paramInvalidToken(tokenDso, allow);
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
if (currentMarkup())
|
|
Packit |
8a864e |
currentMarkup()->addDelim(Syntax::dDSO);
|
|
Packit |
8a864e |
parm.type = Param::dso;
|
|
Packit |
8a864e |
return 1;
|
|
Packit |
8a864e |
case tokenGrpo:
|
|
Packit |
8a864e |
if (currentMarkup())
|
|
Packit |
8a864e |
currentMarkup()->addDelim(Syntax::dGRPO);
|
|
Packit |
8a864e |
switch (allow.group()) {
|
|
Packit |
8a864e |
case Param::invalid:
|
|
Packit |
8a864e |
paramInvalidToken(tokenGrpo, allow);
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
case Param::modelGroup:
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
ModelGroup *group;
|
|
Packit |
8a864e |
if (!parseModelGroup(1, declInputLevel, group, grpsufMode))
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
parm.type = Param::modelGroup;
|
|
Packit |
8a864e |
parm.modelGroupPtr = group;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
case Param::nameGroup:
|
|
Packit |
8a864e |
if (!parseNameGroup(declInputLevel, parm))
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
case Param::nameTokenGroup:
|
|
Packit |
8a864e |
if (!parseNameTokenGroup(declInputLevel, parm))
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
default:
|
|
Packit |
8a864e |
CANNOT_HAPPEN();
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
parm.type = allow.group();
|
|
Packit |
8a864e |
return 1;
|
|
Packit |
8a864e |
case tokenLita:
|
|
Packit |
8a864e |
case tokenLit:
|
|
Packit |
8a864e |
parm.type = allow.literal();
|
|
Packit |
8a864e |
parm.lita = token == tokenLita;
|
|
Packit |
8a864e |
switch (allow.literal()) {
|
|
Packit |
8a864e |
case Param::invalid:
|
|
Packit |
8a864e |
paramInvalidToken(token, allow);
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
case Param::minimumLiteral:
|
|
Packit |
8a864e |
if (!parseMinimumLiteral(parm.lita, parm.literalText))
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
case Param::attributeValueLiteral:
|
|
Packit |
8a864e |
if (!parseAttributeValueLiteral(parm.lita, parm.literalText))
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
case Param::tokenizedAttributeValueLiteral:
|
|
Packit |
8a864e |
if (!parseTokenizedAttributeValueLiteral(parm.lita, parm.literalText))
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
case Param::systemIdentifier:
|
|
Packit |
8a864e |
if (!parseSystemIdentifier(parm.lita, parm.literalText))
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
case Param::paramLiteral:
|
|
Packit |
8a864e |
if (!parseParameterLiteral(parm.lita, parm.literalText))
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
if (currentMarkup())
|
|
Packit |
8a864e |
currentMarkup()->addLiteral(parm.literalText);
|
|
Packit |
8a864e |
return 1;
|
|
Packit |
8a864e |
case tokenMdc:
|
|
Packit |
8a864e |
if (!allow.mdc()) {
|
|
Packit |
8a864e |
paramInvalidToken(tokenMdc, allow);
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
if (inputLevel() > declInputLevel)
|
|
Packit |
8a864e |
message(ParserMessages::parameterEntityNotEnded);
|
|
Packit |
8a864e |
if (currentMarkup())
|
|
Packit |
8a864e |
currentMarkup()->addDelim(Syntax::dMDC);
|
|
Packit |
8a864e |
parm.type = Param::mdc;
|
|
Packit |
8a864e |
return 1;
|
|
Packit |
8a864e |
case tokenMinus:
|
|
Packit |
8a864e |
parm.type = Param::minus;
|
|
Packit |
8a864e |
if (currentMarkup())
|
|
Packit |
8a864e |
currentMarkup()->addDelim(Syntax::dMINUS);
|
|
Packit |
8a864e |
return 1;
|
|
Packit |
8a864e |
case tokenMinusGrpo:
|
|
Packit |
8a864e |
if (!allow.exclusions()) {
|
|
Packit |
8a864e |
paramInvalidToken(tokenMinusGrpo, allow);
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
if (currentMarkup()) {
|
|
Packit |
8a864e |
currentMarkup()->addDelim(Syntax::dMINUS);
|
|
Packit |
8a864e |
currentMarkup()->addDelim(Syntax::dGRPO);
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
parm.type = Param::exclusions;
|
|
Packit |
8a864e |
return parseElementNameGroup(declInputLevel, parm);
|
|
Packit |
8a864e |
case tokenPero:
|
|
Packit |
8a864e |
parm.type = Param::pero;
|
|
Packit |
8a864e |
if (currentMarkup())
|
|
Packit |
8a864e |
currentMarkup()->addDelim(Syntax::dPERO);
|
|
Packit |
8a864e |
return 1;
|
|
Packit |
8a864e |
case tokenPeroGrpo:
|
|
Packit |
8a864e |
if (!inInstance())
|
|
Packit |
8a864e |
message(ParserMessages::peroGrpoProlog);
|
|
Packit |
8a864e |
// fall through
|
|
Packit |
8a864e |
case tokenPeroNameStart:
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
if (inInstance()) {
|
|
Packit |
8a864e |
if (options().warnInstanceParamEntityRef)
|
|
Packit |
8a864e |
message(ParserMessages::instanceParamEntityRef);
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
else {
|
|
Packit |
8a864e |
if (options().warnInternalSubsetPsParamEntityRef && inputLevel() == 1)
|
|
Packit |
8a864e |
message(ParserMessages::internalSubsetPsParamEntityRef);
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
ConstPtr<Entity> entity;
|
|
Packit |
8a864e |
Ptr<EntityOrigin> origin;
|
|
Packit |
8a864e |
if (!parseEntityReference(1, token == tokenPeroGrpo, entity, origin))
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
if (!entity.isNull())
|
|
Packit |
8a864e |
entity->declReference(*this, origin);
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
case tokenPlusGrpo:
|
|
Packit |
8a864e |
if (!allow.inclusions()) {
|
|
Packit |
8a864e |
paramInvalidToken(tokenPlusGrpo, allow);
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
if (currentMarkup()) {
|
|
Packit |
8a864e |
currentMarkup()->addDelim(Syntax::dPLUS);
|
|
Packit |
8a864e |
currentMarkup()->addDelim(Syntax::dGRPO);
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
parm.type = Param::inclusions;
|
|
Packit |
8a864e |
return parseElementNameGroup(declInputLevel, parm);
|
|
Packit |
8a864e |
case tokenRni:
|
|
Packit |
8a864e |
if (!allow.rni()) {
|
|
Packit |
8a864e |
paramInvalidToken(tokenRni, allow);
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
return parseIndicatedReservedName(allow, parm);
|
|
Packit |
8a864e |
case tokenS:
|
|
Packit |
8a864e |
if (currentMarkup())
|
|
Packit |
8a864e |
currentMarkup()->addS(currentChar());
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
case tokenNameStart:
|
|
Packit |
8a864e |
switch (allow.nameStart()) {
|
|
Packit |
8a864e |
case Param::invalid:
|
|
Packit |
8a864e |
paramInvalidToken(tokenNameStart, allow);
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
case Param::reservedName:
|
|
Packit |
8a864e |
return parseReservedName(allow, parm);
|
|
Packit |
8a864e |
case Param::name:
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
extendNameToken(syntax().namelen(), ParserMessages::nameLength);
|
|
Packit |
8a864e |
parm.type = Param::name;
|
|
Packit |
8a864e |
getCurrentToken(parm.origToken);
|
|
Packit |
8a864e |
parm.token = StringC(parm.origToken);
|
|
Packit |
8a864e |
const SubstTable *subst = syntax().generalSubstTable();
|
|
Packit |
8a864e |
StringC::iterator s = parm.token.begin();
|
|
Packit |
8a864e |
size_t count = parm.token.size();
|
|
Packit |
8a864e |
const Char *tokenData = parm.token.data();
|
|
Packit |
8a864e |
for (; count > 0; --count)
|
|
Packit |
8a864e |
*s++ = (*subst)[*tokenData++];
|
|
Packit |
8a864e |
if (currentMarkup())
|
|
Packit |
8a864e |
currentMarkup()->addName(currentInput());
|
|
Packit |
8a864e |
return 1;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
case Param::entityName:
|
|
Packit |
8a864e |
extendNameToken(syntax().namelen(), ParserMessages::nameLength);
|
|
Packit |
8a864e |
parm.type = Param::entityName;
|
|
Packit |
8a864e |
getCurrentToken(syntax().entitySubstTable(), parm.token);
|
|
Packit |
8a864e |
if (currentMarkup())
|
|
Packit |
8a864e |
currentMarkup()->addName(currentInput());
|
|
Packit |
8a864e |
return 1;
|
|
Packit |
8a864e |
case Param::paramEntityName:
|
|
Packit |
8a864e |
extendNameToken(syntax().penamelen(),
|
|
Packit |
8a864e |
ParserMessages::parameterEntityNameLength);
|
|
Packit |
8a864e |
parm.type = Param::paramEntityName;
|
|
Packit |
8a864e |
getCurrentToken(syntax().entitySubstTable(), parm.token);
|
|
Packit |
8a864e |
if (currentMarkup())
|
|
Packit |
8a864e |
currentMarkup()->addName(currentInput());
|
|
Packit |
8a864e |
return 1;
|
|
Packit |
8a864e |
case Param::attributeValue:
|
|
Packit |
8a864e |
return parseAttributeValueParam(parm);
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
case tokenDigit:
|
|
Packit |
8a864e |
switch (allow.digit()) {
|
|
Packit |
8a864e |
case Param::invalid:
|
|
Packit |
8a864e |
paramInvalidToken(tokenDigit, allow);
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
case Param::number:
|
|
Packit |
8a864e |
extendNumber(syntax().namelen(), ParserMessages::numberLength);
|
|
Packit |
8a864e |
parm.type = Param::number;
|
|
Packit |
8a864e |
getCurrentToken(parm.token);
|
|
Packit |
8a864e |
if (currentMarkup())
|
|
Packit |
8a864e |
currentMarkup()->addNumber(currentInput());
|
|
Packit |
8a864e |
return 1;
|
|
Packit |
8a864e |
case Param::attributeValue:
|
|
Packit |
8a864e |
return parseAttributeValueParam(parm);
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
case tokenLcUcNmchar:
|
|
Packit |
8a864e |
switch (allow.nmchar()) {
|
|
Packit |
8a864e |
case Param::invalid:
|
|
Packit |
8a864e |
paramInvalidToken(tokenLcUcNmchar, allow);
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
case Param::attributeValue:
|
|
Packit |
8a864e |
return parseAttributeValueParam(parm);
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
default:
|
|
Packit |
8a864e |
CANNOT_HAPPEN();
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
void Parser::paramInvalidToken(Token token, const AllowedParams &allow)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
if (!allow.silent())
|
|
Packit |
8a864e |
message(ParserMessages::paramInvalidToken,
|
|
Packit |
8a864e |
TokenMessageArg(token, allow.mainMode(),
|
|
Packit |
8a864e |
syntaxPointer(), sdPointer()),
|
|
Packit |
8a864e |
AllowedParamsMessageArg(allow, syntaxPointer()));
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
Boolean Parser::parseGroupToken(const AllowedGroupTokens &allow,
|
|
Packit |
8a864e |
unsigned nestingLevel,
|
|
Packit |
8a864e |
unsigned declInputLevel,
|
|
Packit |
8a864e |
unsigned groupInputLevel,
|
|
Packit |
8a864e |
GroupToken >)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
for (;;) {
|
|
Packit |
8a864e |
Token token = getToken(grpMode);
|
|
Packit |
8a864e |
switch (token) {
|
|
Packit |
8a864e |
case tokenEe:
|
|
Packit |
8a864e |
if (inputLevel() <= groupInputLevel) {
|
|
Packit |
8a864e |
message(ParserMessages::groupLevel);
|
|
Packit |
8a864e |
if (inputLevel() <= declInputLevel)
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
else if (!sd().www())
|
|
Packit |
8a864e |
message(ParserMessages::groupEntityEnd);
|
|
Packit |
8a864e |
if (currentMarkup())
|
|
Packit |
8a864e |
currentMarkup()->addEntityEnd();
|
|
Packit |
8a864e |
popInputStack();
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
case tokenPeroGrpo:
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
if (!inInstance())
|
|
Packit |
8a864e |
message(ParserMessages::peroGrpoProlog);
|
|
Packit |
8a864e |
Boolean start;
|
|
Packit |
8a864e |
if (inTag(start))
|
|
Packit |
8a864e |
message(start
|
|
Packit |
8a864e |
? ParserMessages::peroGrpoStartTag
|
|
Packit |
8a864e |
: ParserMessages::peroGrpoEndTag);
|
|
Packit |
8a864e |
// fall through
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
case tokenPeroNameStart:
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
if (options().warnInternalSubsetTsParamEntityRef && inputLevel() == 1)
|
|
Packit |
8a864e |
message(ParserMessages::internalSubsetTsParamEntityRef);
|
|
Packit |
8a864e |
ConstPtr<Entity> entity;
|
|
Packit |
8a864e |
Ptr<EntityOrigin> origin;
|
|
Packit |
8a864e |
if (!parseEntityReference(1, token == tokenPeroGrpo, entity, origin))
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
if (!entity.isNull())
|
|
Packit |
8a864e |
entity->declReference(*this, origin);
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
case tokenUnrecognized:
|
|
Packit |
8a864e |
if (reportNonSgmlCharacter())
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
message(ParserMessages::groupCharacter,
|
|
Packit |
8a864e |
StringMessageArg(currentToken()),
|
|
Packit |
8a864e |
AllowedGroupTokensMessageArg(allow, syntaxPointer()));
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
case tokenDtgo:
|
|
Packit |
8a864e |
if (!allow.groupToken(GroupToken::dataTagGroup)) {
|
|
Packit |
8a864e |
groupTokenInvalidToken(tokenDtgo, allow);
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
if (sd().datatag())
|
|
Packit |
8a864e |
message(ParserMessages::datatagNotImplemented);
|
|
Packit |
8a864e |
if (!defDtd().isBase())
|
|
Packit |
8a864e |
message(ParserMessages::datatagBaseDtd);
|
|
Packit |
8a864e |
if (currentMarkup())
|
|
Packit |
8a864e |
currentMarkup()->addDelim(Syntax::dDTGO);
|
|
Packit |
8a864e |
return parseDataTagGroup(nestingLevel + 1, declInputLevel, gt);
|
|
Packit |
8a864e |
case tokenGrpo:
|
|
Packit |
8a864e |
if (currentMarkup())
|
|
Packit |
8a864e |
currentMarkup()->addDelim(Syntax::dGRPO);
|
|
Packit |
8a864e |
switch (allow.group()) {
|
|
Packit |
8a864e |
case GroupToken::modelGroup:
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
ModelGroup *modelGroup;
|
|
Packit |
8a864e |
if (!parseModelGroup(nestingLevel + 1, declInputLevel, modelGroup,
|
|
Packit |
8a864e |
grpMode))
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
gt.model = modelGroup;
|
|
Packit |
8a864e |
gt.type = GroupToken::modelGroup;
|
|
Packit |
8a864e |
return 1;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
case GroupToken::dataTagTemplateGroup:
|
|
Packit |
8a864e |
return parseDataTagTemplateGroup(nestingLevel + 1, declInputLevel, gt);
|
|
Packit |
8a864e |
default:
|
|
Packit |
8a864e |
groupTokenInvalidToken(tokenGrpo, allow);
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
case tokenRni:
|
|
Packit |
8a864e |
if (!allow.groupToken(GroupToken::pcdata)
|
|
Packit |
8a864e |
&& !allow.groupToken(GroupToken::all)
|
|
Packit |
8a864e |
&& !allow.groupToken(GroupToken::implicit)) {
|
|
Packit |
8a864e |
groupTokenInvalidToken(tokenRni, allow);
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
Syntax::ReservedName rn;
|
|
Packit |
8a864e |
if (!getIndicatedReservedName(&rn))
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
if (rn == Syntax::rPCDATA && allow.groupToken(GroupToken::pcdata)) {
|
|
Packit |
8a864e |
gt.type = GroupToken::pcdata;
|
|
Packit |
8a864e |
gt.contentToken = new PcdataToken;
|
|
Packit |
8a864e |
return 1;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
else if (rn == Syntax::rALL && allow.groupToken(GroupToken::all)) {
|
|
Packit |
8a864e |
message(ParserMessages::sorryAllImplicit);
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
else if (rn == Syntax::rIMPLICIT && allow.groupToken(GroupToken::implicit)) {
|
|
Packit |
8a864e |
message(ParserMessages::sorryAllImplicit);
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
else {
|
|
Packit |
8a864e |
StringC token(syntax().delimGeneral(Syntax::dRNI));
|
|
Packit |
8a864e |
token += syntax().reservedName(rn);
|
|
Packit |
8a864e |
message(ParserMessages::invalidToken, StringMessageArg(token));
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
case tokenS:
|
|
Packit |
8a864e |
if (currentMarkup()) {
|
|
Packit |
8a864e |
extendS();
|
|
Packit |
8a864e |
currentMarkup()->addS(currentInput());
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
case tokenNameStart:
|
|
Packit |
8a864e |
switch (allow.nameStart()) {
|
|
Packit |
8a864e |
case GroupToken::elementToken:
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
extendNameToken(syntax().namelen(), ParserMessages::nameLength);
|
|
Packit |
8a864e |
gt.type = GroupToken::elementToken;
|
|
Packit |
8a864e |
StringC &buffer = nameBuffer();
|
|
Packit |
8a864e |
getCurrentToken(syntax().generalSubstTable(), buffer);
|
|
Packit |
8a864e |
if (currentMarkup())
|
|
Packit |
8a864e |
currentMarkup()->addName(currentInput());
|
|
Packit |
8a864e |
const ElementType *e = lookupCreateElement(buffer);
|
|
Packit |
8a864e |
ContentToken::OccurrenceIndicator oi
|
|
Packit |
8a864e |
= getOccurrenceIndicator(grpMode);
|
|
Packit |
8a864e |
gt.contentToken = new ElementToken(e, oi);
|
|
Packit |
8a864e |
return 1;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
case GroupToken::name:
|
|
Packit |
8a864e |
case GroupToken::nameToken:
|
|
Packit |
8a864e |
extendNameToken(syntax().namelen(),
|
|
Packit |
8a864e |
token == GroupToken::name
|
|
Packit |
8a864e |
? ParserMessages::nameLength
|
|
Packit |
8a864e |
: ParserMessages::nameTokenLength);
|
|
Packit |
8a864e |
getCurrentToken(syntax().generalSubstTable(), gt.token);
|
|
Packit |
8a864e |
gt.type = allow.nameStart();
|
|
Packit |
8a864e |
if (currentMarkup()) {
|
|
Packit |
8a864e |
if (gt.type == GroupToken::nameToken)
|
|
Packit |
8a864e |
currentMarkup()->addNameToken(currentInput());
|
|
Packit |
8a864e |
else
|
|
Packit |
8a864e |
currentMarkup()->addName(currentInput());
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
return 1;
|
|
Packit |
8a864e |
default:
|
|
Packit |
8a864e |
groupTokenInvalidToken(tokenNameStart, allow);
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
case tokenDigit:
|
|
Packit |
8a864e |
case tokenLcUcNmchar:
|
|
Packit |
8a864e |
if (!allow.groupToken(GroupToken::nameToken)) {
|
|
Packit |
8a864e |
groupTokenInvalidToken(token, allow);
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
extendNameToken(syntax().namelen(), ParserMessages::nameTokenLength);
|
|
Packit |
8a864e |
getCurrentToken(syntax().generalSubstTable(), gt.token);
|
|
Packit |
8a864e |
gt.type = GroupToken::nameToken;
|
|
Packit |
8a864e |
if (currentMarkup())
|
|
Packit |
8a864e |
currentMarkup()->addNameToken(currentInput());
|
|
Packit |
8a864e |
return 1;
|
|
Packit |
8a864e |
case tokenLit:
|
|
Packit |
8a864e |
case tokenLita:
|
|
Packit |
8a864e |
// parameter literal in data tag pattern
|
|
Packit |
8a864e |
if (!allow.groupToken(GroupToken::dataTagLiteral)) {
|
|
Packit |
8a864e |
groupTokenInvalidToken(token, allow);
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
if (!parseDataTagParameterLiteral(token == tokenLita, gt.text))
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
gt.type = GroupToken::dataTagLiteral;
|
|
Packit |
8a864e |
if (currentMarkup())
|
|
Packit |
8a864e |
currentMarkup()->addLiteral(gt.text);
|
|
Packit |
8a864e |
return 1;
|
|
Packit |
8a864e |
case tokenAnd:
|
|
Packit |
8a864e |
case tokenSeq:
|
|
Packit |
8a864e |
case tokenOr:
|
|
Packit |
8a864e |
case tokenDtgc:
|
|
Packit |
8a864e |
case tokenGrpc:
|
|
Packit |
8a864e |
case tokenOpt:
|
|
Packit |
8a864e |
case tokenPlus:
|
|
Packit |
8a864e |
case tokenRep:
|
|
Packit |
8a864e |
groupTokenInvalidToken(token, allow);
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
void Parser::groupTokenInvalidToken(Token token, const AllowedGroupTokens &allow)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
message(ParserMessages::groupTokenInvalidToken,
|
|
Packit |
8a864e |
TokenMessageArg(token, grpMode, syntaxPointer(), sdPointer()),
|
|
Packit |
8a864e |
AllowedGroupTokensMessageArg(allow, syntaxPointer()));
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
Boolean Parser::parseGroupConnector(const AllowedGroupConnectors &allow,
|
|
Packit |
8a864e |
unsigned declInputLevel,
|
|
Packit |
8a864e |
unsigned groupInputLevel,
|
|
Packit |
8a864e |
GroupConnector &gc)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
for (;;) {
|
|
Packit |
8a864e |
Token token = getToken(grpMode);
|
|
Packit |
8a864e |
switch (token) {
|
|
Packit |
8a864e |
case tokenEe:
|
|
Packit |
8a864e |
if (inputLevel() <= groupInputLevel) {
|
|
Packit |
8a864e |
message(ParserMessages::groupLevel);
|
|
Packit |
8a864e |
if (inputLevel() <= declInputLevel)
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
if (currentMarkup())
|
|
Packit |
8a864e |
currentMarkup()->addEntityEnd();
|
|
Packit |
8a864e |
popInputStack();
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
case tokenS:
|
|
Packit |
8a864e |
if (currentMarkup()) {
|
|
Packit |
8a864e |
extendS();
|
|
Packit |
8a864e |
currentMarkup()->addS(currentInput());
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
case tokenPeroGrpo:
|
|
Packit |
8a864e |
if (inInstance()) {
|
|
Packit |
8a864e |
message(ParserMessages::peroGrpoProlog);
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
// fall through
|
|
Packit |
8a864e |
case tokenPeroNameStart:
|
|
Packit |
8a864e |
if (!sd().www())
|
|
Packit |
8a864e |
message(ParserMessages::groupEntityReference);
|
|
Packit |
8a864e |
else {
|
|
Packit |
8a864e |
ConstPtr<Entity> entity;
|
|
Packit |
8a864e |
Ptr<EntityOrigin> origin;
|
|
Packit |
8a864e |
if (!parseEntityReference(1, token == tokenPeroGrpo, entity, origin))
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
if (!entity.isNull())
|
|
Packit |
8a864e |
entity->declReference(*this, origin);
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
case tokenUnrecognized:
|
|
Packit |
8a864e |
if (reportNonSgmlCharacter())
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
message(ParserMessages::groupCharacter,
|
|
Packit |
8a864e |
StringMessageArg(currentToken()),
|
|
Packit |
8a864e |
AllowedGroupConnectorsMessageArg(allow, syntaxPointer()));
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
case tokenAnd:
|
|
Packit |
8a864e |
if (!allow.groupConnector(GroupConnector::andGC)) {
|
|
Packit |
8a864e |
groupConnectorInvalidToken(tokenAnd, allow);
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
gc.type = GroupConnector::andGC;
|
|
Packit |
8a864e |
if (currentMarkup())
|
|
Packit |
8a864e |
currentMarkup()->addDelim(Syntax::dAND);
|
|
Packit |
8a864e |
return 1;
|
|
Packit |
8a864e |
case tokenSeq:
|
|
Packit |
8a864e |
if (!allow.groupConnector(GroupConnector::seqGC)) {
|
|
Packit |
8a864e |
groupConnectorInvalidToken(tokenSeq, allow);
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
gc.type = GroupConnector::seqGC;
|
|
Packit |
8a864e |
if (currentMarkup())
|
|
Packit |
8a864e |
currentMarkup()->addDelim(Syntax::dSEQ);
|
|
Packit |
8a864e |
return 1;
|
|
Packit |
8a864e |
case tokenOr:
|
|
Packit |
8a864e |
if (!allow.groupConnector(GroupConnector::orGC)) {
|
|
Packit |
8a864e |
groupConnectorInvalidToken(tokenOr, allow);
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
gc.type = GroupConnector::orGC;
|
|
Packit |
8a864e |
if (currentMarkup())
|
|
Packit |
8a864e |
currentMarkup()->addDelim(Syntax::dOR);
|
|
Packit |
8a864e |
return 1;
|
|
Packit |
8a864e |
case tokenDtgc:
|
|
Packit |
8a864e |
if (!allow.groupConnector(GroupConnector::dtgcGC)) {
|
|
Packit |
8a864e |
groupConnectorInvalidToken(tokenDtgc, allow);
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
gc.type = GroupConnector::dtgcGC;
|
|
Packit |
8a864e |
if (inputLevel() > groupInputLevel)
|
|
Packit |
8a864e |
message(ParserMessages::groupParameterEntityNotEnded);
|
|
Packit |
8a864e |
if (currentMarkup())
|
|
Packit |
8a864e |
currentMarkup()->addDelim(Syntax::dDTGC);
|
|
Packit |
8a864e |
return 1;
|
|
Packit |
8a864e |
case tokenGrpc:
|
|
Packit |
8a864e |
if (!allow.groupConnector(GroupConnector::grpcGC)) {
|
|
Packit |
8a864e |
groupConnectorInvalidToken(tokenGrpc, allow);
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
gc.type = GroupConnector::grpcGC;
|
|
Packit |
8a864e |
if (inputLevel() > groupInputLevel)
|
|
Packit |
8a864e |
message(ParserMessages::groupParameterEntityNotEnded);
|
|
Packit |
8a864e |
if (currentMarkup())
|
|
Packit |
8a864e |
currentMarkup()->addDelim(Syntax::dGRPC);
|
|
Packit |
8a864e |
return 1;
|
|
Packit |
8a864e |
default:
|
|
Packit |
8a864e |
groupConnectorInvalidToken(token, allow);
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
void Parser::groupConnectorInvalidToken(Token token,
|
|
Packit |
8a864e |
const AllowedGroupConnectors &allow)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
message(ParserMessages::connectorInvalidToken,
|
|
Packit |
8a864e |
TokenMessageArg(token, grpMode, syntaxPointer(), sdPointer()),
|
|
Packit |
8a864e |
AllowedGroupConnectorsMessageArg(allow, syntaxPointer()));
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
static AllowedGroupTokens allowName(GroupToken::name);
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
Boolean Parser::parseElementNameGroup(unsigned declInputLevel, Param &parm)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
static AllowedGroupTokens allowCommonName(GroupToken::name,
|
|
Packit |
8a864e |
GroupToken::all,
|
|
Packit |
8a864e |
GroupToken::implicit);
|
|
Packit |
8a864e |
if (!parseGroup(sd().www() ? allowCommonName : allowName, declInputLevel, parm))
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
parm.elementVector.resize(parm.nameTokenVector.size());
|
|
Packit |
8a864e |
for (size_t i = 0; i < parm.nameTokenVector.size(); i++)
|
|
Packit |
8a864e |
parm.elementVector[i] = lookupCreateElement(parm.nameTokenVector[i].name);
|
|
Packit |
8a864e |
return 1;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
Boolean Parser::parseEntityReferenceNameGroup(Boolean &ignore)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
Param parm;
|
|
Packit |
8a864e |
if (!parseNameGroup(inputLevel(), parm))
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
if (inInstance()) {
|
|
Packit |
8a864e |
for (size_t i = 0; i < parm.nameTokenVector.size(); i++) {
|
|
Packit |
8a864e |
const Lpd *lpd = lookupLpd(parm.nameTokenVector[i].name).pointer();
|
|
Packit |
8a864e |
if (lpd && lpd->active()) {
|
|
Packit |
8a864e |
ignore = 0;
|
|
Packit |
8a864e |
return 1;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
Ptr<Dtd> dtd = lookupDtd(parm.nameTokenVector[i].name).pointer();
|
|
Packit |
8a864e |
if (!dtd.isNull()) {
|
|
Packit |
8a864e |
instantiateDtd(dtd);
|
|
Packit |
8a864e |
if (currentDtdPointer() == dtd) {
|
|
Packit |
8a864e |
ignore = 0;
|
|
Packit |
8a864e |
return 1;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
ignore = 1;
|
|
Packit |
8a864e |
return 1;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
Boolean Parser::parseTagNameGroup(Boolean &active, Boolean start)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
Param parm;
|
|
Packit |
8a864e |
enterTag(start);
|
|
Packit |
8a864e |
Boolean ret = parseNameGroup(inputLevel(), parm);
|
|
Packit |
8a864e |
leaveTag();
|
|
Packit |
8a864e |
if (!ret)
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
active = 0;
|
|
Packit |
8a864e |
for (size_t i = 0; i < parm.nameTokenVector.size(); i++) {
|
|
Packit |
8a864e |
Ptr<Dtd> dtd = lookupDtd(parm.nameTokenVector[i].name).pointer();
|
|
Packit |
8a864e |
if (!dtd.isNull()) {
|
|
Packit |
8a864e |
instantiateDtd(dtd);
|
|
Packit |
8a864e |
if (currentDtdPointer() == dtd)
|
|
Packit |
8a864e |
active = 1;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
return 1;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
Boolean Parser::parseNameGroup(unsigned declInputLevel, Param &parm)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
return parseGroup(allowName, declInputLevel, parm);
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
Boolean Parser::parseNameTokenGroup(unsigned declInputLevel, Param &parm)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
static AllowedGroupTokens allowNameToken(GroupToken::nameToken);
|
|
Packit |
8a864e |
return parseGroup(allowNameToken, declInputLevel, parm);
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
static
|
|
Packit |
8a864e |
Boolean groupContains(const Vector<NameToken> &vec, const StringC &str)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
for (size_t i = 0; i < vec.size(); i++)
|
|
Packit |
8a864e |
if (vec[i].name == str)
|
|
Packit |
8a864e |
return 1;
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
Boolean Parser::parseGroup(const AllowedGroupTokens &allowToken,
|
|
Packit |
8a864e |
unsigned declInputLevel,
|
|
Packit |
8a864e |
Param &parm)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
unsigned groupInputLevel = inputLevel();
|
|
Packit |
8a864e |
int nDuplicates = 0;
|
|
Packit |
8a864e |
Vector<NameToken> &vec = parm.nameTokenVector;
|
|
Packit |
8a864e |
vec.clear();
|
|
Packit |
8a864e |
GroupConnector::Type connector = GroupConnector::grpcGC;
|
|
Packit |
8a864e |
GroupToken gt;
|
|
Packit |
8a864e |
for (;;) {
|
|
Packit |
8a864e |
if (!parseGroupToken(allowToken, 0, declInputLevel, groupInputLevel, gt))
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
if (groupContains(vec, gt.token)) {
|
|
Packit |
8a864e |
nDuplicates++;
|
|
Packit |
8a864e |
message(ParserMessages::duplicateGroupToken,
|
|
Packit |
8a864e |
StringMessageArg(gt.token));
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
else {
|
|
Packit |
8a864e |
vec.resize(vec.size() + 1);
|
|
Packit |
8a864e |
gt.token.swap(vec.back().name);
|
|
Packit |
8a864e |
getCurrentToken(vec.back().origName);
|
|
Packit |
8a864e |
vec.back().loc = currentLocation();
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
GroupConnector gc;
|
|
Packit |
8a864e |
static AllowedGroupConnectors allowAnyConnectorGrpc(GroupConnector::orGC,
|
|
Packit |
8a864e |
GroupConnector::andGC,
|
|
Packit |
8a864e |
GroupConnector::seqGC,
|
|
Packit |
8a864e |
GroupConnector::grpcGC);
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
if (!parseGroupConnector(allowAnyConnectorGrpc, declInputLevel,
|
|
Packit |
8a864e |
groupInputLevel, gc))
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
if (gc.type == GroupConnector::grpcGC)
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
if (options().warnNameGroupNotOr) {
|
|
Packit |
8a864e |
if (gc.type != GroupConnector::orGC)
|
|
Packit |
8a864e |
message(ParserMessages::nameGroupNotOr);
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
else if (options().warnShould) {
|
|
Packit |
8a864e |
if (connector == GroupConnector::grpcGC)
|
|
Packit |
8a864e |
connector = gc.type;
|
|
Packit |
8a864e |
else if (gc.type != connector) {
|
|
Packit |
8a864e |
message(ParserMessages::mixedConnectors);
|
|
Packit |
8a864e |
connector = gc.type;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
if (nDuplicates + vec.size() > syntax().grpcnt())
|
|
Packit |
8a864e |
message(ParserMessages::groupCount, NumberMessageArg(syntax().grpcnt()));
|
|
Packit |
8a864e |
return 1;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
Boolean Parser::parseDataTagGroup(unsigned nestingLevel,
|
|
Packit |
8a864e |
unsigned declInputLevel, GroupToken &result)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
if (nestingLevel - 1 == syntax().grplvl())
|
|
Packit |
8a864e |
message(ParserMessages::grplvl, NumberMessageArg(syntax().grplvl()));
|
|
Packit |
8a864e |
unsigned groupInputLevel = inputLevel();
|
|
Packit |
8a864e |
GroupToken gt;
|
|
Packit |
8a864e |
static AllowedGroupTokens allowName(GroupToken::name);
|
|
Packit |
8a864e |
if (!parseGroupToken(allowName, nestingLevel, declInputLevel,
|
|
Packit |
8a864e |
groupInputLevel, gt))
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
const ElementType *element = lookupCreateElement(gt.token);
|
|
Packit |
8a864e |
GroupConnector gc;
|
|
Packit |
8a864e |
static AllowedGroupConnectors allowSeq(GroupConnector::seqGC);
|
|
Packit |
8a864e |
if (!parseGroupConnector(allowSeq, declInputLevel, groupInputLevel, gc))
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
static AllowedGroupTokens
|
|
Packit |
8a864e |
allowDataTagLiteralDataTagTemplateGroup(GroupToken::dataTagLiteral,
|
|
Packit |
8a864e |
GroupToken::dataTagTemplateGroup);
|
|
Packit |
8a864e |
if (!parseGroupToken(allowDataTagLiteralDataTagTemplateGroup,
|
|
Packit |
8a864e |
nestingLevel,
|
|
Packit |
8a864e |
declInputLevel,
|
|
Packit |
8a864e |
groupInputLevel,
|
|
Packit |
8a864e |
gt))
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
Vector<Text> templates;
|
|
Packit |
8a864e |
if (gt.type == GroupToken::dataTagTemplateGroup)
|
|
Packit |
8a864e |
gt.textVector.swap(templates);
|
|
Packit |
8a864e |
else {
|
|
Packit |
8a864e |
templates.resize(1);
|
|
Packit |
8a864e |
gt.text.swap(templates[0]);
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
static AllowedGroupConnectors allowSeqDtgc(GroupConnector::seqGC,
|
|
Packit |
8a864e |
GroupConnector::dtgcGC);
|
|
Packit |
8a864e |
if (!parseGroupConnector(allowSeqDtgc, declInputLevel, groupInputLevel, gc))
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
NCVector<Owner<ContentToken> > vec(2);
|
|
Packit |
8a864e |
vec[1] = new PcdataToken;
|
|
Packit |
8a864e |
if (gc.type != GroupConnector::dtgcGC) {
|
|
Packit |
8a864e |
static AllowedGroupTokens allowDataTagLiteral(GroupToken::dataTagLiteral);
|
|
Packit |
8a864e |
if (!parseGroupToken(allowDataTagLiteral,
|
|
Packit |
8a864e |
nestingLevel,
|
|
Packit |
8a864e |
declInputLevel,
|
|
Packit |
8a864e |
groupInputLevel,
|
|
Packit |
8a864e |
gt))
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
vec[0] = new DataTagElementToken(element, templates, gt.text);
|
|
Packit |
8a864e |
static AllowedGroupConnectors allowDtgc(GroupConnector::dtgcGC);
|
|
Packit |
8a864e |
if (!parseGroupConnector(allowDtgc, declInputLevel, groupInputLevel, gc))
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
else
|
|
Packit |
8a864e |
vec[0] = new DataTagElementToken(element, templates);
|
|
Packit |
8a864e |
ContentToken::OccurrenceIndicator oi = getOccurrenceIndicator(grpMode);
|
|
Packit |
8a864e |
result.contentToken = new DataTagGroup(vec, oi);
|
|
Packit |
8a864e |
result.type = GroupToken::dataTagGroup;
|
|
Packit |
8a864e |
return 1;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
Boolean Parser::parseDataTagTemplateGroup(unsigned nestingLevel,
|
|
Packit |
8a864e |
unsigned declInputLevel,
|
|
Packit |
8a864e |
GroupToken &result)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
if (nestingLevel - 1 == syntax().grplvl())
|
|
Packit |
8a864e |
message(ParserMessages::grplvl, NumberMessageArg(syntax().grplvl()));
|
|
Packit |
8a864e |
unsigned groupInputLevel = inputLevel();
|
|
Packit |
8a864e |
Vector<Text> &vec = result.textVector;
|
|
Packit |
8a864e |
for (;;) {
|
|
Packit |
8a864e |
GroupToken gt;
|
|
Packit |
8a864e |
static AllowedGroupTokens allowDataTagLiteral(GroupToken::dataTagLiteral);
|
|
Packit |
8a864e |
if (!parseGroupToken(allowDataTagLiteral,
|
|
Packit |
8a864e |
nestingLevel,
|
|
Packit |
8a864e |
declInputLevel,
|
|
Packit |
8a864e |
groupInputLevel,
|
|
Packit |
8a864e |
gt))
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
if (vec.size() == syntax().grpcnt())
|
|
Packit |
8a864e |
message(ParserMessages::groupCount, NumberMessageArg(syntax().grpcnt()));
|
|
Packit |
8a864e |
vec.resize(vec.size() + 1);
|
|
Packit |
8a864e |
gt.text.swap(vec.back());
|
|
Packit |
8a864e |
static AllowedGroupConnectors allowOrGrpc(GroupConnector::orGC,
|
|
Packit |
8a864e |
GroupConnector::grpcGC);
|
|
Packit |
8a864e |
GroupConnector gc;
|
|
Packit |
8a864e |
if (!parseGroupConnector(allowOrGrpc, declInputLevel, groupInputLevel, gc))
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
if (gc.type == GroupConnector::grpcGC)
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
return 1;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
Boolean Parser::parseModelGroup(unsigned nestingLevel, unsigned declInputLevel,
|
|
Packit |
8a864e |
ModelGroup *&group, Mode oiMode)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
if (nestingLevel - 1 == syntax().grplvl())
|
|
Packit |
8a864e |
message(ParserMessages::grplvl, NumberMessageArg(syntax().grplvl()));
|
|
Packit |
8a864e |
unsigned groupInputLevel = inputLevel();
|
|
Packit |
8a864e |
GroupToken gt;
|
|
Packit |
8a864e |
NCVector<Owner<ContentToken> > tokenVector;
|
|
Packit |
8a864e |
GroupConnector::Type connector = GroupConnector::grpcGC;
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
static AllowedGroupTokens allowContentToken(GroupToken::pcdata,
|
|
Packit |
8a864e |
GroupToken::dataTagGroup,
|
|
Packit |
8a864e |
GroupToken::elementToken,
|
|
Packit |
8a864e |
GroupToken::modelGroup);
|
|
Packit |
8a864e |
static AllowedGroupTokens allowCommonContentToken(GroupToken::pcdata,
|
|
Packit |
8a864e |
GroupToken::all,
|
|
Packit |
8a864e |
GroupToken::implicit,
|
|
Packit |
8a864e |
GroupToken::dataTagGroup,
|
|
Packit |
8a864e |
GroupToken::elementToken,
|
|
Packit |
8a864e |
GroupToken::modelGroup);
|
|
Packit |
8a864e |
static AllowedGroupConnectors allowAnyConnectorGrpc(GroupConnector::orGC,
|
|
Packit |
8a864e |
GroupConnector::andGC,
|
|
Packit |
8a864e |
GroupConnector::seqGC,
|
|
Packit |
8a864e |
GroupConnector::grpcGC);
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
static AllowedGroupConnectors allowOrGrpc(GroupConnector::orGC,
|
|
Packit |
8a864e |
GroupConnector::grpcGC);
|
|
Packit |
8a864e |
static AllowedGroupConnectors allowAndGrpc(GroupConnector::andGC,
|
|
Packit |
8a864e |
GroupConnector::grpcGC);
|
|
Packit |
8a864e |
static AllowedGroupConnectors allowSeqGrpc(GroupConnector::seqGC,
|
|
Packit |
8a864e |
GroupConnector::grpcGC);
|
|
Packit |
8a864e |
const AllowedGroupConnectors *connectorp = &allowAnyConnectorGrpc;
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
GroupConnector gc;
|
|
Packit |
8a864e |
Boolean pcdataCheck = 0;
|
|
Packit |
8a864e |
do {
|
|
Packit |
8a864e |
if (!parseGroupToken(sd().www() ? allowCommonContentToken
|
|
Packit |
8a864e |
: allowContentToken,
|
|
Packit |
8a864e |
nestingLevel, declInputLevel, groupInputLevel, gt))
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
ContentToken *contentToken;
|
|
Packit |
8a864e |
if (gt.type == GroupToken::modelGroup)
|
|
Packit |
8a864e |
contentToken = gt.model.extract();
|
|
Packit |
8a864e |
else
|
|
Packit |
8a864e |
contentToken = gt.contentToken.extract();
|
|
Packit |
8a864e |
if (tokenVector.size() == syntax().grpcnt())
|
|
Packit |
8a864e |
message(ParserMessages::groupCount, NumberMessageArg(syntax().grpcnt()));
|
|
Packit |
8a864e |
tokenVector.resize(tokenVector.size() + 1);
|
|
Packit |
8a864e |
tokenVector.back() = contentToken;
|
|
Packit |
8a864e |
if (!parseGroupConnector(*connectorp, declInputLevel, groupInputLevel, gc))
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
if (options().warnMixedContentRepOrGroup && gt.type == GroupToken::pcdata) {
|
|
Packit |
8a864e |
if (tokenVector.size() != 1)
|
|
Packit |
8a864e |
message(ParserMessages::pcdataNotFirstInGroup);
|
|
Packit |
8a864e |
else if (gc.type == GroupConnector::seqGC)
|
|
Packit |
8a864e |
message(ParserMessages::pcdataInSeqGroup);
|
|
Packit |
8a864e |
else
|
|
Packit |
8a864e |
pcdataCheck = 1;
|
|
Packit |
8a864e |
if (nestingLevel != 1)
|
|
Packit |
8a864e |
message(ParserMessages::pcdataInNestedModelGroup);
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
else if (pcdataCheck) {
|
|
Packit |
8a864e |
if (gt.type == GroupToken::modelGroup)
|
|
Packit |
8a864e |
message(ParserMessages::pcdataGroupMemberModelGroup);
|
|
Packit |
8a864e |
if (contentToken->occurrenceIndicator() != ContentToken::none)
|
|
Packit |
8a864e |
message(ParserMessages::pcdataGroupMemberOccurrenceIndicator);
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
if (tokenVector.size() == 1) {
|
|
Packit |
8a864e |
connector = gc.type;
|
|
Packit |
8a864e |
switch (gc.type) {
|
|
Packit |
8a864e |
case GroupConnector::orGC:
|
|
Packit |
8a864e |
connectorp = &allowOrGrpc;
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
case GroupConnector::seqGC:
|
|
Packit |
8a864e |
connectorp = &allowSeqGrpc;
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
case GroupConnector::andGC:
|
|
Packit |
8a864e |
connectorp = &allowAndGrpc;
|
|
Packit |
8a864e |
if (options().warnAndGroup)
|
|
Packit |
8a864e |
message(ParserMessages::andGroup);
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
default:
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
} while (gc.type != GroupConnector::grpcGC);
|
|
Packit |
8a864e |
ContentToken::OccurrenceIndicator oi
|
|
Packit |
8a864e |
= getOccurrenceIndicator(oiMode);
|
|
Packit |
8a864e |
switch (connector) {
|
|
Packit |
8a864e |
case GroupConnector::orGC:
|
|
Packit |
8a864e |
group = new OrModelGroup(tokenVector, oi);
|
|
Packit |
8a864e |
if (pcdataCheck && oi != ContentToken::rep)
|
|
Packit |
8a864e |
message(ParserMessages::pcdataGroupNotRep);
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
case GroupConnector::grpcGC:
|
|
Packit |
8a864e |
if (pcdataCheck && oi != ContentToken::rep && oi != ContentToken::none)
|
|
Packit |
8a864e |
message(ParserMessages::pcdataGroupNotRep);
|
|
Packit |
8a864e |
// fall through
|
|
Packit |
8a864e |
case GroupConnector::seqGC:
|
|
Packit |
8a864e |
group = new SeqModelGroup(tokenVector, oi);
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
case GroupConnector::andGC:
|
|
Packit |
8a864e |
group = new AndModelGroup(tokenVector, oi);
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
default:
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
return 1;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
ContentToken::OccurrenceIndicator
|
|
Packit |
8a864e |
Parser::getOccurrenceIndicator(Mode oiMode)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
Token token = getToken(oiMode);
|
|
Packit |
8a864e |
switch (token) {
|
|
Packit |
8a864e |
case tokenPlus:
|
|
Packit |
8a864e |
if (currentMarkup())
|
|
Packit |
8a864e |
currentMarkup()->addDelim(Syntax::dPLUS);
|
|
Packit |
8a864e |
return ContentToken::plus;
|
|
Packit |
8a864e |
case tokenOpt:
|
|
Packit |
8a864e |
if (currentMarkup())
|
|
Packit |
8a864e |
currentMarkup()->addDelim(Syntax::dOPT);
|
|
Packit |
8a864e |
return ContentToken::opt;
|
|
Packit |
8a864e |
case tokenRep:
|
|
Packit |
8a864e |
if (currentMarkup())
|
|
Packit |
8a864e |
currentMarkup()->addDelim(Syntax::dREP);
|
|
Packit |
8a864e |
return ContentToken::rep;
|
|
Packit |
8a864e |
default:
|
|
Packit |
8a864e |
currentInput()->ungetToken();
|
|
Packit |
8a864e |
return ContentToken::none;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
Boolean Parser::parseMinimumLiteral(Boolean lita, Text &text)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
return parseLiteral(lita ? mlitaMode : mlitMode, mlitMode,
|
|
Packit |
8a864e |
Syntax::referenceQuantity(Syntax::qLITLEN),
|
|
Packit |
8a864e |
ParserMessages::minimumLiteralLength,
|
|
Packit |
8a864e |
literalSingleSpace|literalMinimumData
|
|
Packit |
8a864e |
|(eventsWanted().wantPrologMarkup()
|
|
Packit |
8a864e |
? literalDelimInfo
|
|
Packit |
8a864e |
: 0),
|
|
Packit |
8a864e |
text);
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
Boolean Parser::parseSystemIdentifier(Boolean lita, Text &text)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
return parseLiteral(lita ? slitaMode : slitMode, slitMode, syntax().litlen(),
|
|
Packit |
8a864e |
ParserMessages::systemIdentifierLength,
|
|
Packit |
8a864e |
(eventsWanted().wantPrologMarkup()
|
|
Packit |
8a864e |
? literalDelimInfo
|
|
Packit |
8a864e |
: 0), text);
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
Boolean Parser::parseParameterLiteral(Boolean lita, Text &text)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
return parseLiteral(lita ? plitaMode : plitMode, pliteMode, syntax().litlen(),
|
|
Packit |
8a864e |
ParserMessages::parameterLiteralLength,
|
|
Packit |
8a864e |
(eventsWanted().wantPrologMarkup()
|
|
Packit |
8a864e |
? literalDelimInfo
|
|
Packit |
8a864e |
: 0),
|
|
Packit |
8a864e |
text);
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
Boolean Parser::parseDataTagParameterLiteral(Boolean lita, Text &text)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
return parseLiteral(lita ? plitaMode : plitMode, pliteMode,
|
|
Packit |
8a864e |
syntax().dtemplen(),
|
|
Packit |
8a864e |
ParserMessages::dataTagPatternLiteralLength,
|
|
Packit |
8a864e |
literalDataTag
|
|
Packit |
8a864e |
| (eventsWanted().wantPrologMarkup()
|
|
Packit |
8a864e |
? literalDelimInfo
|
|
Packit |
8a864e |
: 0),
|
|
Packit |
8a864e |
text);
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
Boolean Parser::parseIndicatedReservedName(const AllowedParams &allow,
|
|
Packit |
8a864e |
Param &parm)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
Syntax::ReservedName rn;
|
|
Packit |
8a864e |
if (!getIndicatedReservedName(&rn))
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
if (!allow.reservedName(rn)) {
|
|
Packit |
8a864e |
message(ParserMessages::invalidReservedName,
|
|
Packit |
8a864e |
StringMessageArg(currentToken()));
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
parm.type = Param::indicatedReservedName + rn;
|
|
Packit |
8a864e |
return 1;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
Boolean Parser::parseReservedName(const AllowedParams &allow,
|
|
Packit |
8a864e |
Param &parm)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
Syntax::ReservedName rn;
|
|
Packit |
8a864e |
if (!getReservedName(&rn))
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
if (!allow.reservedName(rn)) {
|
|
Packit |
8a864e |
message(ParserMessages::invalidReservedName,
|
|
Packit |
8a864e |
StringMessageArg(syntax().reservedName(rn)));
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
parm.type = Param::reservedName + rn;
|
|
Packit |
8a864e |
return 1;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
Boolean Parser::parseAttributeValueParam(Param &parm)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
extendNameToken(syntax().litlen() > syntax().normsep()
|
|
Packit |
8a864e |
? syntax().litlen() - syntax().normsep()
|
|
Packit |
8a864e |
: 0,
|
|
Packit |
8a864e |
ParserMessages::attributeValueLength);
|
|
Packit |
8a864e |
parm.type = Param::attributeValue;
|
|
Packit |
8a864e |
Text text;
|
|
Packit |
8a864e |
text.addChars(currentInput()->currentTokenStart(),
|
|
Packit |
8a864e |
currentInput()->currentTokenLength(),
|
|
Packit |
8a864e |
currentLocation());
|
|
Packit |
8a864e |
text.swap(parm.literalText);
|
|
Packit |
8a864e |
if (currentMarkup())
|
|
Packit |
8a864e |
currentMarkup()->addAttributeValue(currentInput());
|
|
Packit |
8a864e |
return 1;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
Boolean Parser::getIndicatedReservedName(Syntax::ReservedName *result)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
if (currentMarkup())
|
|
Packit |
8a864e |
currentMarkup()->addDelim(Syntax::dRNI);
|
|
Packit |
8a864e |
InputSource *in = currentInput();
|
|
Packit |
8a864e |
in->startToken();
|
|
Packit |
8a864e |
if (!syntax().isNameStartCharacter(in->tokenChar(messenger()))) {
|
|
Packit |
8a864e |
message(ParserMessages::rniNameStart);
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
extendNameToken(syntax().namelen(), ParserMessages::nameLength);
|
|
Packit |
8a864e |
StringC &buffer = nameBuffer();
|
|
Packit |
8a864e |
getCurrentToken(syntax().generalSubstTable(), buffer);
|
|
Packit |
8a864e |
if (!syntax().lookupReservedName(buffer, result)) {
|
|
Packit |
8a864e |
message(ParserMessages::noSuchReservedName, StringMessageArg(buffer));
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
if (currentMarkup())
|
|
Packit |
8a864e |
currentMarkup()->addReservedName(*result, currentInput());
|
|
Packit |
8a864e |
return 1;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
Boolean Parser::getReservedName(Syntax::ReservedName *result)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
extendNameToken(syntax().namelen(), ParserMessages::nameLength);
|
|
Packit |
8a864e |
StringC &buffer = nameBuffer();
|
|
Packit |
8a864e |
getCurrentToken(syntax().generalSubstTable(), buffer);
|
|
Packit |
8a864e |
if (!syntax().lookupReservedName(buffer, result)) {
|
|
Packit |
8a864e |
message(ParserMessages::noSuchReservedName, StringMessageArg(buffer));
|
|
Packit |
8a864e |
return 0;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
if (currentMarkup())
|
|
Packit |
8a864e |
currentMarkup()->addReservedName(*result, currentInput());
|
|
Packit |
8a864e |
return 1;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
#ifdef SP_NAMESPACE
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
#endif
|