Emit node() calls for certain short axes.
An axes such as "." is the same as "self::node()". To simplify things on parser/evaluator level we'll emit the corresponding tokens for a "node()" function call for these axes.
This commit is contained in:
parent
f699b0d097
commit
c43c38fab9
|
@ -23,6 +23,13 @@ module Oga
|
|||
'.' => 'self'
|
||||
}
|
||||
|
||||
##
|
||||
# Axes that require a separate `node()` call to be emitted.
|
||||
#
|
||||
# @return [Array]
|
||||
#
|
||||
AXIS_EMIT_NODE = %w{descendant-or-self parent self}
|
||||
|
||||
##
|
||||
# @param [String] data The data to lex.
|
||||
#
|
||||
|
@ -226,6 +233,17 @@ module Oga
|
|||
value = AXIS_MAPPING[slice_input(ts, te)]
|
||||
|
||||
add_token(:T_AXIS, value)
|
||||
|
||||
# Short axes that use node() as their default, implicit test. This is
|
||||
# added on lexer level to make it easier to handle these cases on
|
||||
# parser/evaluator level.
|
||||
if AXIS_EMIT_NODE.include?(value)
|
||||
add_token(:T_IDENT, 'node')
|
||||
add_token(:T_LPAREN)
|
||||
add_token(:T_RPAREN)
|
||||
|
||||
add_token(:T_SLASH) unless te == eof
|
||||
end
|
||||
}
|
||||
|
||||
# Operators
|
||||
|
|
|
@ -120,6 +120,10 @@ describe Oga::XPath::Lexer do
|
|||
lex_xpath('//A').should == [
|
||||
[:T_SLASH, nil],
|
||||
[:T_AXIS, 'descendant-or-self'],
|
||||
[:T_IDENT, 'node'],
|
||||
[:T_LPAREN, nil],
|
||||
[:T_RPAREN, nil],
|
||||
[:T_SLASH, nil],
|
||||
[:T_IDENT, 'A']
|
||||
]
|
||||
end
|
||||
|
@ -127,14 +131,20 @@ describe Oga::XPath::Lexer do
|
|||
example 'lex the .. axis' do
|
||||
lex_xpath('/..').should == [
|
||||
[:T_SLASH, nil],
|
||||
[:T_AXIS, 'parent']
|
||||
[:T_AXIS, 'parent'],
|
||||
[:T_IDENT, 'node'],
|
||||
[:T_LPAREN, nil],
|
||||
[:T_RPAREN, nil],
|
||||
]
|
||||
end
|
||||
|
||||
example 'lex the . axis' do
|
||||
lex_xpath('/.').should == [
|
||||
[:T_SLASH, nil],
|
||||
[:T_AXIS, 'self']
|
||||
[:T_AXIS, 'self'],
|
||||
[:T_IDENT, 'node'],
|
||||
[:T_LPAREN, nil],
|
||||
[:T_RPAREN, nil],
|
||||
]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -37,6 +37,10 @@ describe Oga::XPath::Lexer do
|
|||
[:T_IDENT, 'wikimedia'],
|
||||
[:T_SLASH, nil],
|
||||
[:T_AXIS, 'descendant-or-self'],
|
||||
[:T_IDENT, 'node'],
|
||||
[:T_LPAREN, nil],
|
||||
[:T_RPAREN, nil],
|
||||
[:T_SLASH, nil],
|
||||
[:T_IDENT, 'editions']
|
||||
]
|
||||
end
|
||||
|
|
|
@ -120,16 +120,23 @@ describe Oga::XPath::Parser do
|
|||
example 'parse the // axis' do
|
||||
parse_xpath('//A').should == s(
|
||||
:absolute_path,
|
||||
s(:axis, 'descendant-or-self', s(:test, nil, 'A'))
|
||||
s(:axis, 'descendant-or-self', s(:call, 'node')),
|
||||
s(:test, nil, 'A')
|
||||
)
|
||||
end
|
||||
|
||||
example 'parse the .. axis' do
|
||||
parse_xpath('/..').should == s(:absolute_path, s(:axis, 'parent'))
|
||||
parse_xpath('/..').should == s(
|
||||
:absolute_path,
|
||||
s(:axis, 'parent', s(:call, 'node'))
|
||||
)
|
||||
end
|
||||
|
||||
example 'parse the . axis' do
|
||||
parse_xpath('/.').should == s(:absolute_path, s(:axis, 'self'))
|
||||
parse_xpath('/.').should == s(
|
||||
:absolute_path,
|
||||
s(:axis, 'self', s(:call, 'node'))
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue