📄 parsedecl.cxx
字号:
eventHandler().sSep(new (eventAllocator()) SSepEvent(currentInput()->currentTokenStart(), currentInput()->currentTokenLength(), currentLocation(), 1)); } break; case tokenIgnoredChar: // from an ignored marked section if (eventsWanted().wantPrologMarkup()) eventHandler().ignoredChars(new (eventAllocator()) IgnoredCharsEvent(currentInput()->currentTokenStart(), currentInput()->currentTokenLength(), currentLocation(), 1)); break; case tokenRe: case tokenRs: case tokenCroNameStart: case tokenCroDigit: case tokenHcroHexDigit: case tokenEroNameStart: case tokenEroGrpo: case tokenChar: // these can occur in a cdata or rcdata marked section message(ParserMessages::dataMarkedSectionDeclSubset); declSubsetRecover(startLevel); break; default: CANNOT_HAPPEN(); } } while (eventQueueEmpty());}void Parser::declSubsetRecover(unsigned startLevel){ for (;;) { Token token = getToken(currentMode()); switch (token) { case tokenUnrecognized: (void)getChar(); break; case tokenEe: if (inputLevel() <= startLevel) return; popInputStack(); break; case tokenMdoCom: case tokenDsc: case tokenMdoNameStart: case tokenMdoMdc: case tokenMdoDso: case tokenMscMdc: case tokenPio: if (inputLevel() == startLevel) { currentInput()->ungetToken(); return; } break; default: break; } }}Boolean Parser::lookingAtStartTag(StringC &gi){ // This is harder than might be expected since we may not have compiled // the recognizers for the instance yet. const StringC &stago = instanceSyntax().delimGeneral(Syntax::dSTAGO); for (size_t i = currentInput()->currentTokenLength(); i < stago.size(); i++) if (currentInput()->tokenChar(messenger()) == InputSource::eE) return 0; StringC delim; getCurrentToken(instanceSyntax().generalSubstTable(), delim); if (delim != stago) return 0; Xchar c = currentInput()->tokenChar(messenger()); if (!instanceSyntax().isNameStartCharacter(c)) return 0; do { gi += (*instanceSyntax().generalSubstTable())[(Char)c]; c = currentInput()->tokenChar(messenger()); } while (instanceSyntax().isNameCharacter(c)); return 1;}Boolean Parser::parseDeclarationName(Syntax::ReservedName *result, Boolean allowAfdr){ currentInput()->discardInitial(); extendNameToken(syntax().namelen(), ParserMessages::nameLength); StringC &name = nameBuffer(); getCurrentToken(syntax().generalSubstTable(), name); if (!syntax().lookupReservedName(name, result)) { if (allowAfdr && name == sd().execToInternal("AFDR")) { *result = Syntax::rANY; if (currentMarkup()) currentMarkup()->addName(currentInput()); } else { message(ParserMessages::noSuchDeclarationType, StringMessageArg(name)); return 0; } } else if (currentMarkup()) currentMarkup()->addReservedName(*result, currentInput()); return 1;}Boolean Parser::parseElementDecl(){ unsigned declInputLevel = inputLevel(); Param parm; if (!parseParam(allowNameNameGroup, declInputLevel, parm)) return 0; Vector<NameToken> nameVector; if (parm.type == Param::nameGroup) { parm.nameTokenVector.swap(nameVector); if (options().warnElementGroupDecl) message(ParserMessages::elementGroupDecl); } else { nameVector.resize(1); parm.token.swap(nameVector[0].name); } static AllowedParams allowRankOmissionContent(Param::number, Param::reservedName + Syntax::rO, Param::minus, Param::reservedName + Syntax::rCDATA, Param::reservedName + Syntax::rRCDATA, Param::reservedName + Syntax::rEMPTY, Param::reservedName + Syntax::rANY, Param::modelGroup); if (!parseParam(allowRankOmissionContent, declInputLevel, parm)) return 0; StringC rankSuffix; Vector<ElementType *> elements(nameVector.size()); Vector<RankStem *> rankStems; Vector<const RankStem *> constRankStems; size_t i; if (parm.type == Param::number) { if (options().warnRank) message(ParserMessages::rank); parm.token.swap(rankSuffix); rankStems.resize(nameVector.size()); constRankStems.resize(nameVector.size()); for (i = 0; i < elements.size(); i++) { StringC name(nameVector[i].name); name += rankSuffix; if (name.size() > syntax().namelen() && nameVector[i].name.size() <= syntax().namelen()) message(ParserMessages::genericIdentifierLength, NumberMessageArg(syntax().namelen())); elements[i] = lookupCreateElement(name); rankStems[i] = lookupCreateRankStem(nameVector[i].name); constRankStems[i] = rankStems[i]; } static AllowedParams allowOmissionContent(Param::reservedName + Syntax::rO, Param::minus, Param::reservedName + Syntax::rCDATA, Param::reservedName + Syntax::rRCDATA, Param::reservedName + Syntax::rEMPTY, Param::reservedName + Syntax::rANY, Param::modelGroup); Token token = getToken(mdMinusMode); if (token == tokenNameStart) message(ParserMessages::psRequired); currentInput()->ungetToken(); if (!parseParam(allowOmissionContent, declInputLevel, parm)) return 0; } else { for (i = 0; i < elements.size(); i++) elements[i] = lookupCreateElement(nameVector[i].name); } for (i = 0; i < elements.size(); i++) if (defDtd().lookupRankStem(elements[i]->name()) && validate()) message(ParserMessages::rankStemGenericIdentifier, StringMessageArg(elements[i]->name())); unsigned char omitFlags = 0; if (parm.type == Param::minus || parm.type == Param::reservedName + Syntax::rO) { if (options().warnMinimizationParam) message(ParserMessages::minimizationParam); omitFlags |= ElementDefinition::omitSpec; if (parm.type != Param::minus) omitFlags |= ElementDefinition::omitStart; static AllowedParams allowOmission(Param::reservedName + Syntax::rO, Param::minus); if (!parseParam(allowOmission, declInputLevel, parm)) return 0; if (parm.type != Param::minus) omitFlags |= ElementDefinition::omitEnd; static AllowedParams allowContent(Param::reservedName + Syntax::rCDATA, Param::reservedName + Syntax::rRCDATA, Param::reservedName + Syntax::rEMPTY, Param::reservedName + Syntax::rANY, Param::modelGroup); if (!parseParam(allowContent, declInputLevel, parm)) return 0; } else { if (sd().omittag()) message(ParserMessages::missingTagMinimization); } Ptr<ElementDefinition> def; switch (parm.type) { case Param::reservedName + Syntax::rCDATA: def = new ElementDefinition(markupLocation(), defDtd().allocElementDefinitionIndex(), omitFlags, ElementDefinition::cdata); if (!parseParam(allowMdc, declInputLevel, parm)) return 0; if (options().warnCdataContent) message(ParserMessages::cdataContent); break; case Param::reservedName + Syntax::rRCDATA: def = new ElementDefinition(markupLocation(), defDtd().allocElementDefinitionIndex(), omitFlags, ElementDefinition::rcdata); if (!parseParam(allowMdc, declInputLevel, parm)) return 0; if (options().warnRcdataContent) message(ParserMessages::rcdataContent); break; case Param::reservedName + Syntax::rEMPTY: def = new ElementDefinition(markupLocation(), defDtd().allocElementDefinitionIndex(), omitFlags, ElementDefinition::empty); if ((omitFlags & ElementDefinition::omitSpec) && !(omitFlags & ElementDefinition::omitEnd) && options().warnShould) message(ParserMessages::emptyOmitEndTag); if (!parseParam(allowMdc, declInputLevel, parm)) return 0; break; case Param::reservedName + Syntax::rANY: def = new ElementDefinition(markupLocation(), defDtd().allocElementDefinitionIndex(), omitFlags, ElementDefinition::any); if (!parseExceptions(declInputLevel, def)) return 0; break; case Param::modelGroup: { unsigned long cnt = parm.modelGroupPtr->grpgtcnt(); // The outermost model group isn't formally a content token. if (cnt - 1 > syntax().grpgtcnt()) message(ParserMessages::grpgtcnt, NumberMessageArg(syntax().grpgtcnt())); Owner<CompiledModelGroup> modelGroup(new CompiledModelGroup(parm.modelGroupPtr)); Vector<ContentModelAmbiguity> ambiguities; Boolean pcdataUnreachable; modelGroup->compile(currentDtd().nElementTypeIndex(), ambiguities, pcdataUnreachable); if (pcdataUnreachable && options().warnMixedContent) message(ParserMessages::pcdataUnreachable); if (validate()) { for (i = 0; i < ambiguities.size(); i++) { const ContentModelAmbiguity &a = ambiguities[i]; reportAmbiguity(a.from, a.to1, a.to2, a.andDepth); } } def = new ElementDefinition(markupLocation(), defDtd().allocElementDefinitionIndex(), omitFlags, ElementDefinition::modelGroup, modelGroup); if (!parseExceptions(declInputLevel, def)) return 0; } break; } if (rankSuffix.size() > 0) def->setRank(rankSuffix, constRankStems); ConstPtr<ElementDefinition> constDef(def); for (i = 0; i < elements.size(); i++) { if (elements[i]->definition() != 0) { if (validate()) message(ParserMessages::duplicateElementDefinition, StringMessageArg(elements[i]->name())); } else { elements[i]->setElementDefinition(constDef, i); if (!elements[i]->attributeDef().isNull()) checkElementAttribute(elements[i]); } if (rankStems.size() > 0) rankStems[i]->addDefinition(constDef); } if (currentMarkup()) { Vector<const ElementType *> v(elements.size()); for (i = 0; i < elements.size(); i++) v[i] = elements[i]; eventHandler().elementDecl(new (eventAllocator()) ElementDeclEvent(v, currentDtdPointer(), markupLocation(), currentMarkup())); } return 1;}void Parser::reportAmbiguity(const LeafContentToken *from, const LeafContentToken *to1, const LeafContentToken *to2, unsigned ambigAndDepth){ StringC toName; const ElementType *toType = to1->elementType(); if (toType) toName = toType->name(); else { toName = syntax().delimGeneral(Syntax::dRNI); toName += syntax().reservedName(Syntax::rPCDATA); } unsigned to1Index = to1->typeIndex() + 1; unsigned to2Index = to2->typeIndex() + 1; if (from->isInitial()) message(ParserMessages::ambiguousModelInitial, StringMessageArg(toName), OrdinalMessageArg(to1Index), OrdinalMessageArg(to2Index)); else { StringC fromName; const ElementType *fromType = from->elementType(); if (fromType) fromName = fromType->name(); else { fromName = syntax().delimGeneral(Syntax::dRNI); fromName += syntax().reservedName(Syntax::rPCDATA); } unsigned fromIndex = from->typeIndex() + 1; unsigned andMatches = from->andDepth() - ambigAndDepth; if (andMatches == 0) message(ParserMessages::ambiguousModel, StringMessageArg(fromName), OrdinalMessageArg(fromIndex), StringMessageArg(toName), OrdinalMessageArg(to1Index), OrdinalMessageArg(to2Index)); else if (andMatches == 1) message(ParserMessages::ambiguousModelSingleAnd, StringMessageArg(fromName), OrdinalMessageArg(fromIndex), StringMessageArg(toName), OrdinalMessageArg(to1Index), OrdinalMessageArg(to2Index)); else message(ParserMessages::ambiguousModelMultipleAnd, StringMessageArg(fromName), OrdinalMessageArg(fromIndex), NumberMessageArg(andMatches), StringMessageArg(toName), OrdinalMessageArg(to1Index), OrdinalMessageArg(to2Index)); }}// Check the compatibility of the attribute definition with// the element definition.void Parser::checkElementAttribute(const ElementType *e, size_t checkFrom){ if (!validate()) return; const AttributeDefinitionList *attDef = e->attributeDef().pointer(); Boolean conref = 0; ASSERT(e != 0); const ElementDefinition *edef = e->definition(); ASSERT(edef != 0); ASSERT(attDef != 0); size_t attDefLength = attDef->size(); for (size_t i = checkFrom; i < attDefLength; i++) { const AttributeDefinition *p = attDef->def(i); if (p->isConref()) conref = 1; if (p->isNotation() && edef->declaredContent() == ElementDefinition::empty) message(ParserMessages::notationEmpty, StringMessageArg(e->name())); } if (conref) {#if 0 if (edef->omittedTagSpec() && !edef->canOmitEndTag() && options().warnShould) message(ParserMessages::conrefOmitEndTag, StringMessageArg(e->name()));#endif if (edef->declaredContent() == ElementDefinition::empty) message(ParserMessages::conrefEmpty, StringMessageArg(e->name())); }}ElementType *Parser::lookupCreateElement(const StringC &name){ ElementType *e = defDtd().lookupElementType(name); if (!e) { if (haveDefLpd()) message(ParserMessages::noSuchSourceElement, StringMessageArg(name)); else { e = new ElementType(name, defDtd().allocElementTypeIndex()); defDtd().insertElementType(e); } } return e;}RankStem *Parser::lookupCreateRankStem(const StringC &name){ RankStem *r = defDtd().lookupRankStem(name); if (!r) { r = new RankStem(name, defDtd().nRankStem()); defDtd().insertRankStem(r); const ElementType *e = defDtd().lookupElementType(name); if (e && e->definition() != 0) message(ParserMessages::rankStemGenericIdentifier, StringMessageArg(name));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -