mirror of
https://github.com/jezhiggins/arabica
synced 2025-01-18 22:26:32 +01:00
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:
parent
8d0ce36da3
commit
f610d739fe
14 changed files with 89 additions and 49 deletions
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -33,6 +33,7 @@ public:
|
|||
{
|
||||
return value_;
|
||||
} // value
|
||||
virtual const Precedence& precedence() const { return Precedence::InitialPrecedence(); }
|
||||
|
||||
private:
|
||||
static DOM::Node<std::string> null_node;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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"
|
||||
>
|
||||
|
|
Loading…
Reference in a new issue