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;
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

View file

@ -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,

View file

@ -16,7 +16,15 @@ class VariableHandler : public ItemContainerHandler<VType>
public:
VariableHandler(CompilationContext& 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
@ -42,7 +50,7 @@ protected:
} // if ...
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
virtual void characters(const std::string& ch)
@ -58,6 +66,7 @@ protected:
private:
bool has_select_;
const Precedence precedence_;
}; // class VariableHandler
template<class VType>
@ -65,7 +74,7 @@ class TopLevelVariableHandler : public VariableHandler<VType>
{
public:
TopLevelVariableHandler(CompilationContext& context) :
VariableHandler<VType>(context)
VariableHandler<VType>(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

View file

@ -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<SAX::DefaultHandler<std::string>*> handlerStack_;
std::stack<ItemContainer*> parentStack_;
std::map<std::string, Namespace> namespaceRemap_;
PrecedenceStack precedenceStack_;
CompilationContext(const CompilationContext&);
mutable int autoNs_;

View file

@ -35,8 +35,7 @@ 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)
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;
@ -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)
for(VariableDeclList::const_iterator ci = topLevelVars_.begin(), ce = topLevelVars_.end(); ci != ce; ++ci)
(*ci)->execute(initialNode, context);
context.pushVariablePrecedence();
} // for ...
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<ModeTemplates> TemplateStack;
typedef std::map<std::pair<std::string, std::string>, Template*> NamedTemplates;
typedef std::vector<Item*> ItemList;
typedef std::vector<ItemList> ItemStack;
typedef std::vector<Item*> VariableDeclList;
typedef std::vector<TopLevelParam*> ParamList;
TemplateList all_templates_;
NamedTemplates named_templates_;
TemplateStack templates_;
ItemStack items_;
VariableDeclList topLevelVars_;
ParamList params_;
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,
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<std::string>& node, const Variable_declaration& param);
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 injectGlobalScope(const Scope& scope);
@ -106,7 +103,6 @@ private:
private:
const CompiledStylesheet& stylesheet_;
VariableStack stack_;
PrecedenceStack variable_precedence_;
Arabica::XPath::ExecutionContext<std::string> 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<std::string> value() const
{
@ -195,7 +191,6 @@ void ExecutionContext::declareVariable(const DOM::Node<std::string>& node, const
void ExecutionContext::freezeTopLevel()
{
stack_.freezeTopLevel();
variable_precedence_.freeze();
} // freezeTopLevel
void ExecutionContext::injectGlobalScope(const Scope& scope)

View file

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

View file

@ -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<Precedence> stack_;
std::stack<Precedence> stack_;
}; // class PrecedenceStack
#endif

View file

@ -14,20 +14,24 @@ class Template : public ItemContainer
public:
Template(const std::pair<std::string, std::string>& name,
const std::pair<std::string, std::string>& 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<Arabica::XPath::MatchExpr<std::string> >& matches,
const std::pair<std::string, std::string>& name,
const std::pair<std::string, std::string>& 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<std::string, std::string>& name() const { return name_; }
const std::pair<std::string, std::string>& mode() const { return mode_; }
const Precedence& precedence() const { return precedence_; }
private:
std::vector<Arabica::XPath::MatchExpr<std::string> > matches_;
std::pair<std::string, std::string> name_;
std::pair<std::string, std::string> mode_;
const Precedence precedence_;
}; // class Template
} // namespace XSLT

View file

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

View file

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

View file

@ -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<std::string> select) :
Arabica::XPath::XPathExpressionPtr<std::string> 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<std::string, Arabica::default_string_adaptor<std::string> >::createValue(nodeset);
} // value
virtual const Precedence& precedence() const { return precedence_; }
private:
std::string namespace_uri_;
std::string name_;
Arabica::XPath::XPathExpressionPtr<std::string> select_;
Precedence precedence_;
}; // Variable_impl
} // namespace XSLT

View file

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

View file

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