void File::ParseDefs(InputStream& s, Reference* pParentRef) { while(s.SkipWhiteSpace(L";") != '}' && s.PeekChar() != Stream::EOS) { NodePriority priority = PNormal; CAtlList<CStringW> types; CStringW name; int c = s.SkipWhiteSpace(); if(c == '*') {s.GetChar(); priority = PLow;} else if(c == '!') {s.GetChar(); priority = PHigh;} ParseTypes(s, types); if(s.SkipWhiteSpace() == '#') { s.GetChar(); ParseName(s, name); } if(types.IsEmpty()) { if(name.IsEmpty()) s.ThrowError(_T("syntax error")); types.AddTail(L"?"); } Reference* pRef = pParentRef; while(types.GetCount() > 1) pRef = CreateRef(CreateDef(pRef, types.RemoveHead())); Definition* pDef = NULL; if(!types.IsEmpty()) pDef = CreateDef(pRef, types.RemoveHead(), name, priority); c = s.SkipWhiteSpace(L":="); if(c == '"' || c == '\'') ParseQuotedString(s, pDef); else if(iswdigit(c) || c == '+' || c == '-') ParseNumber(s, pDef); else if(pDef->IsType(L"@")) ParseBlock(s, pDef); else ParseRefs(s, pDef); } s.GetChar(); }
Definition* NodeFactory::CreateDef(Reference* pParentRef, CStringW type, CStringW name, NodePriority priority) { Definition* pDef = NULL; if(name.IsEmpty()) { name = GenName(); } else { pDef = GetDefByName(name); if(pDef) { if(!pDef->m_predefined) { throw Exception(_T("redefinition of '%s' is not allowed"), CString(name)); } if(!pDef->IsTypeUnknown() && !pDef->IsType(type)) { throw Exception(_T("cannot redefine type of %s to %s"), CString(name), CString(type)); } } } if(!pDef) { pDef = DNew Definition(this, name); m_nodes.SetAt(name, pDef); m_newnodes.AddTail(name); if(pParentRef) { pParentRef->AddTail(pDef); pDef->m_parent = pParentRef; } } pDef->m_type = type; pDef->m_priority = priority; pDef->m_predefined = m_predefined; return pDef; }
Definition* Definition::SetChildAsValue(CStringW path, status_t s, CStringW v, CStringW u) { Definition* pDef = this; Split split('.', path); for(size_t i = 0, j = split - 1; i <= j; i++) { CStringW type = split[i]; if(pDef->m_nodes.IsEmpty() || !dynamic_cast<Reference*>(pDef->m_nodes.GetTail())) { EXECUTE_ASSERT(m_pnf->CreateRef(pDef) != NULL); } if(Reference* pRef = dynamic_cast<Reference*>(pDef->m_nodes.GetTail())) { pDef = NULL; POSITION pos = pRef->m_nodes.GetTailPosition(); while(pos) { Definition* pChildDef = dynamic_cast<Definition*>(pRef->m_nodes.GetPrev(pos)); if(pChildDef->IsType(type)) { if(pChildDef->IsNameUnknown()) pDef = pChildDef; break; } } if(!pDef) { pDef = m_pnf->CreateDef(pRef, type); } if(i == j) { pDef->SetAsValue(s, v, u); return pDef; } } } return NULL; }