diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2009-03-26 17:09:53 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2009-03-26 17:09:53 +0200 |
commit | e4c22d3686da0e973e21eae0561c1169c0eeff36 (patch) | |
tree | 0a49e9167edc88938b0287949080931314e8afea /xsde/cxx/hybrid/parser-aggregate-source.cxx | |
parent | 0d62005a3ff3b62d02c2eb3fd8644e0e19b202e8 (diff) |
Implement support for XML Schema polymorphism in C++/Hybrid
examples/cxx/hybrid/polyroot/
examples/cxx/hybrid/polymorphism/: new examples
tests/cxx/hybrid/polymorphism/: new tests
Diffstat (limited to 'xsde/cxx/hybrid/parser-aggregate-source.cxx')
-rw-r--r-- | xsde/cxx/hybrid/parser-aggregate-source.cxx | 162 |
1 files changed, 154 insertions, 8 deletions
diff --git a/xsde/cxx/hybrid/parser-aggregate-source.cxx b/xsde/cxx/hybrid/parser-aggregate-source.cxx index 6e80318..055cffb 100644 --- a/xsde/cxx/hybrid/parser-aggregate-source.cxx +++ b/xsde/cxx/hybrid/parser-aggregate-source.cxx @@ -4,6 +4,7 @@ // license : GNU GPL v2 + exceptions; see accompanying LICENSE file #include <cxx/hybrid/parser-aggregate-source.hxx> +#include <cxx/hybrid/aggregate-elements.hxx> #include <xsd-frontend/semantic-graph.hxx> #include <xsd-frontend/traversal.hxx> @@ -16,10 +17,6 @@ namespace CXX { namespace { - typedef - Cult::Containers::Map<SemanticGraph::Type*, String> - TypeInstanceMap; - // // struct ParticleArg: Traversal::Element, Context @@ -186,6 +183,57 @@ namespace CXX TypeInstanceMap& map_; }; + // + // + struct ParserMapConnect: Traversal::Complex, + Traversal::Element, + Context + { + ParserMapConnect (Context& c, String const& inst, String const& map) + : Context (c), inst_ (inst), map_ (map) + { + *this >> inherits_ >> *this; + + *this >> contains_compositor_; + contains_compositor_ >> compositor_; + compositor_ >> contains_particle_; + contains_particle_ >> compositor_; + contains_particle_ >> *this; + } + + virtual Void + traverse (SemanticGraph::Complex& c) + { + inherits (c); + + if (!restriction_p (c)) + contains_compositor (c); + } + + virtual Void + traverse (SemanticGraph::Element& e) + { + SemanticGraph::Type& t (e.type ()); + + if (polymorphic (t)) + { + os << "this->" << inst_ << "." << + e.context ().get<String> ("p:parser") << " (" << map_ << ");"; + } + } + + private: + String const& inst_; + String const& map_; + + Traversal::Inherits inherits_; + + Traversal::Compositor compositor_; + Traversal::Element particle_; + Traversal::ContainsCompositor contains_compositor_; + Traversal::ContainsParticle contains_particle_; + }; + struct GlobalType: Traversal::Type, Context { GlobalType (Context& c) @@ -208,18 +256,67 @@ namespace CXX << "//" << endl << endl; + TypeIdInstanceMap* tid_map (0); + + if (poly_code && tc.count ("paggr-tid-map")) + tid_map = &tc.get<TypeIdInstanceMap> ("paggr-tid-map"); + // c-tor () // os << name << "::" << endl - << name << " ()" - << "{"; + << name << " ()"; + + if (tid_map) + { + os << endl + << ": " << tc.get<String> ("paggr-parser-map") << " (" << + tc.get<String> ("paggr-parser-map-entries") << ", " << + tid_map->size () << "UL)"; + } + + os << "{"; + // Populate the polymorphic parser map. + // + if (tid_map) + { + String const& entry (tc.get<String> ("paggr-parser-map-entries")); + + Size n (0); + + for (TypeIdInstanceMap::Iterator i (tid_map->begin ()); + i != tid_map->end (); + ++i, ++n) + { + os << entry << "[" << n << "UL].type_id = " << + fq_name (*i->second.type, "p:name") << "::_static_type ();" + << entry << "[" << n << "UL].parser = &this->" << + i->second.name << ";" + << endl; + } + } + + // Connect parsers. + // ParserConnect connect (*this, map); for (TypeInstanceMap::Iterator i (map.begin ()), end (map.end ()); i != end; ++i) connect.dispatch (*i->first); + // Connect the parser map. + // + if (tid_map) + { + for (TypeInstanceMap::Iterator i (map.begin ()), end (map.end ()); + i != end; ++i) + { + ParserMapConnect t ( + *this, i->second, tc.get<String> ("paggr-parser-map")); + t.dispatch (*i->first); + } + } + os << "}"; } }; @@ -246,18 +343,67 @@ namespace CXX << "//" << endl << endl; + TypeIdInstanceMap* tid_map (0); + + if (poly_code && ec.count ("paggr-tid-map")) + tid_map = &ec.get<TypeIdInstanceMap> ("paggr-tid-map"); + // c-tor () // os << name << "::" << endl - << name << " ()" - << "{"; + << name << " ()"; + + if (tid_map) + { + os << endl + << ": " << ec.get<String> ("paggr-parser-map") << " (" << + ec.get<String> ("paggr-parser-map-entries") << ", " << + tid_map->size () << "UL)"; + } + + os << "{"; + + // Populate the polymorphic parser map. + // + if (tid_map) + { + String const& entry (ec.get<String> ("paggr-parser-map-entries")); + + Size n (0); + + for (TypeIdInstanceMap::Iterator i (tid_map->begin ()); + i != tid_map->end (); + ++i, ++n) + { + os << entry << "[" << n << "UL].type_id = " << + fq_name (*i->second.type, "p:name") << "::_static_type ();" + << entry << "[" << n << "UL].parser = &this->" << + i->second.name << ";" + << endl; + } + } + // Connect parsers. + // ParserConnect connect (*this, map); for (TypeInstanceMap::Iterator i (map.begin ()), end (map.end ()); i != end; ++i) connect.dispatch (*i->first); + // Connect the parser map. + // + if (tid_map) + { + for (TypeInstanceMap::Iterator i (map.begin ()), end (map.end ()); + i != end; ++i) + { + ParserMapConnect t ( + *this, i->second, ec.get<String> ("paggr-parser-map")); + t.dispatch (*i->first); + } + } + os << "}"; // root_name () |