📄 dtdparser.cpp
字号:
} } } } } }/////////////////////////////////////////////////////////////////////////////// DTDParser - entitiesvoid DTDParser::BeginEntityContent(void){// Entity:// http://www.w3.org/TR/2000/REC-xml-20001006#sec-entity-decl TToken tok = Next(); if (tok != T_SYMBOL || NextToken().GetSymbol() != '%') { ParseError("Incorrect format", "%"); }// _ASSERT(tok == T_SYMBOL);// _ASSERT(NextToken().GetSymbol() == '%'); Consume(); tok = Next(); if (tok != T_IDENTIFIER) { ParseError("identifier"); }// _ASSERT(tok == T_IDENTIFIER); // entity name string name = NextToken().GetText(); Consume(); ParseEntityContent(name);}void DTDParser::ParseEntityContent(const string& name){ DTDEntity& node = m_MapEntity[name]; node.SetName(name); TToken tok = Next(); if ((tok==K_SYSTEM) || (tok==K_PUBLIC)) { node.SetExternal(); Consume(); if (tok==K_PUBLIC) { // skip public id tok = Next(); if (tok!=T_STRING) { ParseError("string"); }// _ASSERT(tok==T_STRING); Consume(); } tok = Next(); } if (tok!=T_STRING) { ParseError("string"); }// _ASSERT(tok==T_STRING); node.SetData(NextToken().GetText()); Consume(); // entity description is ended ConsumeSymbol('>');}void DTDParser::PushEntityLexer(const string& name){ map<string,DTDEntity>::iterator i = m_MapEntity.find(name); if (i == m_MapEntity.end()) { ParseError("Undefined entity","entity"); }// _ASSERT (i != m_MapEntity.end()); CNcbiIstream* in; if (m_MapEntity[name].IsExternal()) { string filename(m_MapEntity[name].GetData()); string fullname = CDirEntry::MakePath(m_StackPath.top(), filename); CFile file(fullname); if (!file.Exists()) { ParseError("file not found", fullname.c_str()); }// _ASSERT(file.Exists()); in = new CNcbiIfstream(fullname.c_str()); if (!((CNcbiIfstream*)in)->is_open()) { ParseError("cannot access file",fullname.c_str()); }// _ASSERT(((CNcbiIfstream*)in)->is_open()); m_StackPath.push(file.GetDir()); } else { in = new CNcbiIstrstream(m_MapEntity[name].GetData().c_str()); m_StackPath.push(""); } DTDEntityLexer *lexer = new DTDEntityLexer(*in); m_StackLexer.push(lexer); SetLexer(lexer);}bool DTDParser::PopEntityLexer(void){ if (m_StackLexer.size() > 1) { delete m_StackLexer.top(); m_StackLexer.pop(); SetLexer(m_StackLexer.top()); m_StackPath.pop(); return true; } return false;}/////////////////////////////////////////////////////////////////////////////// DTDParser - attributesvoid DTDParser::BeginAttributesContent(void){// Attributes// http://www.w3.org/TR/2000/REC-xml-20001006#attdecls // element name string name = NextToken().GetText(); Consume(); ParseAttributesContent(name);}void DTDParser::ParseAttributesContent(const string& name){ string id_name; DTDElement& node = m_MapElement[ name]; while (Next()==T_IDENTIFIER) { // attribute name id_name = NextToken().GetText(); Consume(); ConsumeAttributeContent(node, id_name); } // attlist description is ended ConsumeSymbol('>');}void DTDParser::ConsumeAttributeContent(DTDElement& node, const string& id_name){ bool skip; bool done=false; DTDAttribute attrib; attrib.SetName(id_name); for (done=skip=false; !done;) { switch(Next()) { default: ParseError("Unknown token", "token");// _ASSERT(0); break; case T_ENTITY: PushEntityLexer(NextToken().GetText()); skip = true; break; case T_EOF: PopEntityLexer(); break; case T_IDENTIFIER: if (attrib.GetType() == DTDAttribute::eUnknown) { ParseError(attrib.GetName().c_str(), "attribute type"); } done = true; break; case T_SYMBOL: switch (NextToken().GetSymbol()) { default: done = true; break; case '(': // parse enumerated list attrib.SetType(DTDAttribute::eEnum); Consume(); ParseEnumeratedList(attrib); break; } break; case T_STRING: attrib.SetValue(NextToken().GetText()); break; case K_CDATA: attrib.SetType(DTDAttribute::eString); break; case K_ID: attrib.SetType(DTDAttribute::eId); break; case K_IDREF: attrib.SetType(DTDAttribute::eIdRef); break; case K_IDREFS: attrib.SetType(DTDAttribute::eIdRefs); break; case K_NMTOKEN: attrib.SetType(DTDAttribute::eNmtoken); break; case K_NMTOKENS: attrib.SetType(DTDAttribute::eNmtokens); break; case K_ENTITY: attrib.SetType(DTDAttribute::eEntity); break; case K_ENTITIES: attrib.SetType(DTDAttribute::eEntities); break; case K_NOTATION: attrib.SetType(DTDAttribute::eNotation); break; case K_DEFAULT: attrib.SetValueType(DTDAttribute::eDefault); break; case K_REQUIRED: attrib.SetValueType(DTDAttribute::eRequired); break; case K_IMPLIED: attrib.SetValueType(DTDAttribute::eImplied); break; case K_FIXED: attrib.SetValueType(DTDAttribute::eFixed); break; } if (skip) { skip=false; } else { if (!done) { Consume(); } } } node.AddAttribute(attrib);}void DTDParser::ParseEnumeratedList(DTDAttribute& attrib){ for (;;) { switch(Next()) { default: ParseError("Unknown token", "token");// _ASSERT(0); break; case T_IDENTIFIER: attrib.AddEnumValue(NextToken().GetText()); Consume(); break; case T_SYMBOL: // may be either '|' or ')' if (NextToken().GetSymbol() == ')') { return; } Consume(); break; case T_ENTITY: PushEntityLexer(NextToken().GetText()); break; case T_EOF: PopEntityLexer(); Consume(); break; } }}/////////////////////////////////////////////////////////////////////////////// model generationvoid DTDParser::GenerateDataTree(CDataTypeModule& module){ map<string,DTDElement>::iterator i; for (i = m_MapElement.begin(); i != m_MapElement.end(); ++i) { if (i->second.GetName().empty()) { ParseError(i->first.c_str(),"definition"); } DTDElement::EType type = i->second.GetType(); if (((type == DTDElement::eSequence) || (type == DTDElement::eChoice) || i->second.HasAttributes()) && !i->second.IsEmbedded()) { ModuleType(module, i->second); } }}void DTDParser::ModuleType(CDataTypeModule& module, const DTDElement& node){ AutoPtr<CDataType> type = Type(node, node.GetOccurrence(), false); module.AddDefinition(node.GetName(), type);}AutoPtr<CDataType> DTDParser::Type( const DTDElement& node, DTDElement::EOccurrence occ, bool fromInside, bool ignoreAttrib){ AutoPtr<CDataType> type(x_Type(node, occ, fromInside, ignoreAttrib)); return type;}CDataType* DTDParser::x_Type( const DTDElement& node, DTDElement::EOccurrence occ, bool fromInside, bool ignoreAttrib){ CDataType* type;// if the node contains single embedded element - prune it if ((!fromInside || node.IsEmbedded()) && !node.HasAttributes()) { const list<string>& refs = node.GetContent(); if (refs.size() == 1) { string refName = refs.front(); if (m_MapElement[refName].IsEmbedded() && (node.GetOccurrence(refName) == DTDElement::eOne)) { type = x_Type(m_MapElement[refName],occ,fromInside); if (node.IsEmbedded()) { DTDElement& emb = const_cast<DTDElement&>(node); emb.SetName(m_MapElement[refName].GetName()); } return type; } } } bool uniseq = (occ == DTDElement::eOneOrMore || occ == DTDElement::eZeroOrMore); bool cont = (node.GetType() == DTDElement::eSequence || node.GetType() == DTDElement::eChoice); bool attrib = !ignoreAttrib && node.HasAttributes(); bool ref = fromInside && !node.IsEmbedded(); if ((cont && uniseq && (attrib || node.IsEmbedded())) || (!cont && attrib)) { if (ref) { type = new CReferenceDataType(node.GetName()); } else { type = CompositeNode(node, occ); uniseq = false; } } else { switch (node.GetType()) { case DTDElement::eSequence: if (ref) { type = new CReferenceDataType(node.GetName()); } else { type = TypesBlock(new CDataSequenceType(),node,ignoreAttrib); } break; case DTDElement::eChoice: if (ref) { type = new CReferenceDataType(node.GetName()); } else { type = TypesBlock(new CChoiceDataType(),node,ignoreAttrib); } break; case DTDElement::eString: type = new CStringDataType(); break; case DTDElement::eAny: type = new CAnyContentDataType(); break; case DTDElement::eEmpty: type = new CNullDataType(); break; default: ParseError("Unknown element", "element");// _ASSERT(0); break; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -