aboutsummaryrefslogtreecommitdiff
path: root/xsde/cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2011-02-11 17:18:30 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2011-02-11 17:18:30 +0200
commit49d8e39f9a42ff1963c5df0f6e9ed903d66f2eb0 (patch)
tree17cb3577baa07e30720788e059399f7c07c22a37 /xsde/cxx
parentbcf2ac66e6c21d75f4e76b8e0bc2e3c6d64886b8 (diff)
Fix recursive polymorphic parsing in C++/Parser
New test: cxx/parser/polyrecur.
Diffstat (limited to 'xsde/cxx')
-rw-r--r--xsde/cxx/parser/element-validation-source.cxx58
-rw-r--r--xsde/cxx/parser/elements.cxx6
-rw-r--r--xsde/cxx/parser/elements.hxx3
-rw-r--r--xsde/cxx/parser/name-processor.cxx8
-rw-r--r--xsde/cxx/parser/parser-header.cxx3
-rw-r--r--xsde/cxx/parser/parser-source.cxx83
6 files changed, 74 insertions, 87 deletions
diff --git a/xsde/cxx/parser/element-validation-source.cxx b/xsde/cxx/parser/element-validation-source.cxx
index eec0c2f..92eb73c 100644
--- a/xsde/cxx/parser/element-validation-source.cxx
+++ b/xsde/cxx/parser/element-validation-source.cxx
@@ -386,23 +386,27 @@ namespace CXX
Boolean poly (poly_code && !anonymous (type));
String const& name (ename (*e));
- String inst (poly ? emember_cache (*e) : emember (*e));
+ String fq_type (fq_name (type));
- String def_parser, map;
+ String def_parser, map, inst;
if (poly)
{
def_parser = emember (*e);
map = emember_map (*e);
+ inst = "p";
}
+ else
+ inst = L"this->" + emember (*e);
if (poly)
{
String cast (mixin ? L"dynamic_cast" : L"static_cast");
- String fq_type (fq_name (type));
- os << "if (t == 0 && this->" << def_parser << " != 0)" << endl
- << "this->" << inst << " = this->" << def_parser << ";"
+ os << fq_type << "* p = 0;"
+ << endl
+ << "if (t == 0 && this->" << def_parser << " != 0)" << endl
+ << inst << " = this->" << def_parser << ";"
<< "else"
<< "{"
<< "const char* ts = " << fq_type << "::_static_type ();"
@@ -412,7 +416,7 @@ namespace CXX
<< endl
<< "if (this->" << def_parser << " != 0 && " <<
"strcmp (t, ts) == 0)" << endl
- << "this->" << inst << " = this->" << def_parser << ";"
+ << inst << " = this->" << def_parser << ";"
<< "else"
<< "{";
@@ -427,50 +431,46 @@ namespace CXX
<< "}";
os << "if (this->" << map << " != 0)" << endl
- << "this->" << inst << " = " << cast << "< " <<
- fq_type << "* > (" << endl
+ << inst << " = " << cast << "< " << fq_type << "* > (" << endl
<< "this->" << map << "->find (t));"
- << "else" << endl
- << "this->" << inst << " = 0;"
<< "}"
<< "}";
}
String const& post (post_name (type));
- os << "if (this->" << inst << ")"
+ os << "if (" << inst << ")"
<< "{"
- << "this->" << inst << "->pre ();";
+ << inst << "->pre ();";
if (!exceptions)
{
- // Note that after pre() we need to check both parser and
- // context error states because of the recursive parsing.
- //
os << endl
- << "if (this->" << inst << "->_error_type ())" << endl
- << "this->" << inst << "->_copy_error (ctx);"
- << endl
- << "if (!ctx.error_type ())" << endl;
+ << "if (" << inst << "->_error_type ())" << endl
+ << inst << "->_copy_error (ctx);"
+ << endl;
}
- os << "this->" << inst << "->_pre_impl (ctx);"
+ os << "ctx.nested_parser (" << inst << ");" << endl
<< "}"
- << "else" << endl
- << "ctx.current_.depth_++;" // Ignoring document fragment.
- << endl
<< "}"
<< "else" // start
- << "{"
- << "if (this->" << inst << ")"
+ << "{";
+
+ if (poly)
+ os << fq_type << "* p =" << endl
+ << "static_cast< " << fq_type << "* > (ctx.nested_parser ());"
+ << endl;
+
+ os << "if (" << inst << " != 0)"
<< "{";
String const& ret (ret_type (type));
if (ret == L"void")
- os << "this->" << inst << "->" << post << " ();";
+ os << inst << "->" << post << " ();";
else
- os << arg_type (type) << " tmp = this->" << inst << "->" <<
+ os << arg_type (type) << " tmp = " << inst << "->" <<
post << " ();";
if (!exceptions)
@@ -479,8 +479,8 @@ namespace CXX
// context error states because of the recursive parsing.
//
os << endl
- << "if (this->" << inst << "->_error_type ())" << endl
- << "this->" << inst << "->_copy_error (ctx);"
+ << "if (" << inst << "->_error_type ())" << endl
+ << inst << "->_copy_error (ctx);"
<< endl
<< "if (!ctx.error_type ())" << endl;
}
diff --git a/xsde/cxx/parser/elements.cxx b/xsde/cxx/parser/elements.cxx
index 2ef3a23..1e58262 100644
--- a/xsde/cxx/parser/elements.cxx
+++ b/xsde/cxx/parser/elements.cxx
@@ -171,12 +171,6 @@ namespace CXX
}
String const& Context::
- emember_cache (SemanticGraph::Member& m)
- {
- return m.context ().get<String> ("p:member-cache");
- }
-
- String const& Context::
emember_map (SemanticGraph::Member& m)
{
return m.context ().get<String> ("p:member-map");
diff --git a/xsde/cxx/parser/elements.hxx b/xsde/cxx/parser/elements.hxx
index e6d755f..020e51b 100644
--- a/xsde/cxx/parser/elements.hxx
+++ b/xsde/cxx/parser/elements.hxx
@@ -151,9 +151,6 @@ namespace CXX
emember (SemanticGraph::Member&);
static String const&
- emember_cache (SemanticGraph::Member&);
-
- static String const&
emember_map (SemanticGraph::Member&);
static String const&
diff --git a/xsde/cxx/parser/name-processor.cxx b/xsde/cxx/parser/name-processor.cxx
index d6d7340..c3c2ec3 100644
--- a/xsde/cxx/parser/name-processor.cxx
+++ b/xsde/cxx/parser/name-processor.cxx
@@ -417,13 +417,8 @@ namespace CXX
ec.set ("p:member", find_name (base + L"_parser_", set_));
if (poly)
- {
- ec.set (
- "p:member-cache", find_name (base + L"_parser_cache_", set_));
-
ec.set (
"p:member-map", find_name (base + L"_parser_map_", set_));
- }
}
else
{
@@ -435,10 +430,7 @@ namespace CXX
ec.set ("p:member", bc.get<String> ("p:member"));
if (poly)
- {
- ec.set ("p:member-cache", bc.get<String> ("p:member-cache"));
ec.set ("p:member-map", bc.get<String> ("p:member-map"));
- }
}
}
diff --git a/xsde/cxx/parser/parser-header.cxx b/xsde/cxx/parser/parser-header.cxx
index 3b8663c..9d45b45 100644
--- a/xsde/cxx/parser/parser-header.cxx
+++ b/xsde/cxx/parser/parser-header.cxx
@@ -547,8 +547,7 @@ namespace CXX
if (poly_code && !anonymous (e.type ()))
{
- os << type << "* " << emember_cache (e) << ";"
- << parser_map << "* " << emember_map (e) << ";"
+ os << parser_map << "* " << emember_map (e) << ";"
<< endl;
}
}
diff --git a/xsde/cxx/parser/parser-source.cxx b/xsde/cxx/parser/parser-source.cxx
index 5c5093f..47e4867 100644
--- a/xsde/cxx/parser/parser-source.cxx
+++ b/xsde/cxx/parser/parser-source.cxx
@@ -493,7 +493,6 @@ namespace CXX
{
Boolean poly (poly_code && !anonymous (e.type ()));
Boolean subst (poly && e.global_p ());
- String const& inst (poly ? emember_cache (e) : emember (e));
if (e.qualified_p () && e.namespace_ ().name ())
{
@@ -528,6 +527,8 @@ namespace CXX
os << ")"
<< "{";
+ String inst;
+
if (poly)
{
// In case of mixin we use virtual inheritance and only
@@ -537,9 +538,12 @@ namespace CXX
String fq_type (fq_name (e.type ()));
String const& member (emember (e));
String const& member_map (emember_map (e));
+ inst = "p";
- os << "if (t == 0 && this->" << member << " != 0)" << endl
- << "this->" << inst << " = this->" << member << ";"
+ os << fq_type << "* p = 0;"
+ << endl
+ << "if (t == 0 && this->" << member << " != 0)" << endl
+ << inst << " = this->" << member << ";"
<< "else"
<< "{"
<< "const char* ts = " << fq_type << "::_static_type ();"
@@ -549,42 +553,30 @@ namespace CXX
<< endl
<< "if (this->" << member << " != 0 && " <<
"strcmp (t, ts) == 0)" << endl
- << "this->" << inst << " = this->" << member << ";"
+ << inst << " = this->" << member << ";"
<< "else if (this->" << member_map << " != 0)" << endl
- << "this->" << inst << " = " << cast << "< " << fq_type <<
+ << inst << " = " << cast << "< " << fq_type <<
"* > (" << endl
<< "this->" << member_map << "->find (t));"
- << "else" << endl
- << "this->" << inst << " = 0;"
<< "}";
}
+ else
+ inst = L"this->" + emember (e);
- os << "if (this->" << inst << ")"
- << "{";
+ os << "if (" << inst << ")"
+ << "{"
+ << inst << "->pre ();";
- if (exceptions)
+ if (!exceptions)
{
- os << "this->" << inst << "->pre ();"
- << "this->" << inst << "->_pre_impl (ctx);";
- }
- else
- {
- // Note that after pre() we need to check both parser and
- // context error states because of the recursive parsing.
- //
- os << "this->" << inst << "->pre ();"
- << endl
- << "if (this->" << inst << "->_error_type ())" << endl
- << "this->" << inst << "->_copy_error (ctx);"
- << endl
- << "if (!ctx.error_type ())" << endl
- << "this->" << inst << "->_pre_impl (ctx);";
+ os << endl
+ << "if (" << inst << "->_error_type ())" << endl
+ << inst << "->_copy_error (ctx);"
+ << endl;
}
- os << "}"
- << "else" << endl
- << "ctx.current_.depth_++;" // Ignoring document fragment.
- << endl
+ os << "ctx.nested_parser (" << inst << ");" << endl
+ << "}"
<< "return true;"
<< "}";
}
@@ -606,7 +598,6 @@ namespace CXX
String const& name (ename (e));
Boolean poly (poly_code && !anonymous (e.type ()));
Boolean subst (poly && e.global_p ());
- String const& inst (poly ? emember_cache (e) : emember (e));
if (e.qualified_p () && e.namespace_ ().name ())
{
@@ -643,17 +634,31 @@ namespace CXX
SemanticGraph::Type& type (e.type ());
String const& post (post_name (type));
+ String inst;
- os << "if (this->" << inst << ")"
+ if (poly)
+ {
+ String fq_type (fq_name (e.type ()));
+ inst = "p";
+
+ os << fq_type << "* p =" << endl
+ << "static_cast< " << fq_type << "* > (" <<
+ "this->_context ().nested_parser ());"
+ << endl;
+ }
+ else
+ inst = L"this->" + emember (e);
+
+ os << "if (" << inst << ")"
<< "{";
if (exceptions)
{
if (ret_type (type) == L"void")
- os << "this->" << inst << "->" << post << " ();"
+ os << inst << "->" << post << " ();"
<< "this->" << name << " ();";
else
- os << "this->" << name << " (this->" << inst << "->" <<
+ os << "this->" << name << " (" << inst << "->" <<
post << " ());";
}
else
@@ -663,21 +668,21 @@ namespace CXX
//
if (ret_type (type) == L"void")
{
- os << "this->" << inst << "->" << post << " ();"
+ os << inst << "->" << post << " ();"
<< endl
- << "if (this->" << inst << "->_error_type ())" << endl
- << "this->" << inst << "->_copy_error (ctx);"
+ << "if (" << inst << "->_error_type ())" << endl
+ << inst << "->_copy_error (ctx);"
<< endl
<< "if (!ctx.error_type ())" << endl
<< "this->" << name << " ();";
}
else
{
- os << arg_type (type) << " tmp = this->" << inst << "->" <<
+ os << arg_type (type) << " tmp = " << inst << "->" <<
post << " ();"
<< endl
- << "if (this->" << inst << "->_error_type ())" << endl
- << "this->" << inst << "->_copy_error (ctx);"
+ << "if (" << inst << "->_error_type ())" << endl
+ << inst << "->_copy_error (ctx);"
<< endl
<< "if (!ctx.error_type ())" << endl
<< "this->" << name << " (tmp);";