📄 parsesd.cxx
字号:
} } if (!checkNmchars(set, *sdBuilder.syntax)) sdBuilder.valid = 0; } while (!isNamechar++); ISet<WideChar> bad; intersectCharSets(nameStartChar, nameChar, bad); if (!bad.isEmpty()) { sdBuilder.valid = 0; message(ParserMessages::nmcharNmstrt, CharsetMessageArg(bad)); } sdBuilder.syntax->addNameStartCharacters(nameStartChar); sdBuilder.syntax->addNameCharacters(nameChar); if (!parseSdParam(AllowedSdParams(SdParam::reservedName + Sd::rGENERAL), parm)) return 0; if (!parseSdParam(AllowedSdParams(SdParam::reservedName + Sd::rNO, SdParam::reservedName + Sd::rYES), parm)) return 0; sdBuilder.syntax->setNamecaseGeneral(parm.type == SdParam::reservedName + Sd::rYES); if (!parseSdParam(AllowedSdParams(SdParam::reservedName + Sd::rENTITY), parm)) return 0; if (!parseSdParam(AllowedSdParams(SdParam::reservedName + Sd::rNO, SdParam::reservedName + Sd::rYES), parm)) return 0; sdBuilder.syntax->setNamecaseEntity(parm.type == SdParam::reservedName + Sd::rYES); return 1;}Boolean Parser::checkNmchars(const ISet<Char> &set, const Syntax &syntax){ Boolean valid = 1; ISet<WideChar> bad; intersectCharSets(set, *syntax.charSet(Syntax::nameStart), bad); if (!bad.isEmpty()) { message(ParserMessages::nmcharLetter, CharsetMessageArg(bad)); valid = 0; bad.clear(); } intersectCharSets(set, *syntax.charSet(Syntax::digit), bad); if (!bad.isEmpty()) { message(ParserMessages::nmcharDigit, CharsetMessageArg(bad)); valid = 0; bad.clear(); } Char funChar; if (syntax.getStandardFunction(Syntax::fRE, funChar) && set.contains(funChar)) { message(ParserMessages::nmcharRe, NumberMessageArg(funChar)); valid = 0; } if (syntax.getStandardFunction(Syntax::fRS, funChar) && set.contains(funChar)) { message(ParserMessages::nmcharRs, NumberMessageArg(funChar)); valid = 0; } if (syntax.getStandardFunction(Syntax::fSPACE, funChar) && set.contains(funChar)) { message(ParserMessages::nmcharSpace, NumberMessageArg(funChar)); valid = 0; } intersectCharSets(set, *syntax.charSet(Syntax::sepchar), bad); if (!bad.isEmpty()) { message(ParserMessages::nmcharSepchar, CharsetMessageArg(bad)); valid = 0; } return valid;}// Result is a ISet<WideChar>, so it can be used with CharsetMessageArg.void Parser::intersectCharSets(const ISet<Char> &s1, const ISet<Char> &s2, ISet<WideChar> &inter){ ISetIter<Char> i1(s1); ISetIter<Char> i2(s2); Char min1, max1, min2, max2; if (!i1.next(min1, max1)) return; if (!i2.next(min2, max2)) return; for (;;) { if (max1 < min2) { if (!i1.next(min1, max1)) break; } else if (max2 < min1) { if (!i2.next(min2, max2)) break; } else { // min2 <= max1 // min1 <= max2 Char min = min1 > min2 ? min1 : min2; Char max = max1 < max2 ? max1 : max2; inter.addRange(min, max); if (max2 > max) { if (!i1.next(min1, max1)) break; } else { if (!i2.next(min2, max2)) break; } } }}Boolean Parser::sdParseDelim(SdBuilder &sdBuilder, SdParam &parm){ if (!parseSdParam(AllowedSdParams(SdParam::reservedName + Sd::rDELIM), parm)) return 0; if (!parseSdParam(AllowedSdParams(SdParam::reservedName + Sd::rGENERAL), parm)) return 0; if (!parseSdParam(AllowedSdParams(SdParam::reservedName + Sd::rSGMLREF), parm)) return 0; PackedBoolean delimGeneralSpecified[Syntax::nDelimGeneral]; for (int i = 0; i < Syntax::nDelimGeneral; i++) delimGeneralSpecified[i] = 0; for (;;) { if (!parseSdParam(AllowedSdParams(SdParam::generalDelimiterName, SdParam::reservedName + Sd::rSHORTREF), parm)) return 0; if (parm.type == SdParam::reservedName + Sd::rSHORTREF) break; Syntax::DelimGeneral delimGeneral = parm.delimGeneralIndex; if (delimGeneralSpecified[delimGeneral]) message(ParserMessages::duplicateDelimGeneral, StringMessageArg(sd().generalDelimiterName(delimGeneral))); switch (delimGeneral) { case Syntax::dHCRO: case Syntax::dNESTC: requireWWW(sdBuilder); break; default: break; } if (!parseSdParam(sdBuilder.externalSyntax ? AllowedSdParams(SdParam::paramLiteral, SdParam::number) : AllowedSdParams(SdParam::paramLiteral), parm)) return 0; sdParamConvertToLiteral(parm); StringC str; if (parm.paramLiteralText.size() == 0) message(ParserMessages::sdEmptyDelimiter); else if (translateSyntax(sdBuilder, parm.paramLiteralText, str)) { const SubstTable<Char> *table = sdBuilder.syntax->generalSubstTable(); for (size_t i = 0; i < str.size(); i++) table->subst(str[i]); if (checkGeneralDelim(*sdBuilder.syntax, str) && !delimGeneralSpecified[delimGeneral]) sdBuilder.syntax->setDelimGeneral(delimGeneral, str); else sdBuilder.valid = 0; } delimGeneralSpecified[delimGeneral] = 1; } if (sdBuilder.syntax->delimGeneral(Syntax::dNET).size() && !sdBuilder.syntax->delimGeneral(Syntax::dNESTC).size()) sdBuilder.syntax->setDelimGeneral(Syntax::dNESTC, sdBuilder.syntax->delimGeneral(Syntax::dNET)); if (!setRefDelimGeneral(*sdBuilder.syntax, sdBuilder.syntaxCharset, sdBuilder.sd->internalCharset(), sdBuilder.switcher)) sdBuilder.valid = 0; if (!parseSdParam(AllowedSdParams(SdParam::reservedName + Sd::rSGMLREF, SdParam::reservedName + Sd::rNONE), parm)) return 0; if (parm.type == SdParam::reservedName + Sd::rSGMLREF) { if (!addRefDelimShortref(*sdBuilder.syntax, sdBuilder.syntaxCharset, sdBuilder.sd->internalCharset(), sdBuilder.switcher)) sdBuilder.valid = 0; } String<SyntaxChar> lastLiteral; for (;;) { if (!parseSdParam(sdBuilder.externalSyntax ? AllowedSdParams(SdParam::paramLiteral, SdParam::number, SdParam::minus, SdParam::reservedName + Sd::rNAMES) : AllowedSdParams(SdParam::paramLiteral, SdParam::reservedName + Sd::rNAMES), parm)) return 0; sdParamConvertToLiteral(parm); if (parm.type == SdParam::minus) { if (!parseSdParam(AllowedSdParams(SdParam::paramLiteral, SdParam::number), parm)) return 0; sdParamConvertToLiteral(parm); if (parm.paramLiteralText.size() == 0) message(ParserMessages::sdEmptyDelimiter); else if (lastLiteral.size() != 1 || parm.paramLiteralText.size() != 1) message(ParserMessages::sdRangeNotSingleChar); else if (parm.paramLiteralText[0] < lastLiteral[0]) message(ParserMessages::sdInvalidRange); else if (parm.paramLiteralText[0] != lastLiteral[0]) { ISet<Char> shortrefChars; translateRange(sdBuilder, lastLiteral[0] + 1, parm.paramLiteralText[0], shortrefChars); ISet<WideChar> duplicates; intersectCharSets(shortrefChars, sdBuilder.syntax->delimShortrefSimple(), duplicates); int nComplexShortrefs = sdBuilder.syntax->nDelimShortrefComplex(); for (int i = 0; i < nComplexShortrefs; i++) { const StringC &delim = sdBuilder.syntax->delimShortrefComplex(i); if (delim.size() == 1 && shortrefChars.contains(delim[0])) duplicates.add(delim[0]); } if (!duplicates.isEmpty()) message(ParserMessages::duplicateDelimShortrefSet, CharsetMessageArg(duplicates)); sdBuilder.syntax->addDelimShortrefs(shortrefChars, sdBuilder.sd->internalCharset()); } lastLiteral.resize(0); } else if (parm.type == SdParam::paramLiteral) { parm.paramLiteralText.swap(lastLiteral); StringC str; if (lastLiteral.size() == 0) message(ParserMessages::sdEmptyDelimiter); else if (translateSyntax(sdBuilder, lastLiteral, str)) { const SubstTable<Char> *table = sdBuilder.syntax->generalSubstTable(); for (size_t i = 0; i < str.size(); i++) table->subst(str[i]); if (str.size() == 1 || checkShortrefDelim(*sdBuilder.syntax, sdBuilder.sd->internalCharset(), str)) { if (sdBuilder.syntax->isValidShortref(str)) message(ParserMessages::duplicateDelimShortref, StringMessageArg(str)); else sdBuilder.syntax->addDelimShortref(str, sdBuilder.sd->internalCharset()); } } } else break; } return 1;}Boolean Parser::sdParseNames(SdBuilder &sdBuilder, SdParam &parm){ if (!parseSdParam(AllowedSdParams(SdParam::reservedName + Sd::rSGMLREF), parm)) return 0; for (;;) { if (!parseSdParam(AllowedSdParams(SdParam::reservedName + Sd::rQUANTITY, SdParam::referenceReservedName), parm)) return 0; if (parm.type == SdParam::reservedName + Sd::rQUANTITY) break; Syntax::ReservedName reservedName = parm.reservedNameIndex; switch (reservedName) { case Syntax::rALL: case Syntax::rDATA: case Syntax::rIMPLICIT: requireWWW(sdBuilder); break; default: break; } if (!parseSdParam(sdBuilder.externalSyntax ? AllowedSdParams(SdParam::name, SdParam::paramLiteral) : AllowedSdParams(SdParam::name), parm)) return 0; StringC transName; if (parm.type == SdParam::name ? translateName(sdBuilder, parm.token, transName) : translateSyntax(sdBuilder, parm.paramLiteralText, transName)) { Syntax::ReservedName tem; if (sdBuilder.syntax->lookupReservedName(transName, &tem)) message(ParserMessages::ambiguousReservedName, StringMessageArg(transName)); else { if (transName.size() == 0 || !sdBuilder.syntax->isNameStartCharacter(transName[0])) { message(ParserMessages::reservedNameSyntax, StringMessageArg(transName)); transName.resize(0); } size_t i; // Check that its a valid name in the declared syntax // (- and . might not be name characters). for (i = 1; i < transName.size(); i++) if (!sdBuilder.syntax->isNameCharacter(transName[i])) { message(ParserMessages::reservedNameSyntax, StringMessageArg(transName)); transName.resize(0); break; } for (i = 0; i < transName.size(); i++) sdBuilder.syntax->generalSubstTable()->subst(transName[i]); if (sdBuilder.syntax->reservedName(reservedName).size() > 0) message(ParserMessages::duplicateReservedName, StringMessageArg(syntax().reservedName(reservedName))); else if (transName.size() > 0) sdBuilder.syntax->setName(reservedName, transName); else sdBuilder.valid = 0; } } } setRefNames(*sdBuilder.syntax, sdBuilder.sd->internalCharset(), sdBuilder.www); static Syntax::ReservedName functionNameIndex[3] = { Syntax::rRE, Syntax::rRS, Syntax::rSPACE }; for (int i = 0; i < 3; i++) { const StringC &functionName = sdBuilder.syntax->reservedName(functionNameIndex[i]); Char tem; if (sdBuilder.syntax->lookupFunctionChar(functionName, &tem)) message(ParserMessages::duplicateFunctionName, StringMessageArg(functionName)); } sdBuilder.syntax->enterStandardFunctionNames(); return 1;}Boolean Parser::sdParseQuantity(SdBuilder &sdBuilder, SdParam &parm){ if (!parseSdParam(sdBuilder.www ? AllowedSdParams(SdParam::reservedName + Sd::rNONE, SdParam::reservedName + Sd::rSGMLREF) : AllowedSdParams(SdParam::reservedName + Sd::rSGMLREF), parm)) return 0; int final = (sdBuilder.externalSyntax ? int(SdParam::eE) : SdParam::reservedName + Sd::rFEATURES); if (parm.type == SdParam::reservedName + Sd::rNONE) { for (int i = 0; i < Syntax::nQuantity; i++) { if (i != Syntax::qNORMSEP) sdBuilder.syntax->setQuantity(Syntax::Quantity(i), Syntax::unlimited); } if (!parseSdParam(AllowedSdParams(final, SdParam::reservedName + Sd::rENTITIES), parm)) return 0; } else { for (;;) { if (!parseSdParam(sdBuilder.www ? AllowedSdParams(SdParam::quantityName, final, SdParam::reservedName + Sd::rENTITIES) : AllowedSdParams(SdParam::quantityName, final), parm)) return 0; if (parm.type != SdParam::quantityName) break; Syntax::Quantity quantity = parm.quantityIndex; if (!parseSdParam(AllowedSdParams(SdParam::number), parm)) return 0; sdBuilder.syntax->setQuantity(quantity, parm.n); } if (sdBuilder.sd->scopeInstance()) { for (int i = 0; i < Syntax::nQuantity; i++) if (sdBuilder.syntax->quantity(Syntax::Quantity(i)) < syntax().quantity(Syntax::Quantity(i))) message(ParserMessages::scopeInstanceQuantity, StringMessageArg(sd().quantityName(Syntax::Quantity(i)))); } } if (parm.type == SdParam::reservedName + Sd::rENTITIES) return sdParseEntities(sdBuilder, parm); else return 1;}Boolean Parser::sdParseEntities(SdBuilder &sdBuilder, SdParam &parm){ int final = (sdBuilder.externalSyntax ? int(SdParam::eE) : SdParam::reservedName + Sd::rFEATURES); for (;;) { if (!parseSdParam(AllowedSdParams(final, SdParam::paramLiteral), parm)) return 0; if (parm.type != SdParam::paramLiteral) break; StringC name; if (!translateSyntax(sdBuilder, parm.paramLiteralText, name)) name.resize(0); else if (name.size() == 0 || !sdBuilder.syntax->isNameStartCharacter(name[0])) { message(ParserMessages::entityNameSyntax, StringMessageArg(name)); name.resize(0); } else { // Check that its a valid name in the declared syntax for (size_t i = 1; i < name.size(); i++) if (!sdBuilder.syntax->isNameCharacter(name[i])) { message(ParserMessages::entityNameSyntax, StringMessageArg(name)); name.resize(0); break; } } if (!parseSdParam(AllowedSdParams(SdParam::number), parm)) return 0; Char c; if (translateSyntax(sdBuilder, parm.n, c) && name.size()) sdBuilder.syntax->addEntity(name, c); } return 1;}Boolean Parser::sdParseFeatures(SdBuilder &sdBuilder, SdParam &parm){ struct FeatureInfo { Sd::ReservedName name; enum { none, boolean, number, netenabl } arg; }; static FeatureInfo features[] = { { Sd::rMINIMIZE, FeatureInfo::none }, { Sd::rDATATAG, FeatureInfo::boolean }, { Sd::rOMITTAG, FeatureInfo::boolean }, { Sd::rRANK, FeatureInfo::boolean }, { Sd::rSHORTTAG, FeatureInfo::none }, { Sd::rSTARTTAG, FeatureInfo::none }, { Sd::rEMPTY, FeatureInfo::boolean }, { Sd::rUNCLOSED, FeatureInfo::boolean }, { Sd::rNETENABL, FeatureInfo::netenabl }, { Sd::rEND
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -