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.
This commit is contained in:
jez 2008-11-19 17:26:07 +00:00
parent 8d0ce36da3
commit f610d739fe
14 changed files with 89 additions and 49 deletions

View file

@ -113,8 +113,9 @@ public:
{ {
std::vector<std::string>::iterator import = import_stack_.end()-1; std::vector<std::string>::iterator import = import_stack_.end()-1;
size_t index = import_stack_.size() - 1; size_t index = import_stack_.size() - 1;
context_->stylesheet().push_import_precedence(); context_->push_import_precedence();
include_stylesheet(import_stack_.back()); include_stylesheet(import_stack_.back());
context_->pop_import_precedence();
import_stack_.erase(import_stack_.begin() + index); import_stack_.erase(import_stack_.begin() + index);
} // while ... } // while ...
} // unwind_imports } // unwind_imports

View file

@ -71,12 +71,14 @@ protected:
if(match == "") if(match == "")
return new Template(name, return new Template(name,
mode, mode,
attributes["priority"]); attributes["priority"],
context().precedence());
return new Template(context().xpath_match(match), return new Template(context().xpath_match(match),
name, name,
mode, mode,
atts.getValue("priority")); atts.getValue("priority"),
context().precedence());
} // createContainer } // createContainer
virtual bool createChild(const std::string& namespaceURI, virtual bool createChild(const std::string& namespaceURI,

View file

@ -16,7 +16,15 @@ class VariableHandler : public ItemContainerHandler<VType>
public: public:
VariableHandler(CompilationContext& context) : VariableHandler(CompilationContext& context) :
ItemContainerHandler<VType>(context), ItemContainerHandler<VType>(context),
has_select_(false) has_select_(false),
precedence_(Precedence::FrozenPrecedence())
{
} // VariableHandler
VariableHandler(CompilationContext& context, const Precedence& precedence) :
ItemContainerHandler<VType>(context),
has_select_(false),
precedence_(precedence)
{ {
} // VariableHandler } // VariableHandler
@ -42,7 +50,7 @@ protected:
} // if ... } // if ...
std::pair<std::string, std::string> name = this->context().processInternalQName(attrs["name"]); std::pair<std::string, std::string> name = this->context().processInternalQName(attrs["name"]);
return new VType(name.first, name.second, xpath); return new VType(name.first, name.second, xpath, precedence_);
} // createContainer } // createContainer
virtual void characters(const std::string& ch) virtual void characters(const std::string& ch)
@ -58,6 +66,7 @@ protected:
private: private:
bool has_select_; bool has_select_;
const Precedence precedence_;
}; // class VariableHandler }; // class VariableHandler
template<class VType> template<class VType>
@ -65,7 +74,7 @@ class TopLevelVariableHandler : public VariableHandler<VType>
{ {
public: public:
TopLevelVariableHandler(CompilationContext& context) : TopLevelVariableHandler(CompilationContext& context) :
VariableHandler<VType>(context) VariableHandler<VType>(context, context.precedence())
{ {
} // VariableHandler } // VariableHandler
@ -73,7 +82,7 @@ public:
const std::string& localName, const std::string& localName,
const std::string& qName) const std::string& qName)
{ {
this->context().stylesheet().add_item(this->container()); this->context().stylesheet().add_variable(this->container());
this->context().pop(); this->context().pop();
} // endElement } // endElement

View file

@ -139,6 +139,20 @@ public:
return ss.str(); return ss.str();
} // autoNamespacePrefix } // 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: private:
// FunctionResolver // FunctionResolver
@ -185,6 +199,7 @@ private:
std::stack<SAX::DefaultHandler<std::string>*> handlerStack_; std::stack<SAX::DefaultHandler<std::string>*> handlerStack_;
std::stack<ItemContainer*> parentStack_; std::stack<ItemContainer*> parentStack_;
std::map<std::string, Namespace> namespaceRemap_; std::map<std::string, Namespace> namespaceRemap_;
PrecedenceStack precedenceStack_;
CompilationContext(const CompilationContext&); CompilationContext(const CompilationContext&);
mutable int autoNs_; mutable int autoNs_;

View file

@ -35,9 +35,8 @@ public:
virtual ~CompiledStylesheet() virtual ~CompiledStylesheet()
{ {
// let's clean up! // let's clean up!
for(ItemStack::const_iterator isi = items_.begin(), ise = items_.end(); isi != ise; ++isi) for(VariableDeclList::const_iterator ci = topLevelVars_.begin(), ce = topLevelVars_.end(); ci != ce; ++ci)
for(ItemList::const_iterator ci = isi->begin(), ce = isi->end(); ci != ce; ++ci) delete *ci;
delete *ci;
for(ParamList::const_iterator pi = params_.begin(), pe = params_.end(); pi != pe; ++pi) for(ParamList::const_iterator pi = params_.begin(), pe = params_.end(); pi != pe; ++pi)
delete *pi; delete *pi;
for(TemplateList::const_iterator ti = all_templates_.begin(), te = all_templates_.end(); ti != te; ++ti) 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 // set up variables and so forth
for(ParamList::const_iterator pi = params_.begin(), pe = params_.end(); pi != pe; ++pi) for(ParamList::const_iterator pi = params_.begin(), pe = params_.end(); pi != pe; ++pi)
(*pi)->declare(context); (*pi)->declare(context);
for(ItemStack::const_iterator isi = items_.begin(), ise = items_.end(); isi != ise; ++isi) for(VariableDeclList::const_iterator ci = topLevelVars_.begin(), ce = topLevelVars_.end(); ci != ce; ++ci)
{ (*ci)->execute(initialNode, context);
for(ItemList::const_iterator ci = isi->begin(), ce = isi->end(); ci != ce; ++ci)
(*ci)->execute(initialNode, context);
context.pushVariablePrecedence();
} // for ...
context.freezeTopLevel(); context.freezeTopLevel();
// go! // go!
@ -127,12 +122,11 @@ public:
void push_import_precedence() void push_import_precedence()
{ {
templates_.push_back(ModeTemplates()); templates_.push_back(ModeTemplates());
items_.push_back(ItemList());
} // push_import_precedence } // push_import_precedence
void add_item(Item* item) void add_variable(Item* item)
{ {
items_.back().push_back(item); topLevelVars_.push_back(item);
} // add_item } // add_item
void output_settings(const Output::Settings& settings) void output_settings(const Output::Settings& settings)
@ -310,15 +304,14 @@ private:
typedef std::vector<ModeTemplates> TemplateStack; typedef std::vector<ModeTemplates> TemplateStack;
typedef std::map<std::pair<std::string, std::string>, Template*> NamedTemplates; typedef std::map<std::pair<std::string, std::string>, Template*> NamedTemplates;
typedef std::vector<Item*> ItemList; typedef std::vector<Item*> VariableDeclList;
typedef std::vector<ItemList> ItemStack;
typedef std::vector<TopLevelParam*> ParamList; typedef std::vector<TopLevelParam*> ParamList;
TemplateList all_templates_; TemplateList all_templates_;
NamedTemplates named_templates_; NamedTemplates named_templates_;
TemplateStack templates_; TemplateStack templates_;
ItemStack items_; VariableDeclList topLevelVars_;
ParamList params_; ParamList params_;
std::vector<int> current_import_precedence_; std::vector<int> current_import_precedence_;

View file

@ -24,6 +24,7 @@ public:
virtual Arabica::XPath::XPathValue<std::string> value(const DOM::Node<std::string>& node, virtual Arabica::XPath::XPathValue<std::string> value(const DOM::Node<std::string>& node,
ExecutionContext& context, ExecutionContext& context,
DOMSink& sink) const = 0; DOMSink& sink) const = 0;
virtual const Precedence& precedence() const = 0;
private: private:
Variable_declaration(const Variable_declaration&); Variable_declaration(const Variable_declaration&);
@ -40,7 +41,6 @@ public:
stylesheet_(stylesheet), stylesheet_(stylesheet),
sink_(output.asOutput()), sink_(output.asOutput()),
message_sink_(error_output), message_sink_(error_output),
variable_precedence_(),
to_msg_(0) to_msg_(0)
{ {
xpathContext_.setVariableResolver(stack_); xpathContext_.setVariableResolver(stack_);
@ -54,7 +54,6 @@ public:
stack_(rhs.stack_), stack_(rhs.stack_),
sink_(output.asOutput()), sink_(output.asOutput()),
message_sink_(rhs.message_sink_), message_sink_(rhs.message_sink_),
variable_precedence_(rhs.variable_precedence_),
to_msg_(false) to_msg_(false)
{ {
xpathContext_.setVariableResolver(stack_); xpathContext_.setVariableResolver(stack_);
@ -79,8 +78,6 @@ public:
void unpassParam(const std::string& name); void unpassParam(const std::string& name);
void declareParam(const DOM::Node<std::string>& node, const Variable_declaration& param); void declareParam(const DOM::Node<std::string>& node, const Variable_declaration& param);
void declareVariable(const DOM::Node<std::string>& node, const Variable_declaration& variable); void declareVariable(const DOM::Node<std::string>& node, const Variable_declaration& variable);
void pushVariablePrecedence() { variable_precedence_.push(); }
const Precedence& variablePrecedence() const { return variable_precedence_.top(); }
void freezeTopLevel(); void freezeTopLevel();
void injectGlobalScope(const Scope& scope); void injectGlobalScope(const Scope& scope);
@ -106,7 +103,6 @@ private:
private: private:
const CompiledStylesheet& stylesheet_; const CompiledStylesheet& stylesheet_;
VariableStack stack_; VariableStack stack_;
PrecedenceStack variable_precedence_;
Arabica::XPath::ExecutionContext<std::string> xpathContext_; Arabica::XPath::ExecutionContext<std::string> xpathContext_;
Output& sink_; Output& sink_;
StreamSink message_sink_; StreamSink message_sink_;
@ -129,7 +125,7 @@ public:
virtual const std::string& namespace_uri() const { return var_.namespace_uri(); } virtual const std::string& namespace_uri() const { return var_.namespace_uri(); }
virtual const std::string& name() const { return var_.name(); } 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<std::string> value() const virtual Arabica::XPath::XPathValue<std::string> value() const
{ {
@ -195,7 +191,6 @@ void ExecutionContext::declareVariable(const DOM::Node<std::string>& node, const
void ExecutionContext::freezeTopLevel() void ExecutionContext::freezeTopLevel()
{ {
stack_.freezeTopLevel(); stack_.freezeTopLevel();
variable_precedence_.freeze();
} // freezeTopLevel } // freezeTopLevel
void ExecutionContext::injectGlobalScope(const Scope& scope) void ExecutionContext::injectGlobalScope(const Scope& scope)

View file

@ -13,8 +13,9 @@ class Param : public Variable_impl
public: public:
Param(const std::string& namespace_uri, Param(const std::string& namespace_uri,
const std::string& name, const std::string& name,
Arabica::XPath::XPathExpressionPtr<std::string> select) : Arabica::XPath::XPathExpressionPtr<std::string> select,
Variable_impl(namespace_uri, name, select) const Precedence& precedence) :
Variable_impl(namespace_uri, name, select, precedence)
{ {
} // Param } // Param

View file

@ -4,13 +4,13 @@
class Precedence class Precedence
{ {
public: public:
static Precedence InitialPrecedence() static const Precedence& InitialPrecedence()
{ {
static Precedence initial_(0); static Precedence initial_(0);
return initial_; return initial_;
} // Precedence } // Precedence
static Precedence FrozenPrecedence() static const Precedence& FrozenPrecedence()
{ {
static Precedence frozen_(-1); static Precedence frozen_(-1);
return frozen_; return frozen_;
@ -74,7 +74,7 @@ public:
PrecedenceStack() : PrecedenceStack() :
stack_() stack_()
{ {
stack_.push_back(Precedence::InitialPrecedence()); stack_.push(Precedence::InitialPrecedence());
} // PrecedenceStack } // PrecedenceStack
PrecedenceStack(const PrecedenceStack& rhs) : PrecedenceStack(const PrecedenceStack& rhs) :
@ -82,15 +82,17 @@ public:
{ {
} // PrecedenceStack } // PrecedenceStack
const Precedence& top() const { return stack_[stack_.size()-1]; } const Precedence& top() const { return stack_.top(); }
void push() { stack_.push_back(top().nextGeneration(stack_.size())); } void push() { stack_.push(top().nextGeneration(stack_.size())); }
void pop() { stack_.pop(); }
void freeze() void freeze()
{ {
stack_.clear(); while(!stack_.empty())
stack_.push_back(Precedence::FrozenPrecedence()); stack_.pop();
stack_.push(Precedence::FrozenPrecedence());
} // freeze } // freeze
private: private:
std::vector<Precedence> stack_; std::stack<Precedence> stack_;
}; // class PrecedenceStack }; // class PrecedenceStack
#endif #endif

View file

@ -14,20 +14,24 @@ class Template : public ItemContainer
public: public:
Template(const std::pair<std::string, std::string>& name, Template(const std::pair<std::string, std::string>& name,
const std::pair<std::string, std::string>& mode, const std::pair<std::string, std::string>& mode,
const std::string& priority) : const std::string& priority,
const Precedence& precedence) :
matches_(), matches_(),
name_(name), name_(name),
mode_(mode) mode_(mode),
precedence_(precedence)
{ {
} // Template } // Template
Template(const std::vector<Arabica::XPath::MatchExpr<std::string> >& matches, Template(const std::vector<Arabica::XPath::MatchExpr<std::string> >& matches,
const std::pair<std::string, std::string>& name, const std::pair<std::string, std::string>& name,
const std::pair<std::string, std::string>& mode, const std::pair<std::string, std::string>& mode,
const std::string& priority) : const std::string& priority,
const Precedence& precedence) :
matches_(matches), matches_(matches),
name_(name), name_(name),
mode_(mode) mode_(mode),
precedence_(precedence)
{ {
if(!priority.empty()) if(!priority.empty())
{ {
@ -50,11 +54,13 @@ public:
bool has_name() const { return !name_.second.empty(); } bool has_name() const { return !name_.second.empty(); }
const std::pair<std::string, std::string>& name() const { return name_; } const std::pair<std::string, std::string>& name() const { return name_; }
const std::pair<std::string, std::string>& mode() const { return mode_; } const std::pair<std::string, std::string>& mode() const { return mode_; }
const Precedence& precedence() const { return precedence_; }
private: private:
std::vector<Arabica::XPath::MatchExpr<std::string> > matches_; std::vector<Arabica::XPath::MatchExpr<std::string> > matches_;
std::pair<std::string, std::string> name_; std::pair<std::string, std::string> name_;
std::pair<std::string, std::string> mode_; std::pair<std::string, std::string> mode_;
const Precedence precedence_;
}; // class Template }; // class Template
} // namespace XSLT } // namespace XSLT

View file

@ -33,6 +33,7 @@ public:
{ {
return value_; return value_;
} // value } // value
virtual const Precedence& precedence() const { return Precedence::InitialPrecedence(); }
private: private:
static DOM::Node<std::string> null_node; static DOM::Node<std::string> null_node;

View file

@ -13,8 +13,9 @@ class Variable : public Variable_impl
public: public:
Variable(const std::string& namespace_uri, Variable(const std::string& namespace_uri,
const std::string& name, const std::string& name,
Arabica::XPath::XPathExpressionPtr<std::string> select) : Arabica::XPath::XPathExpressionPtr<std::string> select,
Variable_impl(namespace_uri, name, select) const Precedence precedence) :
Variable_impl(namespace_uri, name, select, precedence)
{ {
} // Variable } // Variable

View file

@ -16,10 +16,12 @@ class Variable_impl : public ItemContainer, public Variable_declaration
protected: protected:
Variable_impl(const std::string& namespace_uri, Variable_impl(const std::string& namespace_uri,
const std::string& name, const std::string& name,
Arabica::XPath::XPathExpressionPtr<std::string> select) : Arabica::XPath::XPathExpressionPtr<std::string> select,
const Precedence& precedence) :
namespace_uri_(namespace_uri), namespace_uri_(namespace_uri),
name_(name), name_(name),
select_(select) select_(select),
precedence_(precedence)
{ {
} // Variable_impl } // Variable_impl
@ -48,10 +50,13 @@ public:
return Arabica::XPath::NodeSetValue<std::string, Arabica::default_string_adaptor<std::string> >::createValue(nodeset); return Arabica::XPath::NodeSetValue<std::string, Arabica::default_string_adaptor<std::string> >::createValue(nodeset);
} // value } // value
virtual const Precedence& precedence() const { return precedence_; }
private: private:
std::string namespace_uri_; std::string namespace_uri_;
std::string name_; std::string name_;
Arabica::XPath::XPathExpressionPtr<std::string> select_; Arabica::XPath::XPathExpressionPtr<std::string> select_;
Precedence precedence_;
}; // Variable_impl }; // Variable_impl
} // namespace XSLT } // namespace XSLT

View file

@ -13,8 +13,9 @@ class WithParam : public Variable_impl
public: public:
WithParam(const std::string& namespace_uri, WithParam(const std::string& namespace_uri,
const std::string& name, const std::string& name,
Arabica::XPath::XPathExpressionPtr<std::string> select) : Arabica::XPath::XPathExpressionPtr<std::string> select,
Variable_impl(namespace_uri, name, select) const Precedence& precedence) :
Variable_impl(namespace_uri, name, select, precedence)
{ {
} // WithParam } // WithParam

View file

@ -224,6 +224,10 @@
RelativePath="..\include\Xslt\impl\xslt_compilation_context.hpp" RelativePath="..\include\Xslt\impl\xslt_compilation_context.hpp"
> >
</File> </File>
<File
RelativePath="..\include\XSLT\impl\xslt_compiled_stylesheet.hpp"
>
</File>
<File <File
RelativePath="..\include\Xslt\impl\xslt_copy.hpp" RelativePath="..\include\Xslt\impl\xslt_copy.hpp"
> >
@ -268,6 +272,10 @@
RelativePath="..\include\Xslt\impl\xslt_param.hpp" RelativePath="..\include\Xslt\impl\xslt_param.hpp"
> >
</File> </File>
<File
RelativePath="..\include\XSLT\impl\xslt_precedence.hpp"
>
</File>
<File <File
RelativePath="..\include\Xslt\impl\xslt_processing_instruction.hpp" RelativePath="..\include\Xslt\impl\xslt_processing_instruction.hpp"
> >