Wrap predicate AST nodes _around_ other nodes.

This means that "foo[1]" uses this AST:

    (predicate (test nil "foo") (int 1))

Instead of this AST:

    (test nil "foo" (int 1))

This makes it easier for the XPath evaluator to process predicates correctly.
This commit is contained in:
Yorick Peterse committed 2014-11-12 22:59:38 +01:00
1 parent 24350fa457
commit 817a5e075b
5 files changed
+68 -62

No files matched your search

+36 -23
View File
@@ -163,45 +163,58 @@ module Oga
end
##
# Processes a node test and optionally a predicate.
# Processes a node test.
#
# @param [AST::Node] ast_node
# @param [Oga::XML::NodeSet] context
# @return [Oga::XML::NodeSet]
#
def on_test(ast_node, context)
nodes = XML::NodeSet.new
predicate = ast_node.children[2]
xpath_index = 1
nodes = XML::NodeSet.new
context.each do |xml_node|
next unless node_matches?(xml_node, ast_node)
nodes << xml_node if node_matches?(xml_node, ast_node)
end
if predicate
retval = with_node_set(context) do
process(predicate, XML::NodeSet.new([xml_node]))
return nodes
end
##
# Processes a predicate.
#
# @param [AST::Node] ast_node
# @param [Oga::XML::NodeSet] context
# @return [Oga::XML::NodeSet]
#
def on_predicate(ast_node, context)
test, predicate = *ast_node
initial_nodes = process(test, context)
final_nodes = XML::NodeSet.new
xpath_index = 1
initial_nodes.each do |xml_node|
retval = with_node_set(initial_nodes) do
process(predicate, XML::NodeSet.new([xml_node]))
end
# Numeric values are used as node set indexes.
if retval.is_a?(Numeric)
final_nodes << xml_node if retval.to_i == xpath_index
# Node sets, strings, booleans, etc
elsif retval
if retval.respond_to?(:empty?) and retval.empty?
next
end
# Numeric values are used as node set indexes.
if retval.is_a?(Numeric)
nodes << xml_node if retval.to_i == xpath_index
# Node sets, strings, booleans, etc
elsif retval
if retval.respond_to?(:empty?) and retval.empty?
next
end
nodes << xml_node
end
else
nodes << xml_node
final_nodes << xml_node
end
xpath_index += 1
end
return nodes
return final_nodes
end
##
+8 -4
View File
@@ -40,9 +40,8 @@ rule
;
expression_members
: node_test_as_axis
: expression_with_predicate
| operator
| axis
| string
| number
| call
@@ -51,9 +50,14 @@ rule
| variable
;
path_member
expression_with_predicate
: node_test_as_axis
| node_test_as_axis predicate { s(:predicate, val[0], val[1]) }
| axis
| axis predicate { s(:predicate, val[0], val[1]) }
path_member
: expression_with_predicate
| call
;
@@ -83,7 +87,7 @@ rule
node_test
: node_name { s(:test, *val[0]) }
| node_name predicate { s(:test, *val[0], val[1]) }
#| node_name predicate { s(:predicate, s(:test, *val[0]), val[1]) }
| type_test { val[0] }
;