From 49d8e39f9a42ff1963c5df0f6e9ed903d66f2eb0 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 11 Feb 2011 17:18:30 +0200 Subject: Fix recursive polymorphic parsing in C++/Parser New test: cxx/parser/polyrecur. --- xsde/cxx/parser/element-validation-source.cxx | 58 +++++++++---------- xsde/cxx/parser/elements.cxx | 6 -- xsde/cxx/parser/elements.hxx | 3 - xsde/cxx/parser/name-processor.cxx | 8 --- xsde/cxx/parser/parser-header.cxx | 3 +- xsde/cxx/parser/parser-source.cxx | 83 ++++++++++++++------------- 6 files changed, 74 insertions(+), 87 deletions(-) (limited to 'xsde/cxx') 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 ("p:member-cache"); - } - - String const& Context:: emember_map (SemanticGraph::Member& m) { return m.context ().get ("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 ("p:member")); if (poly) - { - ec.set ("p:member-cache", bc.get ("p:member-cache")); ec.set ("p:member-map", bc.get ("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);"; -- cgit v1.1