aboutsummaryrefslogtreecommitdiff
path: root/xsde/cxx/hybrid/parser-source.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'xsde/cxx/hybrid/parser-source.cxx')
-rw-r--r--xsde/cxx/hybrid/parser-source.cxx1185
1 files changed, 1185 insertions, 0 deletions
diff --git a/xsde/cxx/hybrid/parser-source.cxx b/xsde/cxx/hybrid/parser-source.cxx
new file mode 100644
index 0000000..4f5fc38
--- /dev/null
+++ b/xsde/cxx/hybrid/parser-source.cxx
@@ -0,0 +1,1185 @@
+// file : xsde/cxx/hybrid/parser-source.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/hybrid/parser-source.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+namespace CXX
+{
+ namespace Hybrid
+ {
+ namespace
+ {
+ struct List: Traversal::List, Context
+ {
+ List (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& l)
+ {
+ String const& name (epimpl_custom (l));
+
+ if (!name)
+ return;
+
+ String const& type (fq_name (l));
+ String const& base (epstate_base (l));
+ String const& member (epstate_member (l));
+ String item (unclash (epskel (l), "item"));
+
+ os << "// " << name << endl
+ << "//" << endl
+ << endl;
+
+ // c-tor
+ //
+ os << name << "::" << endl
+ << name << " (bool b)"
+ << "{"
+ << "this->" << base << " = b;"
+ << "this->" << member << " = 0;"
+ << "}";
+
+ // d-tor
+ //
+ os << name << "::" << endl
+ << "~" << name << " ()"
+ << "{"
+ << "if (!this->" << base << ")" << endl
+ << "delete this->" << member << ";"
+ << "}";
+
+ // reset
+ //
+ if (reset)
+ os << "void " << name << "::" << endl
+ << "_reset ()"
+ << "{"
+ << epskel (l) << "::_reset ();"
+ << endl
+ << "if (!this->" << base << ")"
+ << "{"
+ << "delete this->" << member << ";"
+ << "this->" << member << " = 0;"
+ << "}"
+ << "}";
+
+ // pre_impl
+ //
+ os << "void " << name << "::" << endl
+ << pre_impl_name (l) << " (" << type << "* x)"
+ << "{"
+ << "this->" << member << " = x;"
+ << "}";
+
+ // pre
+ //
+ os << "void " << name << "::" << endl
+ << "pre ()"
+ << "{";
+
+ if (exceptions)
+ os << "this->" << pre_impl_name (l) << " (new " << type << ");";
+ else
+ os << type << "* x = new " << type << ";"
+ << "if (x)" << endl
+ << "this->" << pre_impl_name (l) << " (x);"
+ << "else" << endl
+ << "this->_sys_error (::xsde::cxx::sys_error::no_memory);";
+
+ os << "}";
+
+ // item
+ //
+ String const& arg (parg_type (l.argumented ().type ()));
+
+ os << "void " << name << "::" << endl
+ << item << " (" << arg << " i)"
+ << "{";
+
+ if (exceptions)
+ os << "this->" << member << "->push_back (i);";
+ else
+ os << "if (this->" << member << "->push_back (i))" << endl
+ << "this->_sys_error (::xsde::cxx::sys_error::no_memory);";
+
+ os << "}";
+
+ // post
+ //
+ String const& ret (pret_type (l));
+
+ os << ret << " " << name << "::" << endl
+ << post_name (l) << " ()"
+ << "{"
+ << type << "* r = this->" << member << ";"
+ << "this->" << member << " = 0;"
+ << "return r;"
+ << "}";
+ }
+ };
+
+ //
+ //
+ struct Union: Traversal::Union, Context
+ {
+ Union (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& u)
+ {
+ String const& name (epimpl_custom (u));
+
+ if (!name)
+ return;
+
+ String const& type (fq_name (u));
+ String const& state (epstate (u));
+ String const& ret (pret_type (u));
+ String const& value (u.context ().get<String> ("value"));
+
+ os << "// " << name << endl
+ << "//" << endl
+ << endl;
+
+ if (stl)
+ {
+ // pre
+ //
+ os << "void " << name << "::" << endl
+ << "pre ()"
+ << "{"
+ << "this->" << state << ".str_.clear ();"
+ << "}";
+
+ // _characters
+ //
+ os << "void " << name << "::" << endl
+ << "_characters (const " << string_type << "& s)"
+ << "{"
+ << "this->" << state << ".str_.append (s.data (), s.size ());"
+ << "}";
+
+ // post
+ //
+ os << ret << " " << name << "::" << endl
+ << post_name (u) << " ()"
+ << "{"
+ << "::std::string s;"
+ << "s.swap (this->" << state << ".str_);"
+ << type << " r;"
+ << "r." << value << " (s);"
+ << "return r;"
+ << "}";
+ }
+ else
+ {
+ String const& base (epstate_base (u));
+
+ // c-tor
+ //
+ os << name << "::" << endl
+ << name << " (bool b)"
+ << "{"
+ << "this->" << base << " = b;"
+ << "this->" << state << ".x_ = 0;"
+ << "}";
+
+ // d-tor
+ //
+ os << name << "::" << endl
+ << "~" << name << " ()"
+ << "{"
+ << "if (!this->" << base << ")" << endl
+ << "delete this->" << state << ".x_;"
+ << "}";
+
+ // reset
+ //
+ if (reset)
+ os << "void " << name << "::" << endl
+ << "_reset ()"
+ << "{"
+ << epskel (u) << "::_reset ();"
+ << endl
+ << "if (!this->" << base << ")"
+ << "{"
+ << "delete this->" << state << ".x_;"
+ << "this->" << state << ".x_ = 0;"
+ << "}"
+ << "}";
+
+ // pre_impl
+ //
+ os << "void " << name << "::" << endl
+ << pre_impl_name (u) << " (" << type << "* x)"
+ << "{"
+ << "this->" << state << ".x_ = x;";
+
+ if (exceptions)
+ os << "this->" << state << ".str_.assign (\"\", 0);";
+ else
+ {
+ os << endl
+ << "if (this->" << state << ".str_.assign (\"\", 0))" << endl
+ << "this->_sys_error (::xsde::cxx::sys_error::no_memory);";
+ }
+
+ os << "}";
+
+ // pre
+ //
+ os << "void " << name << "::" << endl
+ << "pre ()"
+ << "{";
+
+ if (exceptions)
+ os << "this->" << pre_impl_name (u) << " (new " << type << ");";
+ else
+ os << type << "* x = new " << type << ";"
+ << "if (x)" << endl
+ << "this->" << pre_impl_name (u) << " (x);"
+ << "else" << endl
+ << "this->_sys_error (::xsde::cxx::sys_error::no_memory);";
+
+ os << "}";
+
+ // _characters
+ //
+ os << "void " << name << "::" << endl
+ << "_characters (const " << string_type << "& s)"
+ << "{";
+
+ if (exceptions)
+ os << "this->" << state << ".str_.append (s.data (), s.size ());";
+ else
+ {
+ os << "if (this->" << state << ".str_.append (" <<
+ "s.data (), s.size ()))" << endl
+ << "this->_sys_error (::xsde::cxx::sys_error::no_memory);";
+ }
+
+ os << "}";
+
+ // post
+ //
+ os << ret << " " << name << "::" << endl
+ << post_name (u) << " ()"
+ << "{"
+ << type << "* r = this->" << state << ".x_;"
+ << "this->" << state << ".x_ = 0;"
+ << "r->" << value << " (this->" << state << ".str_.detach ());"
+ << "return r;"
+ << "}";
+ }
+ }
+ };
+
+ struct ParserContext: Context
+ {
+ ParserContext (Context& c)
+ : Context (c)
+ {
+ }
+
+ // Return the access sequence up until this particle. If
+ // element is false then the access sequence for the
+ // container is returned. Otherwise the access sequence
+ // for the current element in the container is returned.
+ //
+ String
+ access_seq (SemanticGraph::Particle& p, Boolean element = true)
+ {
+ using namespace SemanticGraph;
+
+ String r;
+
+ Boolean seq (false);
+
+ Compositor* c;
+
+ if (p.contained_particle_p ())
+ {
+ c = &p.contained_particle ().compositor ();
+
+ // Check if this particle is a sequence. In this case
+ // we just need the top-level struct member.
+ //
+ if (element && p.max () != 1 && p.is_a<Compositor> ())
+ {
+ seq = true;
+ }
+ else
+ {
+ for (;; c = &c->contained_particle ().compositor ())
+ {
+ if (c->context ().count ("type"))
+ {
+ // Not a see-through compositor.
+ //
+ if (c->max () != 1)
+ {
+ String const& ptr (epstate_member (*c));
+
+ if (!r)
+ {
+ r = ptr;
+ r += L"->";
+ }
+ else
+ {
+ String tmp;
+ tmp.swap (r);
+ r = ptr;
+ r += L"->";
+ r += tmp;
+ }
+
+ seq = true;
+ break;
+ }
+ else
+ {
+ String const& func (ename (*c));
+
+ if (!r)
+ {
+ r = func;
+ r += L" ().";
+ }
+ else
+ {
+ String tmp;
+ tmp.swap (r);
+ r = func;
+ r += L" ().";
+ r += tmp;
+ }
+ }
+ }
+
+ if (c->contained_compositor_p ())
+ break;
+ }
+ }
+
+ // Get to the top in case we bailed out on a sequence.
+ //
+ while (!c->contained_compositor_p ())
+ c = &c->contained_particle ().compositor ();
+ }
+ else
+ {
+ // This particle is a top-level compositor.
+ //
+ c = &dynamic_cast<Compositor&> (p);
+ seq = element && c->max () != 1;
+ }
+
+ Complex& t (
+ dynamic_cast<Complex&> (
+ c->contained_compositor ().container ()));
+
+ if (!seq)
+ {
+ Boolean fixed (fixed_length (t));
+ String const& s (epstate_member (t));
+
+ if (!r)
+ {
+ r = s;
+ r += fixed ? L"." : L"->";
+ }
+ else
+ {
+ String tmp;
+ tmp.swap (r);
+ r = s;
+ r += fixed ? L"." : L"->";
+ r += tmp;
+ }
+ }
+
+ String tmp;
+ tmp.swap (r);
+ r = epstate (t);
+ r += L".";
+ r += tmp;
+
+ return r;
+ }
+
+ String
+ access_seq (SemanticGraph::Attribute& a)
+ {
+ using namespace SemanticGraph;
+
+ Complex& t (dynamic_cast<Complex&> (a.scope ()));
+
+ String r (epstate (t));
+ r += L".";
+ r += epstate_member (t);
+ r += fixed_length (t) ? L"." : L"->";
+
+ return r;
+ }
+ };
+
+ //
+ // Test for presence of var-length compositor in choice
+ // that need initialization.
+ //
+
+ struct CompositorTest: Traversal::Compositor
+ {
+ CompositorTest (Boolean& p)
+ : p_ (p)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Compositor& c)
+ {
+ // We are only interested in var-length required compositors.
+ //
+ if (c.max () == 1 &&
+ c.min () == 1 &&
+ !c.context ().get<Boolean> ("fixed"))
+ p_ = true;
+ }
+
+ private:
+ Boolean& p_;
+ };
+
+ //
+ // Callbacks.
+ //
+
+ struct CompositorCallback: Traversal::All,
+ Traversal::Choice,
+ Traversal::Sequence,
+ ParserContext
+ {
+ CompositorCallback (Context& c)
+ : ParserContext (c), compositor_test_ (init_)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::All& a)
+ {
+ // For the all compositor, maxOccurs=1 and minOccurs={0,1}.
+ //
+ if (a.min () == 0)
+ {
+ String const& s (epimpl_custom (scope (a)));
+
+ os << "void " << s << "::" << endl
+ << eppresent (a) << " ()"
+ << "{";
+
+ String access (access_seq (a));
+
+ if (fixed_length (a))
+ os << "this->" << access << epresent (a) << " (true);";
+ else
+ {
+ String const& name (ename (a));
+ String const& type (etype (a));
+ String const& scope (fq_scope (a));
+
+ if (exceptions)
+ os << "this->" << access << name << " (new " <<
+ scope << "::" << type << ");";
+ else
+ os << scope << "::" << type << "* x = new " <<
+ scope << "::" << type << ";"
+ << "if (x)" << endl
+ << "this->" << access << name << " (x);"
+ << "else" << endl
+ << "this->_sys_error (::xsde::cxx::sys_error::no_memory);";
+ }
+
+ os << "}";
+ }
+
+ Traversal::All::traverse (a);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Choice& c)
+ {
+ String const& s (epimpl_custom (scope (c)));
+ String const& access (access_seq (c));
+ String const& type_scope (fq_scope (c));
+
+ os << "void " << s << "::" << endl
+ << eparm (c) << " (" << eparm_tag (c) << " t)"
+ << "{";
+
+ if (c.max () != 1)
+ {
+ String const& name (ename (c));
+ String const& type (etype (c));
+ String const& access_s (access_seq (c, false));
+ String const& ptr (epstate_member (c));
+
+ if (fixed_length (c))
+ {
+ if (exceptions)
+ os << "this->" << access_s << name << " ().push_back (" <<
+ type_scope << "::" << type << " ());";
+ else
+ os << "if (this->" << access_s << name << " ().push_back (" <<
+ type_scope << "::" << type << " ()))"
+ << "{"
+ << "this->_sys_error (::xsde::cxx::sys_error::no_memory);"
+ << "return;"
+ << "}";
+
+ os << "this->" << access << ptr << " = &this->" <<
+ access_s << name << " ().back ();";
+ }
+ else
+ {
+ os << "this->" << access << ptr << " = new " <<
+ type_scope << "::" << type << ";";
+
+ if (exceptions)
+ os << "this->" << access_s << name << " ().push_back (" <<
+ "this->" << access << ptr << ");";
+ else
+ os << "if (!this->" << access << ptr << " ||" << endl
+ << "this->" << access_s << name << " ().push_back (" <<
+ "this->" << access << ptr << "))"
+ << "{"
+ << "this->_sys_error (::xsde::cxx::sys_error::no_memory);"
+ << "return;"
+ << "}";
+ }
+
+ os << "this->" << access << ptr << "->";
+ }
+ else if (c.min () == 0)
+ {
+ String const& name (ename (c));
+
+ if (fixed_length (c))
+ os << "this->" << access << epresent (c) << " (true);";
+ else
+ {
+ String const& type (etype (c));
+
+ if (exceptions)
+ os << "this->" << access << name << " (new " <<
+ type_scope << "::" << type << ");";
+ else
+ os << type_scope << "::" << type << "* x = new " <<
+ type_scope << "::" << type << ";"
+ << "if (x)" << endl
+ << "this->" << access << name << " (x);"
+ << "else"
+ << "{"
+ << "this->_sys_error (::xsde::cxx::sys_error::no_memory);"
+ << "return;"
+ << "}";
+ }
+
+ os << "this->" << access << name << " ().";
+ }
+ else
+ {
+ // We may be in a choice in which case we get a nested
+ // type (and accessor function) even for min == max == 1.
+ //
+ if (c.context ().count ("type"))
+ os << "this->" << access << ename (c) << " ().";
+ else
+ os << "this->" << access;
+ }
+
+ os << earm (c) << " (static_cast< " << type_scope;
+
+ if (c.context ().count ("type"))
+ os << "::" << etype (c);
+
+ os << "::" << earm_tag (c) << " > (t));"
+ << endl;
+
+ // Test whether we have any arms that need initialization.
+ // Those are var-length required compositors.
+ //
+ init_ = false;
+
+ for (SemanticGraph::Choice::ContainsIterator
+ i (c.contains_begin ()), e (c.contains_end ());
+ !init_ && i != e; ++i)
+ {
+ compositor_test_.dispatch (i->particle ());
+ }
+
+ if (init_)
+ {
+ os << "switch (t)"
+ << "{";
+
+ for (SemanticGraph::Choice::ContainsIterator
+ i (c.contains_begin ()), e (c.contains_end ());
+ i != e; ++i)
+ {
+ // Test if this arm needs initialization.
+ //
+ init_ = false;
+ compositor_test_.dispatch (i->particle ());
+
+ if (init_)
+ {
+ SemanticGraph::Compositor& p (
+ dynamic_cast<SemanticGraph::Compositor&> (
+ i->particle ()));
+
+ os << "case " << eptag (p) << ":"
+ << "{";
+
+ String const& type (etype (p));
+ String const& scope (fq_scope (p));
+
+ if (exceptions)
+ os << "this->" << access_seq (p) << ename (p) <<
+ " (new " << scope << "::" << type << ");";
+ else
+ os << scope << "::" << type << "* x = new " <<
+ scope << "::" << type << ";"
+ << "if (x)" << endl
+ << "this->" << access_seq (p) << ename (p) << " (x);"
+ << "else" << endl
+ << "this->_sys_error (::xsde::cxx::sys_error::no_memory);";
+
+ os << "break;"
+ << "}";
+ }
+ }
+
+ os << "default:"
+ << "{"
+ << "break;"
+ << "}"
+ << "}";
+ }
+
+ os << "}";
+
+ Traversal::Choice::traverse (c);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Sequence& s)
+ {
+ if (s.max () != 1)
+ {
+ String const& sc (epimpl_custom (scope (s)));
+
+ String const& access (access_seq (s));
+ String const& access_s (access_seq (s, false));
+ String const& name (ename (s));
+ String const& type (etype (s));
+ String const& scope (fq_scope (s));
+ String const& ptr (epstate_member (s));
+
+ os << "void " << sc << "::" << endl
+ << epnext (s) << " ()"
+ << "{";
+
+ if (fixed_length (s))
+ {
+ if (exceptions)
+ os << "this->" << access_s << name << " ().push_back (" <<
+ scope << "::" << type << " ());";
+ else
+ os << "if (this->" << access_s << name << " ().push_back (" <<
+ scope << "::" << type << " ()))"
+ << "{"
+ << "this->_sys_error (::xsde::cxx::sys_error::no_memory);"
+ << "return;"
+ << "}";
+
+ os << "this->" << access << ptr << " = &this->" <<
+ access_s << name << " ().back ();";
+ }
+ else
+ {
+ os << "this->" << access << ptr << " = new " <<
+ scope << "::" << type << ";";
+
+ if (exceptions)
+ os << "this->" << access_s << name << " ().push_back (" <<
+ "this->" << access << ptr << ");";
+ else
+ os << "if (!this->" << access << ptr << " ||" << endl
+ << "this->" << access_s << name << " ().push_back (" <<
+ "this->" << access << ptr << "))" << endl
+ << "this->_sys_error (::xsde::cxx::sys_error::no_memory);";
+ }
+
+ os << "}";
+ }
+ else if (s.min () == 0)
+ {
+ String const& sc (epimpl_custom (scope (s)));
+
+ os << "void " << sc << "::" << endl
+ << eppresent (s) << " ()"
+ << "{";
+
+ String access (access_seq (s));
+
+ if (fixed_length (s))
+ os << "this->" << access << epresent (s) << " (true);";
+ else
+ {
+ String const& name (ename (s));
+ String const& type (etype (s));
+ String const& scope (fq_scope (s));
+
+ if (exceptions)
+ os << "this->" << access << name << " (new " <<
+ scope << "::" << type << ");";
+ else
+ os << scope << "::" << type << "* x = new " <<
+ scope << "::" << type << ";"
+ << "if (x)" << endl
+ << "this->" << access << name << " (x);"
+ << "else" << endl
+ << "this->_sys_error (::xsde::cxx::sys_error::no_memory);";
+ }
+
+ os << "}";
+ }
+
+ Traversal::Sequence::traverse (s);
+ }
+
+ private:
+ SemanticGraph::Complex&
+ scope (SemanticGraph::Compositor& c)
+ {
+ SemanticGraph::Compositor* root (&c);
+
+ while (root->contained_particle_p ())
+ root = &root->contained_particle ().compositor ();
+
+ return dynamic_cast<SemanticGraph::Complex&> (
+ root->contained_compositor ().container ());
+ }
+
+ private:
+ Boolean init_;
+ CompositorTest compositor_test_;
+ };
+
+ struct ParticleCallback: Traversal::Element, ParserContext
+ {
+ ParticleCallback (Context& c)
+ : ParserContext (c)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Element& e)
+ {
+ using SemanticGraph::Complex;
+
+ String const& name (epname (e));
+ String const& arg (parg_type (e.type ()));
+ Complex& c (dynamic_cast<Complex&> (e.scope ()));
+
+ os << "void " << epimpl_custom (c) << "::" << endl
+ << name << " (";
+
+ if (arg != L"void")
+ {
+ os << arg << " x)"
+ << "{";
+
+ if (e.max () != 1)
+ {
+ if (exceptions)
+ os << "this->" << access_seq (e) << ename (e) <<
+ " ().push_back (x);";
+ else
+ os << "if (this->" << access_seq (e) << ename (e) <<
+ " ().push_back (x))" << endl
+ << "this->_sys_error (::xsde::cxx::sys_error::no_memory);";
+ }
+ else
+ {
+ os << "this->" << access_seq (e) << ename (e) << " (x);";
+ }
+
+ os << "}";
+ }
+ else
+ {
+ os << ")"
+ << "{"
+ << "}";
+ }
+ }
+ };
+
+ struct AttributeCallback: Traversal::Attribute, ParserContext
+ {
+ AttributeCallback (Context& c)
+ : ParserContext (c)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Attribute& a)
+ {
+ using SemanticGraph::Complex;
+
+ String const& name (epname (a));
+ String const& arg (parg_type (a.type ()));
+ Complex& c (dynamic_cast<Complex&> (a.scope ()));
+
+ os << "void " << epimpl_custom (c) << "::" << endl
+ << name << " (";
+
+ if (arg != L"void")
+ {
+ os << arg << " x)"
+ << "{"
+ << "this->" << access_seq (a) << ename (a) << " (x);"
+ << "}";
+ }
+ else
+ {
+ os << ")"
+ << "{"
+ << "}";
+ }
+ }
+ };
+
+ //
+ //
+ struct Complex : Traversal::Complex, Context
+ {
+ Complex (Context& c)
+ : Context (c),
+ base_name_ (c, TypeName::base),
+ compositor_callback_ (c),
+ particle_callback_ (c),
+ attribute_callback_ (c)
+ {
+ contains_compositor_callback_ >> compositor_callback_;
+ compositor_callback_ >> contains_particle_callback_;
+ contains_particle_callback_ >> compositor_callback_;
+ contains_particle_callback_ >> particle_callback_;
+
+ names_attribute_callback_ >> attribute_callback_;
+ }
+
+ virtual Void
+ traverse (Type& c)
+ {
+ String const& name (epimpl_custom (c));
+
+ if (!name)
+ return;
+
+ Boolean hb (c.inherits_p ());
+ Boolean restriction (restriction_p (c));
+ Boolean fixed (fixed_length (c));
+ Boolean c_string_base (false);
+
+ if (!stl && hb)
+ {
+ StringType test (c_string_base);
+ test.dispatch (c.inherits ().base ());
+ }
+
+ String const& ret (pret_type (c));
+
+ String const& state (epstate (c));
+ String const& member (epstate_member (c));
+ String const& type (fq_name (c));
+
+ os << "// " << name << endl
+ << "//" << endl
+ << endl;
+
+ // c-tor
+ //
+ if (!fixed || (hb && tiein))
+ {
+ os << name << "::" << endl
+ << name << " (" << (fixed ? "" : "bool b") << ")";
+
+ if (hb)
+ {
+ if (tiein)
+ os << endl
+ << ": " << epskel (c) << " (&base_impl_)";
+
+ SemanticGraph::Type& b (c.inherits ().base ());
+
+ // C-string-based built-in parser implementations don't
+ // have c-tor (bool base).
+ //
+ if (!c_string_base && !fixed_length (b))
+ {
+ if (tiein)
+ os << "," << endl
+ << " " << "base_impl_" << " (true)";
+ else
+ os << endl
+ << ": " << fq_name (b, "p:impl") << " (true)";
+ }
+ }
+
+ os << "{";
+
+ if (!fixed)
+ os << "this->" << epstate_base (c) << " = b;"
+ << "this->" << state << "." << member << " = 0;";
+
+ os << "}";
+ }
+
+ if (!fixed)
+ {
+ // d-tor
+ //
+ os << name << "::" << endl
+ << "~" << name << " ()"
+ << "{"
+ << "if (!this->" << epstate_base (c) << ")" << endl
+ << "delete this->" << state << "." << member << ";"
+ << "}";
+
+ // reset
+ //
+ if (reset)
+ os << "void " << name << "::" << endl
+ << "_reset ()"
+ << "{";
+
+ if (mixin && hb)
+ os << epimpl (c); //@@ fq-name
+ else
+ os << epskel (c); //@@ fq-name
+
+ os << "::_reset ();"
+ << endl;
+
+ os << "if (!this->" << epstate_base (c) << ")"
+ << "{"
+ << "delete this->" << state << "." << member << ";"
+ << "this->" << state << "." << member << " = 0;"
+ << "}"
+ << "}";
+ }
+
+ // pre_impl
+ //
+ if (!fixed)
+ {
+ os << "void " << name << "::" << endl
+ << pre_impl_name (c) << " (" << type << "* x)"
+ << "{"
+ << "this->" << state << "." << member << " = x;";
+
+ // Call base pre_impl (var-length) or pre (fix-length). C-string-
+ // based built-in parser implementations don't have pre_impl().
+ //
+ if (hb && !c_string_base)
+ {
+ SemanticGraph::Type& b (c.inherits ().base ());
+
+ if (tiein)
+ os << "this->base_impl_.";
+ else
+ os << epimpl (b) << "::"; //@@ fq-name.
+
+ if (fixed_length (b))
+ os << "pre ();";
+ else
+ os << pre_impl_name (b) << " (x);";
+ }
+
+ os << "}";
+ }
+
+ // pre
+ //
+ os << "void " << name << "::" << endl
+ << "pre ()"
+ << "{";
+
+ if (fixed)
+ {
+ if (hb)
+ {
+ // Our base is also fixed-length so call its pre()
+ //
+ if (tiein)
+ os << "this->base_impl_.";
+ else
+ os << epimpl (c.inherits ().base ()) << "::"; //@@ fq-name.
+
+ os << "pre ();";
+ }
+
+ os << "this->" << state << "." << member << " = " <<
+ type << " ();";
+ }
+ else
+ {
+ if (exceptions)
+ os << "this->" << pre_impl_name (c) << " (new " << type << ");";
+ else
+ os << type << "* x = new " << type << ";"
+ << "if (x)" << endl
+ << "this->" << pre_impl_name (c) << " (x);"
+ << "else" << endl
+ << "this->_sys_error (::xsde::cxx::sys_error::no_memory);";
+ }
+
+ os << "}";
+
+ // Parser callbacks.
+ //
+ if (!restriction)
+ {
+ names (c, names_attribute_callback_);
+ contains_compositor (c, contains_compositor_callback_);
+ }
+
+ // post
+ //
+ os << ret << " " << name << "::" << endl
+ << post_name (c) << " ()"
+ << "{";
+
+ if (hb)
+ {
+ SemanticGraph::Type& b (c.inherits ().base ());
+
+ // Default parser implementations for anyType and
+ // anySimpleType return void.
+ //
+ if (!b.is_a<SemanticGraph::AnyType> () &&
+ !b.is_a<SemanticGraph::AnySimpleType> ())
+ {
+ // If our base is a fixed-length type or C-string-base, then
+ // copy the data over.
+ //
+ if (fixed_length (b))
+ {
+ os << "static_cast< ";
+
+ base_name_.dispatch (b);
+
+ os << "& > (" << (fixed ? "" : "*") << "this->" <<
+ state << "." << member << ") = ";
+ }
+
+ if (c_string_base)
+ {
+ os << "static_cast< ";
+
+ base_name_.dispatch (b);
+
+ os << "* > (this->" <<
+ state << "." << member << ")->base_value (";
+ }
+
+ if (tiein)
+ os << "this->base_impl_.";
+ else
+ os << epimpl (b) << "::"; //@@ fq-name.
+
+ os << post_name (b) << " ()";
+
+ if (c_string_base)
+ os << ")";
+
+ os << ";";
+ }
+ }
+
+ if (fixed)
+ os << "return this->" << state << "." << member << ";";
+ else
+ os << type << "* r = this->" << state << "." << member << ";"
+ << "this->" << state << "." << member << " = 0;"
+ << "return r;";
+
+ os << "}";
+ }
+
+ private:
+ TypeName base_name_;
+
+ CompositorCallback compositor_callback_;
+ ParticleCallback particle_callback_;
+ Traversal::ContainsCompositor contains_compositor_callback_;
+ Traversal::ContainsParticle contains_particle_callback_;
+
+ AttributeCallback attribute_callback_;
+ Traversal::Names names_attribute_callback_;
+ };
+ }
+
+ Void
+ generate_parser_source (Context& ctx)
+ {
+ {
+ // Emit "weak" header includes for the object model types.
+ // Otherwise we cannot delete the objects of forward-declared
+ // classes in the parser implementations.
+ //
+ Traversal::Schema schema;
+ Includes includes (ctx, Includes::source);
+
+ schema >> includes;
+
+ schema.dispatch (ctx.schema_root);
+ }
+
+ Traversal::Schema schema;
+
+ Traversal::Sources sources;
+ Traversal::Names schema_names;
+
+ Namespace ns (ctx);
+ Traversal::Names names;
+
+ schema >> sources >> schema;
+ schema >> schema_names >> ns >> names;
+
+ List list (ctx);
+ Union union_ (ctx);
+ Complex complex (ctx);
+
+ names >> list;
+ names >> union_;
+ names >> complex;
+
+ schema.dispatch (ctx.schema_root);
+ }
+ }
+}