📄 parsedecl.cxx
字号:
Param::mdc); ExternalId id; if (!parseExternalId(allowSystemIdentifierEntityTypeMdc, allowEntityTypeMdc, 1, declInputLevel, parm, id)) return 0; if (parm.type == Param::mdc) { maybeDefineEntity(new ExternalTextEntity(name, declType, markupLocation(), id)); return 1; } Ptr<Entity> entity; if (parm.type == Param::reservedName + Syntax::rSUBDOC) { if (sd().subdoc() == 0) message(ParserMessages::subdocEntity, StringMessageArg(name)); if (!parseParam(allowMdc, declInputLevel, parm)) return 0; entity = new SubdocEntity(name, markupLocation(), id); } else { Entity::DataType dataType; switch (parm.type) { case Param::reservedName + Syntax::rCDATA: dataType = Entity::cdata; if (options().warnExternalCdataEntity) message(ParserMessages::externalCdataEntity); break; case Param::reservedName + Syntax::rSDATA: dataType = Entity::sdata; if (options().warnExternalSdataEntity) message(ParserMessages::externalSdataEntity); break; case Param::reservedName + Syntax::rNDATA: dataType = Entity::ndata; break; default: CANNOT_HAPPEN(); } if (!parseParam(allowName, declInputLevel, parm)) return 0; Ptr<Notation> notation(lookupCreateNotation(parm.token)); if (!parseParam(allowDsoMdc, declInputLevel, parm)) return 0; AttributeList attributes(notation->attributeDef()); if (parm.type == Param::dso) { if (attributes.size() == 0) message(ParserMessages::notationNoAttributes, StringMessageArg(notation->name())); Boolean netEnabling; Ptr<AttributeDefinitionList> newAttDef; if (!parseAttributeSpec(1, attributes, netEnabling, newAttDef)) return 0; if (!newAttDef.isNull()) { newAttDef->setIndex(defDtd().allocAttributeDefinitionListIndex()); notation->setAttributeDef(newAttDef); } if (attributes.nSpec() == 0) message(ParserMessages::emptyDataAttributeSpec); if (!parseParam(allowMdc, declInputLevel, parm)) return 0; } else attributes.finish(*this); entity = new ExternalDataEntity(name, dataType, markupLocation(), id, notation, attributes); } if (declType == Entity::parameterEntity) { message(ParserMessages::externalParameterDataSubdocEntity, StringMessageArg(name)); return 1; } maybeDefineEntity(entity); return 1;}Notation *Parser::lookupCreateNotation(const StringC &name){ Ptr<Notation> nt = defDtd().lookupNotation(name); if (nt.isNull()) { nt = new Notation(name, defDtd().namePointer(), defDtd().isBase()); defDtd().insertNotation(nt); } return nt.pointer();}void Parser::maybeDefineEntity(const Ptr<Entity> &entity){ Dtd &dtd = defDtd(); if (haveDefLpd()) entity->setDeclIn(dtd.namePointer(), dtd.isBase(), defLpd().namePointer(), defLpd().active()); else entity->setDeclIn(dtd.namePointer(), dtd.isBase()); Boolean ignored = 0; if (entity->name().size() == 0) { const Entity *oldEntity = dtd.defaultEntity().pointer(); if (oldEntity == 0 || (!oldEntity->declInActiveLpd() && entity->declInActiveLpd())) dtd.setDefaultEntity(entity, *this); else { ignored = 1; if (options().warnDuplicateEntity) message(ParserMessages::duplicateEntityDeclaration, StringMessageArg(syntax().rniReservedName(Syntax::rDEFAULT))); } } else { Ptr<Entity> oldEntity = dtd.insertEntity(entity); if (oldEntity.isNull()) entity->generateSystemId(*this); else if (oldEntity->defaulted()) { dtd.insertEntity(entity, 1); message(ParserMessages::defaultedEntityDefined, StringMessageArg(entity->name())); entity->generateSystemId(*this); } else { if (entity->declInActiveLpd() && !oldEntity->declInActiveLpd()) { dtd.insertEntity(entity, 1); entity->generateSystemId(*this); } else { ignored = 1; if (options().warnDuplicateEntity) message(entity->declType() == Entity::parameterEntity ? ParserMessages::duplicateParameterEntityDeclaration : ParserMessages::duplicateEntityDeclaration, StringMessageArg(entity->name())); } } } if (currentMarkup()) eventHandler().entityDecl(new (eventAllocator()) EntityDeclEvent(entity, ignored, markupLocation(), currentMarkup()));}Boolean Parser::parseShortrefDecl(){ if (!defDtd().isBase()) message(ParserMessages::shortrefOnlyInBaseDtd); unsigned declInputLevel = inputLevel(); Param parm; if (!parseParam(allowName, declInputLevel, parm)) return 0; ShortReferenceMap *map = lookupCreateMap(parm.token); int valid = 1; if (map->defined()) { message(ParserMessages::duplicateShortrefDeclaration, StringMessageArg(parm.token), map->defLocation()); valid = 0; } else map->setDefLocation(markupLocation()); if (!parseParam(allowParamLiteral, declInputLevel, parm)) return 0; Vector<StringC> vec; do { StringC delim(parm.literalText.string()); const SubstTable<Char> *table = instanceSyntax().generalSubstTable(); for (size_t i = 0; i < delim.size(); i++) table->subst(delim[i]); size_t srIndex; if (!defDtd().shortrefIndex(delim, instanceSyntax(), srIndex)) { message(ParserMessages::unknownShortrefDelim, StringMessageArg(prettifyDelim(delim))); valid = 0; } static AllowedParams allowEntityName(Param::entityName); if (!parseParam(allowEntityName, declInputLevel, parm)) return 0; if (valid) { if (srIndex >= vec.size()) vec.resize(srIndex + 1); if (vec[srIndex].size() > 0) { message(ParserMessages::delimDuplicateMap, StringMessageArg(prettifyDelim(delim))); valid = 0; } else parm.token.swap(vec[srIndex]); } static AllowedParams allowParamLiteralMdc(Param::paramLiteral, Param::mdc); if (!parseParam(allowParamLiteralMdc, declInputLevel, parm)) return 0; } while (parm.type != Param::mdc); if (valid) { map->setNameMap(vec); if (currentMarkup()) eventHandler().shortrefDecl(new (eventAllocator()) ShortrefDeclEvent(map, currentDtdPointer(), markupLocation(), currentMarkup())); } return 1;}StringC Parser::prettifyDelim(const StringC &delim){ StringC prettyDelim; for (size_t i = 0; i < delim.size(); i++) { const StringC *nameP; if (syntax().charFunctionName(delim[i], nameP)) { prettyDelim += syntax().delimGeneral(Syntax::dCRO); prettyDelim += *nameP; prettyDelim += syntax().delimGeneral(Syntax::dREFC); } else prettyDelim += delim[i]; } return prettyDelim;}ShortReferenceMap *Parser::lookupCreateMap(const StringC &name){ ShortReferenceMap *map = defDtd().lookupShortReferenceMap(name); if (!map) { map = new ShortReferenceMap(name); defDtd().insertShortReferenceMap(map); } return map;}Boolean Parser::parseUsemapDecl(){ if (!inInstance() && !defDtd().isBase()) message(ParserMessages::usemapOnlyInBaseDtd); unsigned declInputLevel = inputLevel(); Param parm; static AllowedParams allowNameEmpty(Param::name, Param::indicatedReservedName + Syntax::rEMPTY); if (!parseParam(allowNameEmpty, declInputLevel, parm)) return 0; const ShortReferenceMap *map; if (parm.type == Param::name) { if (inInstance()) { map = currentDtd().lookupShortReferenceMap(parm.token); if (!map) message(ParserMessages::undefinedShortrefMapInstance, StringMessageArg(parm.token)); } else { ShortReferenceMap *tem = lookupCreateMap(parm.token); tem->setUsed(); map = tem; } } else map = &theEmptyMap; static AllowedParams allowNameNameGroupMdc(Param::name, Param::nameGroup, Param::mdc); if (!parseParam(allowNameNameGroupMdc, declInputLevel, parm)) return 0; if (parm.type != Param::mdc) { if (inInstance()) { message(ParserMessages::usemapAssociatedElementTypeInstance); if (!parseParam(allowMdc, declInputLevel, parm)) return 0; } else { Vector<const ElementType *> v; if (parm.type == Param::name) { ElementType *e = lookupCreateElement(parm.token); v.push_back(e); if (!e->map()) e->setMap(map); } else { v.resize(parm.nameTokenVector.size()); for (size_t i = 0; i < parm.nameTokenVector.size(); i++) { ElementType *e = lookupCreateElement(parm.nameTokenVector[i].name); v[i] = e; if (!e->map()) e->setMap(map); } } if (!parseParam(allowMdc, declInputLevel, parm)) return 0; if (currentMarkup()) eventHandler().usemap(new (eventAllocator()) UsemapEvent(map, v, currentDtdPointer(), markupLocation(), currentMarkup())); } } else { if (!inInstance()) message(ParserMessages::usemapAssociatedElementTypeDtd); else if (map) { if (map != &theEmptyMap && !map->defined()) message(ParserMessages::undefinedShortrefMapInstance, StringMessageArg(map->name())); else { if (currentMarkup()) { Vector<const ElementType *> v; eventHandler().usemap(new (eventAllocator()) UsemapEvent(map, v, currentDtdPointer(), markupLocation(), currentMarkup())); } currentElement().setMap(map); } } } return 1;}Boolean Parser::parseDoctypeDeclStart(){ if (hadDtd() && !sd().concur() && !sd().explicitLink()) message(ParserMessages::multipleDtds); if (hadLpd()) message(ParserMessages::dtdAfterLpd); unsigned declInputLevel = inputLevel(); Param parm; if (!parseParam(allowName, declInputLevel, parm)) return 0; StringC name; parm.token.swap(name); if (!lookupDtd(name).isNull()) message(ParserMessages::duplicateDtd, StringMessageArg(name)); static AllowedParams allowPublicSystemDsoMdc(Param::reservedName + Syntax::rPUBLIC, Param::reservedName + Syntax::rSYSTEM, Param::dso, Param::mdc); if (!parseParam(allowPublicSystemDsoMdc, declInputLevel, parm)) return 0; ConstPtr<Entity> entity; if (parm.type == Param::reservedName + Syntax::rPUBLIC || parm.type == Param::reservedName + Syntax::rSYSTEM) { static AllowedParams allowSystemIdentifierDsoMdc(Param::systemIdentifier, Param::dso, Param::mdc); ExternalId id; if (!parseExternalId(allowSystemIdentifierDsoMdc, allowDsoMdc, 1, declInputLevel, parm, id)) return 0; Ptr<Entity> tem = new ExternalTextEntity(name, Entity::doctype, markupLocation(), id); tem->generateSystemId(*this); entity = tem;#if 0 eventHandler() .externalEntityDecl(new (eventAllocator()) ExternalEntityDeclEvent(entity, 0));#endif } else if (parm.type == Param::mdc) { if (!sd().implydefElement()) { message(ParserMessages::noDtdSubset); enableImplydef(); } } // Discard mdc or dso if (currentMarkup()) currentMarkup()->resize(currentMarkup()->size() - 1); eventHandler().startDtd(new (eventAllocator()) StartDtdEvent(name, entity, parm.type == Param::dso, markupLocation(), currentMarkup())); startDtd(name); if (parm.type == Param::mdc) { // unget the mdc currentInput()->ungetToken(); if (entity.isNull()) { (void)parseDoctypeDeclEnd(); return 1; } // reference the entity Ptr<EntityOrigin> origin = EntityOrigin::make(internalAllocator(), entity, currentLocation()); entity->dsReference(*this, origin); if (inputLevel() == 1) { // reference failed (void)parseDoctypeDeclEnd(); return 1; } } else if (!entity.isNull()) setDsEntity(entity); setPhase(declSubsetPhase); return 1;}void Parser::implyDtd(const StringC &gi){ startMarkup(eventsWanted().wantPrologMarkup(), Location());#if 0 if (currentMarkup()) { currentMarkup()->addDelim(Syntax::dMDO); currentMarkup()->addReservedName(Syntax::rDOCTYPE, syntax().reservedName(Syntax::rDOCTYPE)); currentMarkup()->addS(syntax().space()); currentMarkup()->addName(gi.data(), gi.size()); }#endif if (sd().implydefElement() && !sd().implydefDoctype()) { eventHandler().startDtd(new (eventAllocator()) StartDtdEvent(gi, ConstPtr<Entity>(), 0, markupLocation(), currentMarkup())); startDtd(gi); parseDoctypeDeclEnd(1); return; } ExternalId id; // The null location indicates that this is a fake entity. Entity *tem = new ExternalTextEntity(gi, Entity::doctype, Location(), id); ConstPtr<Entity> entity(te
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -