From f610d739fe2ebc0414d9821eaec2c2e866c0a0ac Mon Sep 17 00:00:00 2001 From: jez Date: Wed, 19 Nov 2008 17:26:07 +0000 Subject: [PATCH] More work on rejigging precedence. Templates are now constructed with their precedence. Variables are too, with a tweak to allow for the immediate evaluation of non-topl-level params and vars. The execution context now no longer needs to track variable precedence, which is good because it will be getting it wrong anyway. Corresponding simplifications follow to compliation context. --- .../impl/handler/xslt_include_handler.hpp | 3 ++- .../impl/handler/xslt_template_handler.hpp | 6 +++-- .../impl/handler/xslt_variable_handler.hpp | 17 ++++++++++---- .../XSLT/impl/xslt_compilation_context.hpp | 15 ++++++++++++ .../XSLT/impl/xslt_compiled_stylesheet.hpp | 23 +++++++------------ include/XSLT/impl/xslt_execution_context.hpp | 9 ++------ include/XSLT/impl/xslt_param.hpp | 5 ++-- include/XSLT/impl/xslt_precedence.hpp | 18 ++++++++------- include/XSLT/impl/xslt_template.hpp | 14 +++++++---- include/XSLT/impl/xslt_top_level_param.hpp | 1 + include/XSLT/impl/xslt_variable.hpp | 5 ++-- include/XSLT/impl/xslt_variable_impl.hpp | 9 ++++++-- include/XSLT/impl/xslt_with_param.hpp | 5 ++-- vs9/example_XSLT_Mangle.vcproj | 8 +++++++ 14 files changed, 89 insertions(+), 49 deletions(-) diff --git a/include/XSLT/impl/handler/xslt_include_handler.hpp b/include/XSLT/impl/handler/xslt_include_handler.hpp index 5a1d9f29..51af9bb5 100644 --- a/include/XSLT/impl/handler/xslt_include_handler.hpp +++ b/include/XSLT/impl/handler/xslt_include_handler.hpp @@ -113,8 +113,9 @@ public: { std::vector::iterator import = import_stack_.end()-1; size_t index = import_stack_.size() - 1; - context_->stylesheet().push_import_precedence(); + context_->push_import_precedence(); include_stylesheet(import_stack_.back()); + context_->pop_import_precedence(); import_stack_.erase(import_stack_.begin() + index); } // while ... } // unwind_imports diff --git a/include/XSLT/impl/handler/xslt_template_handler.hpp b/include/XSLT/impl/handler/xslt_template_handler.hpp index 972fe2e5..cd9ff72f 100755 --- a/include/XSLT/impl/handler/xslt_template_handler.hpp +++ b/include/XSLT/impl/handler/xslt_template_handler.hpp @@ -71,12 +71,14 @@ protected: if(match == "") return new Template(name, mode, - attributes["priority"]); + attributes["priority"], + context().precedence()); return new Template(context().xpath_match(match), name, mode, - atts.getValue("priority")); + atts.getValue("priority"), + context().precedence()); } // createContainer virtual bool createChild(const std::string& namespaceURI, diff --git a/include/XSLT/impl/handler/xslt_variable_handler.hpp b/include/XSLT/impl/handler/xslt_variable_handler.hpp index 79c1209a..91a0b323 100644 --- a/include/XSLT/impl/handler/xslt_variable_handler.hpp +++ b/include/XSLT/impl/handler/xslt_variable_handler.hpp @@ -16,7 +16,15 @@ class VariableHandler : public ItemContainerHandler public: VariableHandler(CompilationContext& context) : ItemContainerHandler(context), - has_select_(false) + has_select_(false), + precedence_(Precedence::FrozenPrecedence()) + { + } // VariableHandler + + VariableHandler(CompilationContext& context, const Precedence& precedence) : + ItemContainerHandler(context), + has_select_(false), + precedence_(precedence) { } // VariableHandler @@ -42,7 +50,7 @@ protected: } // if ... std::pair name = this->context().processInternalQName(attrs["name"]); - return new VType(name.first, name.second, xpath); + return new VType(name.first, name.second, xpath, precedence_); } // createContainer virtual void characters(const std::string& ch) @@ -58,6 +66,7 @@ protected: private: bool has_select_; + const Precedence precedence_; }; // class VariableHandler template @@ -65,7 +74,7 @@ class TopLevelVariableHandler : public VariableHandler { public: TopLevelVariableHandler(CompilationContext& context) : - VariableHandler(context) + VariableHandler(context, context.precedence()) { } // VariableHandler @@ -73,7 +82,7 @@ public: const std::string& localName, const std::string& qName) { - this->context().stylesheet().add_item(this->container()); + this->context().stylesheet().add_variable(this->container()); this->context().pop(); } // endElement diff --git a/include/XSLT/impl/xslt_compilation_context.hpp b/include/XSLT/impl/xslt_compilation_context.hpp index 75e3dcc6..632b2294 100755 --- a/include/XSLT/impl/xslt_compilation_context.hpp +++ b/include/XSLT/impl/xslt_compilation_context.hpp @@ -139,6 +139,20 @@ public: return ss.str(); } // autoNamespacePrefix + void push_import_precedence() + { + precedenceStack_.push(); + stylesheet_.push_import_precedence(); + } // push_import_precedence + + void pop_import_precedence() + { + } // pop_import_precedence + + const Precedence& precedence() const + { + return precedenceStack_.top(); + } // precedence private: // FunctionResolver @@ -185,6 +199,7 @@ private: std::stack*> handlerStack_; std::stack parentStack_; std::map namespaceRemap_; + PrecedenceStack precedenceStack_; CompilationContext(const CompilationContext&); mutable int autoNs_; diff --git a/include/XSLT/impl/xslt_compiled_stylesheet.hpp b/include/XSLT/impl/xslt_compiled_stylesheet.hpp index 856b1fb8..b3486238 100755 --- a/include/XSLT/impl/xslt_compiled_stylesheet.hpp +++ b/include/XSLT/impl/xslt_compiled_stylesheet.hpp @@ -35,9 +35,8 @@ public: virtual ~CompiledStylesheet() { // let's clean up! - for(ItemStack::const_iterator isi = items_.begin(), ise = items_.end(); isi != ise; ++isi) - for(ItemList::const_iterator ci = isi->begin(), ce = isi->end(); ci != ce; ++ci) - delete *ci; + for(VariableDeclList::const_iterator ci = topLevelVars_.begin(), ce = topLevelVars_.end(); ci != ce; ++ci) + delete *ci; for(ParamList::const_iterator pi = params_.begin(), pe = params_.end(); pi != pe; ++pi) delete *pi; for(TemplateList::const_iterator ti = all_templates_.begin(), te = all_templates_.end(); ti != te; ++ti) @@ -84,12 +83,8 @@ public: // set up variables and so forth for(ParamList::const_iterator pi = params_.begin(), pe = params_.end(); pi != pe; ++pi) (*pi)->declare(context); - for(ItemStack::const_iterator isi = items_.begin(), ise = items_.end(); isi != ise; ++isi) - { - for(ItemList::const_iterator ci = isi->begin(), ce = isi->end(); ci != ce; ++ci) - (*ci)->execute(initialNode, context); - context.pushVariablePrecedence(); - } // for ... + for(VariableDeclList::const_iterator ci = topLevelVars_.begin(), ce = topLevelVars_.end(); ci != ce; ++ci) + (*ci)->execute(initialNode, context); context.freezeTopLevel(); // go! @@ -127,12 +122,11 @@ public: void push_import_precedence() { templates_.push_back(ModeTemplates()); - items_.push_back(ItemList()); } // push_import_precedence - void add_item(Item* item) + void add_variable(Item* item) { - items_.back().push_back(item); + topLevelVars_.push_back(item); } // add_item void output_settings(const Output::Settings& settings) @@ -310,15 +304,14 @@ private: typedef std::vector TemplateStack; typedef std::map, Template*> NamedTemplates; - typedef std::vector ItemList; - typedef std::vector ItemStack; + typedef std::vector VariableDeclList; typedef std::vector ParamList; TemplateList all_templates_; NamedTemplates named_templates_; TemplateStack templates_; - ItemStack items_; + VariableDeclList topLevelVars_; ParamList params_; std::vector current_import_precedence_; diff --git a/include/XSLT/impl/xslt_execution_context.hpp b/include/XSLT/impl/xslt_execution_context.hpp index e4b5c78f..b1bdb101 100755 --- a/include/XSLT/impl/xslt_execution_context.hpp +++ b/include/XSLT/impl/xslt_execution_context.hpp @@ -24,6 +24,7 @@ public: virtual Arabica::XPath::XPathValue value(const DOM::Node& node, ExecutionContext& context, DOMSink& sink) const = 0; + virtual const Precedence& precedence() const = 0; private: Variable_declaration(const Variable_declaration&); @@ -40,7 +41,6 @@ public: stylesheet_(stylesheet), sink_(output.asOutput()), message_sink_(error_output), - variable_precedence_(), to_msg_(0) { xpathContext_.setVariableResolver(stack_); @@ -54,7 +54,6 @@ public: stack_(rhs.stack_), sink_(output.asOutput()), message_sink_(rhs.message_sink_), - variable_precedence_(rhs.variable_precedence_), to_msg_(false) { xpathContext_.setVariableResolver(stack_); @@ -79,8 +78,6 @@ public: void unpassParam(const std::string& name); void declareParam(const DOM::Node& node, const Variable_declaration& param); void declareVariable(const DOM::Node& node, const Variable_declaration& variable); - void pushVariablePrecedence() { variable_precedence_.push(); } - const Precedence& variablePrecedence() const { return variable_precedence_.top(); } void freezeTopLevel(); void injectGlobalScope(const Scope& scope); @@ -106,7 +103,6 @@ private: private: const CompiledStylesheet& stylesheet_; VariableStack stack_; - PrecedenceStack variable_precedence_; Arabica::XPath::ExecutionContext xpathContext_; Output& sink_; StreamSink message_sink_; @@ -129,7 +125,7 @@ public: virtual const std::string& namespace_uri() const { return var_.namespace_uri(); } virtual const std::string& name() const { return var_.name(); } - virtual const Precedence& precedence() const { return context_.variablePrecedence(); } + virtual const Precedence& precedence() const { return var_.precedence(); } virtual Arabica::XPath::XPathValue value() const { @@ -195,7 +191,6 @@ void ExecutionContext::declareVariable(const DOM::Node& node, const void ExecutionContext::freezeTopLevel() { stack_.freezeTopLevel(); - variable_precedence_.freeze(); } // freezeTopLevel void ExecutionContext::injectGlobalScope(const Scope& scope) diff --git a/include/XSLT/impl/xslt_param.hpp b/include/XSLT/impl/xslt_param.hpp index 8b147648..94954615 100644 --- a/include/XSLT/impl/xslt_param.hpp +++ b/include/XSLT/impl/xslt_param.hpp @@ -13,8 +13,9 @@ class Param : public Variable_impl public: Param(const std::string& namespace_uri, const std::string& name, - Arabica::XPath::XPathExpressionPtr select) : - Variable_impl(namespace_uri, name, select) + Arabica::XPath::XPathExpressionPtr select, + const Precedence& precedence) : + Variable_impl(namespace_uri, name, select, precedence) { } // Param diff --git a/include/XSLT/impl/xslt_precedence.hpp b/include/XSLT/impl/xslt_precedence.hpp index 6ba51a48..4f349be3 100755 --- a/include/XSLT/impl/xslt_precedence.hpp +++ b/include/XSLT/impl/xslt_precedence.hpp @@ -4,13 +4,13 @@ class Precedence { public: - static Precedence InitialPrecedence() + static const Precedence& InitialPrecedence() { static Precedence initial_(0); return initial_; } // Precedence - static Precedence FrozenPrecedence() + static const Precedence& FrozenPrecedence() { static Precedence frozen_(-1); return frozen_; @@ -74,7 +74,7 @@ public: PrecedenceStack() : stack_() { - stack_.push_back(Precedence::InitialPrecedence()); + stack_.push(Precedence::InitialPrecedence()); } // PrecedenceStack PrecedenceStack(const PrecedenceStack& rhs) : @@ -82,15 +82,17 @@ public: { } // PrecedenceStack - const Precedence& top() const { return stack_[stack_.size()-1]; } - void push() { stack_.push_back(top().nextGeneration(stack_.size())); } + const Precedence& top() const { return stack_.top(); } + void push() { stack_.push(top().nextGeneration(stack_.size())); } + void pop() { stack_.pop(); } void freeze() { - stack_.clear(); - stack_.push_back(Precedence::FrozenPrecedence()); + while(!stack_.empty()) + stack_.pop(); + stack_.push(Precedence::FrozenPrecedence()); } // freeze private: - std::vector stack_; + std::stack stack_; }; // class PrecedenceStack #endif diff --git a/include/XSLT/impl/xslt_template.hpp b/include/XSLT/impl/xslt_template.hpp index 43f264aa..c1c4e9f1 100755 --- a/include/XSLT/impl/xslt_template.hpp +++ b/include/XSLT/impl/xslt_template.hpp @@ -14,20 +14,24 @@ class Template : public ItemContainer public: Template(const std::pair& name, const std::pair& mode, - const std::string& priority) : + const std::string& priority, + const Precedence& precedence) : matches_(), name_(name), - mode_(mode) + mode_(mode), + precedence_(precedence) { } // Template Template(const std::vector >& matches, const std::pair& name, const std::pair& mode, - const std::string& priority) : + const std::string& priority, + const Precedence& precedence) : matches_(matches), name_(name), - mode_(mode) + mode_(mode), + precedence_(precedence) { if(!priority.empty()) { @@ -50,11 +54,13 @@ public: bool has_name() const { return !name_.second.empty(); } const std::pair& name() const { return name_; } const std::pair& mode() const { return mode_; } + const Precedence& precedence() const { return precedence_; } private: std::vector > matches_; std::pair name_; std::pair mode_; + const Precedence precedence_; }; // class Template } // namespace XSLT diff --git a/include/XSLT/impl/xslt_top_level_param.hpp b/include/XSLT/impl/xslt_top_level_param.hpp index 214d0e53..1fe87476 100644 --- a/include/XSLT/impl/xslt_top_level_param.hpp +++ b/include/XSLT/impl/xslt_top_level_param.hpp @@ -33,6 +33,7 @@ public: { return value_; } // value + virtual const Precedence& precedence() const { return Precedence::InitialPrecedence(); } private: static DOM::Node null_node; diff --git a/include/XSLT/impl/xslt_variable.hpp b/include/XSLT/impl/xslt_variable.hpp index c7d5bd8b..7e8aabb3 100644 --- a/include/XSLT/impl/xslt_variable.hpp +++ b/include/XSLT/impl/xslt_variable.hpp @@ -13,8 +13,9 @@ class Variable : public Variable_impl public: Variable(const std::string& namespace_uri, const std::string& name, - Arabica::XPath::XPathExpressionPtr select) : - Variable_impl(namespace_uri, name, select) + Arabica::XPath::XPathExpressionPtr select, + const Precedence precedence) : + Variable_impl(namespace_uri, name, select, precedence) { } // Variable diff --git a/include/XSLT/impl/xslt_variable_impl.hpp b/include/XSLT/impl/xslt_variable_impl.hpp index db42e398..977f028c 100644 --- a/include/XSLT/impl/xslt_variable_impl.hpp +++ b/include/XSLT/impl/xslt_variable_impl.hpp @@ -16,10 +16,12 @@ class Variable_impl : public ItemContainer, public Variable_declaration protected: Variable_impl(const std::string& namespace_uri, const std::string& name, - Arabica::XPath::XPathExpressionPtr select) : + Arabica::XPath::XPathExpressionPtr select, + const Precedence& precedence) : namespace_uri_(namespace_uri), name_(name), - select_(select) + select_(select), + precedence_(precedence) { } // Variable_impl @@ -48,10 +50,13 @@ public: return Arabica::XPath::NodeSetValue >::createValue(nodeset); } // value + virtual const Precedence& precedence() const { return precedence_; } + private: std::string namespace_uri_; std::string name_; Arabica::XPath::XPathExpressionPtr select_; + Precedence precedence_; }; // Variable_impl } // namespace XSLT diff --git a/include/XSLT/impl/xslt_with_param.hpp b/include/XSLT/impl/xslt_with_param.hpp index c37f41aa..ac590103 100644 --- a/include/XSLT/impl/xslt_with_param.hpp +++ b/include/XSLT/impl/xslt_with_param.hpp @@ -13,8 +13,9 @@ class WithParam : public Variable_impl public: WithParam(const std::string& namespace_uri, const std::string& name, - Arabica::XPath::XPathExpressionPtr select) : - Variable_impl(namespace_uri, name, select) + Arabica::XPath::XPathExpressionPtr select, + const Precedence& precedence) : + Variable_impl(namespace_uri, name, select, precedence) { } // WithParam diff --git a/vs9/example_XSLT_Mangle.vcproj b/vs9/example_XSLT_Mangle.vcproj index 53bd7eac..e603fe11 100644 --- a/vs9/example_XSLT_Mangle.vcproj +++ b/vs9/example_XSLT_Mangle.vcproj @@ -224,6 +224,10 @@ RelativePath="..\include\Xslt\impl\xslt_compilation_context.hpp" > + + @@ -268,6 +272,10 @@ RelativePath="..\include\Xslt\impl\xslt_param.hpp" > + +