From 645247287d3a4457ef89e49e18711fea5c3dce62 Mon Sep 17 00:00:00 2001 From: jez <> Date: Tue, 7 Aug 2007 14:43:44 +0000 Subject: [PATCH] see http://www.jezuk.co.uk/cgi-bin/view/SAX/news?id=3285 --- include/XPath/impl/xpath_parser.hpp | 169 +++++++++++++++------------- include/XPath/impl/xpath_step.hpp | 40 ++++--- 2 files changed, 115 insertions(+), 94 deletions(-) diff --git a/include/XPath/impl/xpath_parser.hpp b/include/XPath/impl/xpath_parser.hpp index 32152c17..84848e5e 100644 --- a/include/XPath/impl/xpath_parser.hpp +++ b/include/XPath/impl/xpath_parser.hpp @@ -115,10 +115,10 @@ public: void resetFunctionResolver() { functionResolver_.set(FunctionResolverPtr(new NullFunctionResolver())); } private: - typedef XPathExpression* (*compileFn)(typename impl::types::node_iter_t const& i, impl::CompilationContext& context); + typedef XPathExpression* (*compileFn)(typename impl::types::node_iter_t const& i, + typename impl::types::node_iter_t const& ie, + impl::CompilationContext& context); typedef typename impl::types::tree_info_t(XPath::*parserFn)(const string_type& str) const; - typedef XPathExpression* (*compilerFn)(typename impl::types::node_iter_t const& i, - impl::CompilationContext& context); XPathExpressionPtr do_compile(const string_type& xpath, parserFn parser, @@ -132,7 +132,10 @@ private: impl::CompilationContext context(*this, getNamespaceContext(), getFunctionResolver()); //XPath::dump(ast.trees.begin(), 0); - return XPathExpressionPtr(compile_with_factory(ast.trees.begin(), context, factory)); + return XPathExpressionPtr(compile_with_factory(ast.trees.begin(), + ast.trees.end(), + context, + factory)); } // try catch(const std::exception&) { @@ -180,24 +183,28 @@ private: ///////////////////////////////////////////////////////////////////////////////// public: static XPathExpression* compile_expression(typename impl::types::node_iter_t const& i, - impl::CompilationContext& context) + typename impl::types::node_iter_t const& ie, + impl::CompilationContext& context) { - return compile_with_factory(i, context, XPath::expression_factory()); + return compile_with_factory(i, ie, context, XPath::expression_factory()); } // compile_expression static XPathExpression* compile_match(typename impl::types::node_iter_t const& i, - impl::CompilationContext& context) + typename impl::types::node_iter_t const& ie, + impl::CompilationContext& context) { - return compile_with_factory(i, context, XPath::match_factory()); + return compile_with_factory(i, ie, context, XPath::match_factory()); } // compile_match static XPathExpression* compile_attribute_value(typename impl::types::node_iter_t const& i, - impl::CompilationContext& context) + typename impl::types::node_iter_t const& ie, + impl::CompilationContext& context) { - return compile_with_factory(i, context, XPath::attribute_value_factory()); + return compile_with_factory(i, ie, context, XPath::attribute_value_factory()); } // compile_attribute_value static XPathExpression* compile_with_factory(typename impl::types::node_iter_t const& i, + typename impl::types::node_iter_t const& ie, impl::CompilationContext& context, const std::map& factory) { @@ -210,7 +217,7 @@ public: } try { - return (f->second)(i, context); + return (f->second)(i, ie, context); } catch(...) { @@ -220,34 +227,35 @@ public: } // compile_with_factory private: - static XPathExpression* createAbsoluteLocationPath(typename impl::types::node_iter_t const& i, impl::CompilationContext& context); - static XPathExpression* createRelativeLocationPath(typename impl::types::node_iter_t const& i, impl::CompilationContext& context); - static XPathExpression* createFilteredPath(typename impl::types::node_iter_t const& i, impl::CompilationContext& context); - static XPathExpression* createSingleStepRelativeLocationPath(typename impl::types::node_iter_t const& i, impl::CompilationContext& context); - static XPathExpression* createExpression(typename impl::types::node_iter_t const& i, impl::CompilationContext& context); - static XPathExpression* createFunction(typename impl::types::node_iter_t const& i, impl::CompilationContext& context); - static XPathExpression* createBinaryExpression(typename impl::types::node_iter_t const& i, impl::CompilationContext& context); - static XPathExpression* createLiteral(typename impl::types::node_iter_t const& i, impl::CompilationContext& context); - static XPathExpression* createNumber(typename impl::types::node_iter_t const& i, impl::CompilationContext& context); - static XPathExpression* createVariable(typename impl::types::node_iter_t const& i, impl::CompilationContext& context); - static XPathExpression* createSingleStepAbsoluteLocationPath(typename impl::types::node_iter_t const& i, impl::CompilationContext& context); - static XPathExpression* createUnaryExpression(typename impl::types::node_iter_t const& i, impl::CompilationContext& context); - static XPathExpression* createUnaryNegativeExpr(typename impl::types::node_iter_t const& i, impl::CompilationContext& context); + static XPathExpression* createAbsoluteLocationPath(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context); + static XPathExpression* createRelativeLocationPath(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context); + static XPathExpression* createFilteredPath(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context); + static XPathExpression* createSingleStepRelativeLocationPath(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context); + static XPathExpression* createExpression(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context); + static XPathExpression* createFunction(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context); + static XPathExpression* createBinaryExpression(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context); + static XPathExpression* createLiteral(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context); + static XPathExpression* createNumber(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context); + static XPathExpression* createVariable(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context); + static XPathExpression* createSingleStepAbsoluteLocationPath(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context); + static XPathExpression* createUnaryExpression(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context); + static XPathExpression* createUnaryNegativeExpr(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context); static impl::StepList createStepList(typename impl::types::node_iter_t const& from, typename impl::types::node_iter_t const& to, impl::CompilationContext& context); - static XPathExpression* createDocMatch(typename impl::types::node_iter_t const& i, impl::CompilationContext& context); - static XPathExpression* createSingleMatchStep(typename impl::types::node_iter_t const& i, impl::CompilationContext& context); - static XPathExpression* createRelativePathPattern(typename impl::types::node_iter_t const& i, impl::CompilationContext& context); - static XPathExpression* createAlternatePattern(typename impl::types::node_iter_t const& i, impl::CompilationContext& context); - static double defaultPriority(typename impl::types::node_iter_t const& i); + static XPathExpression* createDocMatch(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context); + static XPathExpression* createSingleMatchStep(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context); + static XPathExpression* createRelativePathPattern(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context); + static XPathExpression* createAlternatePattern(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context); + static double defaultPriority(typename impl::types::node_iter_t const& i, + typename impl::types::node_iter_t const& ie); static impl::StepList createPatternList(typename impl::types::node_iter_t const& from, typename impl::types::node_iter_t const& to, impl::CompilationContext& context); - static XPathExpression* createAttributeValue(typename impl::types::node_iter_t const& i, impl::CompilationContext& context); - static XPathExpression* createEmbeddedExpr(typename impl::types::node_iter_t const& i, impl::CompilationContext& context); - static XPathExpression* createDoubleLeftCurly(typename impl::types::node_iter_t const& i, impl::CompilationContext& context); - static XPathExpression* createDoubleRightCurly(typename impl::types::node_iter_t const& i, impl::CompilationContext& context); + static XPathExpression* createAttributeValue(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context); + static XPathExpression* createEmbeddedExpr(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context); + static XPathExpression* createDoubleLeftCurly(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context); + static XPathExpression* createDoubleRightCurly(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context); static std::map& expression_factory() { @@ -508,19 +516,19 @@ namespace XPath { template -XPathExpression* XPath::createAbsoluteLocationPath(typename impl::types::node_iter_t const& i, impl::CompilationContext& context) +XPathExpression* XPath::createAbsoluteLocationPath(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context) { return new impl::AbsoluteLocationPath(createStepList(i->children.begin(), i->children.end(), context)); } // createAbsoluteLocationPath template -XPathExpression* XPath::createRelativeLocationPath(typename impl::types::node_iter_t const& i, impl::CompilationContext& context) +XPathExpression* XPath::createRelativeLocationPath(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context) { return new impl::RelativeLocationPath(createStepList(i->children.begin(), i->children.end(), context)); } // createRelativeLocationPath template -XPathExpression* XPath::createFilteredPath(typename impl::types::node_iter_t const& i, impl::CompilationContext& context) +XPathExpression* XPath::createFilteredPath(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context) { impl::StepList steps; steps.push_back(impl::StepFactory::createFilter(i, context)); @@ -528,22 +536,22 @@ XPathExpression* XPath } // createFilteredPath template -XPathExpression* XPath::createSingleStepRelativeLocationPath(typename impl::types::node_iter_t const& i, impl::CompilationContext& context) +XPathExpression* XPath::createSingleStepRelativeLocationPath(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context) { typename impl::types::node_iter_t n = i; - return new impl::RelativeLocationPath(impl::StepFactory::createStep(n, context)); + return new impl::RelativeLocationPath(impl::StepFactory::createSingleStep(n, ie, context)); } // createSingleStepRelativeLocationPath template -XPathExpression* XPath::createExpression(typename impl::types::node_iter_t const& i, impl::CompilationContext& context) +XPathExpression* XPath::createExpression(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context) { typename impl::types::node_iter_t c = i->children.begin(); impl::skipWhitespace(c); - return XPath::compile_expression(c, context); + return XPath::compile_expression(c, i->children.end(), context); } // createExpression template -XPathExpression* XPath::createFunction(typename impl::types::node_iter_t const& i, impl::CompilationContext& context) +XPathExpression* XPath::createFunction(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context) { typename impl::types::node_iter_t c = i->children.begin(); @@ -568,7 +576,7 @@ XPathExpression* XPath std::vector > args; while(impl::getNodeId(c) != impl::RightBracket_id) { - XPathExpressionPtr arg(XPath::compile_expression(c++, context)); + XPathExpressionPtr arg(XPath::compile_expression(c++, i->children.end(), context)); args.push_back(arg); impl::skipWhitespace(c); @@ -579,17 +587,17 @@ XPathExpression* XPath } // createFunction template -XPathExpression* XPath::createBinaryExpression(typename impl::types::node_iter_t const& i, impl::CompilationContext& context) +XPathExpression* XPath::createBinaryExpression(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context) { typename impl::types::node_iter_t c = i->children.begin(); - XPathExpression* p1 = XPath::compile_expression(c, context); + XPathExpression* p1 = XPath::compile_expression(c, i->children.end(), context); ++c; do { long op = impl::getNodeId(c); ++c; - XPathExpression* p2 = XPath::compile_expression(c, context); + XPathExpression* p2 = XPath::compile_expression(c, i->children.end(), context); switch(op) { @@ -645,21 +653,21 @@ XPathExpression* XPath } // createBinaryExpression template -XPathExpression* XPath::createLiteral(typename impl::types::node_iter_t const& i, impl::CompilationContext& context) +XPathExpression* XPath::createLiteral(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context) { string_type str = string_adaptor::construct(i->value.begin(), i->value.end()); return new StringValue(str); } // createLiteral template -XPathExpression* XPath::createNumber(typename impl::types::node_iter_t const& i, impl::CompilationContext& context) +XPathExpression* XPath::createNumber(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context) { string_type str = string_adaptor::construct(i->value.begin(), i->value.end()); return new NumericValue(boost::lexical_cast(str)); } // createNumber template -XPathExpression* XPath::createVariable(typename impl::types::node_iter_t const& i, impl::CompilationContext& context) +XPathExpression* XPath::createVariable(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context) { typename impl::types::node_iter_t n = i->children.begin(); ++n; // skip $ @@ -677,22 +685,22 @@ XPathExpression* XPath } // createVariable template -XPathExpression* XPath::createSingleStepAbsoluteLocationPath(typename impl::types::node_iter_t const& i, impl::CompilationContext& context) +XPathExpression* XPath::createSingleStepAbsoluteLocationPath(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context) { typename impl::types::node_iter_t n = i; - return new impl::AbsoluteLocationPath(impl::StepFactory::createStep(n, context)); + return new impl::AbsoluteLocationPath(impl::StepFactory::createSingleStep(n, ie, context)); } // createSingleStepAbsoluteLocationPath template -XPathExpression* XPath::createUnaryExpression(typename impl::types::node_iter_t const& i, impl::CompilationContext& context) +XPathExpression* XPath::createUnaryExpression(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context) { - return XPath::compile_expression(i->children.begin(), context); + return XPath::compile_expression(i->children.begin(), i->children.end(), context); } // createUnaryExpression template -XPathExpression* XPath::createUnaryNegativeExpr(typename impl::types::node_iter_t const& i, impl::CompilationContext& context) +XPathExpression* XPath::createUnaryNegativeExpr(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context) { - return new impl::UnaryNegative(XPath::compile_expression(i+1, context)); + return new impl::UnaryNegative(XPath::compile_expression(i+1, ie, context)); } // createUnaryNegativeExpr template @@ -737,48 +745,49 @@ impl::StepList XPath:: } // createStepList template -XPathExpression* XPath::createDocMatch(typename impl::types::node_iter_t const& i, impl::CompilationContext& context) +XPathExpression* XPath::createDocMatch(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context) { typename impl::types::node_iter_t n = i; - return new impl::MatchExpressionWrapper(new impl::RelativeLocationPath(impl::StepFactory::createStep(n, context)), defaultPriority(i)); + return new impl::MatchExpressionWrapper(new impl::RelativeLocationPath(impl::StepFactory::createSingleStep(n, ie, context)), defaultPriority(i, ie)); } // createDocMatch template -XPathExpression* XPath::createSingleMatchStep(typename impl::types::node_iter_t const& i, impl::CompilationContext& context) +XPathExpression* XPath::createSingleMatchStep(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context) { typename impl::types::node_iter_t n = i; impl::StepList steps; steps.push_back(new impl::TestStepExpression(SELF, new impl::NotAttributeNodeTest())); - steps.push_back(impl::StepFactory::createStep(n, context, SELF)); - return new impl::MatchExpressionWrapper(new impl::RelativeLocationPath(steps), defaultPriority(i)); + steps.push_back(impl::StepFactory::createSingleStep(n, ie, context, SELF)); + return new impl::MatchExpressionWrapper(new impl::RelativeLocationPath(steps), defaultPriority(i, ie)); } // createSingleMatchStep template -XPathExpression* XPath::createRelativePathPattern(typename impl::types::node_iter_t const& i, impl::CompilationContext& context) +XPathExpression* XPath::createRelativePathPattern(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context) { - return new impl::MatchExpressionWrapper(new impl::RelativeLocationPath(createPatternList(i->children.begin(), i->children.end(), context)), defaultPriority(i)); + return new impl::MatchExpressionWrapper(new impl::RelativeLocationPath(createPatternList(i->children.begin(), i->children.end(), context)), defaultPriority(i, ie)); } // createRelativePathPattern template -XPathExpression* XPath::createAlternatePattern(typename impl::types::node_iter_t const& i, impl::CompilationContext& context) +XPathExpression* XPath::createAlternatePattern(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context) { // child sequence is test union_op test ... typename impl::types::node_iter_t n = i->children.begin(), e = i->children.end(); impl::MatchExpressionWrapper* matches = - new impl::MatchExpressionWrapper(compile_match(n++, context)); + new impl::MatchExpressionWrapper(compile_match(n++, e, context)); while(n != e) { ++n; // skip | - matches->add_matches(compile_match(n++, context)); + matches->add_matches(compile_match(n++, e, context)); } // while return matches; } // createAlternatePattern template -double XPath::defaultPriority(typename impl::types::node_iter_t const& node) +double XPath::defaultPriority(typename impl::types::node_iter_t const& node, + typename impl::types::node_iter_t const& end) { typename impl::types::node_iter_t i = node; impl::skipWhitespace(i); @@ -793,7 +802,10 @@ double XPath::defaultPriority(typename impl::types< case impl::QName_id: return 0; case impl::NCName_id: - impl::skipWhitespace(++i); + ++i; + if(i == end) + return 0; + impl::skipWhitespace(i); if(impl::getNodeId(i) == impl::Predicate_id) return 0.5; if(impl::getNodeId(i) == impl::AnyName_id) @@ -813,7 +825,10 @@ double XPath::defaultPriority(typename impl::types< case impl::Text_id: case impl::Comment_id: case impl::ProcessingInstruction_id: - impl::skipWhitespace(++i); + ++i; + if(i == end) + return -0.5; + impl::skipWhitespace(i); if(impl::getNodeId(i) == impl::Predicate_id) return 0.5; return -0.5; @@ -824,14 +839,14 @@ double XPath::defaultPriority(typename impl::types< case impl::RelativePathPattern_id: // case impl::Pattern_id: if(child_count <= 2) - return defaultPriority(i->children.begin()); + return defaultPriority(i->children.begin(), i->children.end()); break; case impl::Child_id: case impl::Attribute_id: case impl::AbbreviatedAxisSpecifier_id: if(child_count == 0) - return defaultPriority(i+1); + return defaultPriority(i+1, end); break; } // switch @@ -873,7 +888,7 @@ void createStepsFromPattern(impl::StepList& steps, switch(impl::getNodeId(c)) { case impl::Slash_id: - steps.push_front(impl::StepFactory::createStep(c, context, PARENT)); + steps.push_front(impl::StepFactory::createStep(c, to, context, PARENT)); case impl::SlashSlash_id: ++c; break; @@ -932,7 +947,7 @@ impl::StepList XPath:: switch(impl::getNodeId(c)) { case impl::Slash_id: - steps.push_front(impl::StepFactory::createStep(c, context, PARENT)); + steps.push_front(impl::StepFactory::createStep(c, to, context, PARENT)); case impl::SlashSlash_id: ++c; break; @@ -945,12 +960,12 @@ impl::StepList XPath:: template -XPathExpression* XPath::createAttributeValue(typename impl::types::node_iter_t const& i, impl::CompilationContext& context) +XPathExpression* XPath::createAttributeValue(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context) { std::vector > args; for(typename impl::types::node_iter_t a = i->children.begin(), e = i->children.end(); a != e; ++a) { - XPathExpressionPtr arg(XPath::compile_attribute_value(a, context)); + XPathExpressionPtr arg(XPath::compile_attribute_value(a, e, context)); args.push_back(arg); } // while ... // maybe trailing whitespace ... @@ -962,19 +977,19 @@ XPathExpression* XPath } // createAttributeValue template -XPathExpression* XPath::createEmbeddedExpr(typename impl::types::node_iter_t const& i, impl::CompilationContext& context) +XPathExpression* XPath::createEmbeddedExpr(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context) { - return compile_expression(i->children.begin() + 1, context); + return compile_expression(i->children.begin() + 1, i->children.end(), context); } // createEmbeddedExpr template -XPathExpression* XPath::createDoubleLeftCurly(typename impl::types::node_iter_t const& i, impl::CompilationContext& context) +XPathExpression* XPath::createDoubleLeftCurly(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context) { return new StringValue("{"); } // createDoubleLeftCurly template -XPathExpression* XPath::createDoubleRightCurly(typename impl::types::node_iter_t const& i, impl::CompilationContext& context) +XPathExpression* XPath::createDoubleRightCurly(typename impl::types::node_iter_t const& i, typename impl::types::node_iter_t const& ie, impl::CompilationContext& context) { return new StringValue("}"); } // createDoubleRightCurly diff --git a/include/XPath/impl/xpath_step.hpp b/include/XPath/impl/xpath_step.hpp index 846a687f..065f5952 100644 --- a/include/XPath/impl/xpath_step.hpp +++ b/include/XPath/impl/xpath_step.hpp @@ -200,10 +200,10 @@ public: Axis axis, bool is_attr = false) { - NodeTest* test = getTest(node, !is_attr ? axis : ATTRIBUTE, context.namespaceContext()); + NodeTest* test = getTest(node, end, !is_attr ? axis : ATTRIBUTE, context.namespaceContext()); XPathExpression* thing = 0; if(!test) - thing = XPath::compile_expression(node++, context); + thing = XPath::compile_expression(node++, end, context); std::vector*> preds = createPredicates(node, end, context); @@ -217,28 +217,32 @@ public: CompilationContext& context) { typename types::node_iter_t c = node->children.begin(); - XPathExpression* step = XPath::compile_expression(c, context); + typename types::node_iter_t const ce = node->children.end(); + XPathExpression* step = XPath::compile_expression(c, ce, context); ++c; - std::vector*> preds = createPredicates(c, node->children.end(), context); + std::vector*> preds = createPredicates(c, ce, context); return new ExprStepExpression(step, preds); } // createFilter - static StepExpression* createStep(typename types::node_iter_t& node, - CompilationContext& context) + static StepExpression* createSingleStep(typename types::node_iter_t& node, + typename types::node_iter_t const& end, + CompilationContext& context) { Axis axis = getAxis(node); - NodeTest* test = getTest(node, axis, context.namespaceContext()); - return new TestStepExpression(axis, test); + return createSingleStep(node, end, context, axis); } // createStep - static StepExpression* createStep(typename types::node_iter_t& node, - CompilationContext& context, - Axis axis) + static StepExpression* createSingleStep(typename types::node_iter_t& node, + typename types::node_iter_t const& end, + CompilationContext& context, + Axis axis) { - NodeTest* test = getTest(node, axis, context.namespaceContext()); + NodeTest* test = getTest(node, end, axis, context.namespaceContext()); return new TestStepExpression(axis, test); + return 0; } // createStep +private: static Axis getAxis(typename types::node_iter_t& node) { long id = getNodeId(node); @@ -309,7 +313,6 @@ public: return CHILD; } // getAxis -private: static std::vector*> createPredicates(typename types::node_iter_t& node, typename types::node_iter_t const& end, CompilationContext& context) @@ -321,7 +324,7 @@ private: typename types::node_iter_t c = node->children.begin(); assert(getNodeId(c) == impl::LeftSquare_id); ++c; - preds.push_back(XPath::compile_expression(c, context)); + preds.push_back(XPath::compile_expression(c, node->children.end(), context)); ++c; assert(getNodeId(c) == impl::RightSquare_id); @@ -331,7 +334,10 @@ private: return preds; } // createPredicates - static NodeTest* getTest(typename types::node_iter_t& node, Axis axis, const NamespaceContext& namespaceContext) + static NodeTest* getTest(typename types::node_iter_t& node, + typename types::node_iter_t const& end, + Axis axis, + const NamespaceContext& namespaceContext) { long id = getNodeId(skipWhitespace(node)); @@ -340,7 +346,7 @@ private: case impl::NodeTest_id: { typename types::node_iter_t c = node->children.begin(); - NodeTest* t = getTest(c, axis, namespaceContext); + NodeTest* t = getTest(c, node->children.end(), axis, namespaceContext); ++node; return t; } // case NodeTest_id @@ -382,7 +388,7 @@ private: case impl::ProcessingInstruction_id: { ++node; - if(getNodeId(node) != impl::Literal_id) // not sure if this is always safe + if((node == end) || (getNodeId(node) != impl::Literal_id)) return new ProcessingInstructionNodeTest(); string_type target = string_adaptor::construct(node->value.begin(), node->value.end());