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'
|
'.' => '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.
|
# @param [String] data The data to lex.
|
||||||
#
|
#
|
||||||
|
@ -226,6 +233,17 @@ module Oga
|
||||||
value = AXIS_MAPPING[slice_input(ts, te)]
|
value = AXIS_MAPPING[slice_input(ts, te)]
|
||||||
|
|
||||||
add_token(:T_AXIS, value)
|
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
|
# Operators
|
||||||
|
|
|
@ -120,6 +120,10 @@ describe Oga::XPath::Lexer do
|
||||||
lex_xpath('//A').should == [
|
lex_xpath('//A').should == [
|
||||||
[:T_SLASH, nil],
|
[:T_SLASH, nil],
|
||||||
[:T_AXIS, 'descendant-or-self'],
|
[:T_AXIS, 'descendant-or-self'],
|
||||||
|
[:T_IDENT, 'node'],
|
||||||
|
[:T_LPAREN, nil],
|
||||||
|
[:T_RPAREN, nil],
|
||||||
|
[:T_SLASH, nil],
|
||||||
[:T_IDENT, 'A']
|
[:T_IDENT, 'A']
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
@ -127,14 +131,20 @@ describe Oga::XPath::Lexer do
|
||||||
example 'lex the .. axis' do
|
example 'lex the .. axis' do
|
||||||
lex_xpath('/..').should == [
|
lex_xpath('/..').should == [
|
||||||
[:T_SLASH, nil],
|
[:T_SLASH, nil],
|
||||||
[:T_AXIS, 'parent']
|
[:T_AXIS, 'parent'],
|
||||||
|
[:T_IDENT, 'node'],
|
||||||
|
[:T_LPAREN, nil],
|
||||||
|
[:T_RPAREN, nil],
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
example 'lex the . axis' do
|
example 'lex the . axis' do
|
||||||
lex_xpath('/.').should == [
|
lex_xpath('/.').should == [
|
||||||
[:T_SLASH, nil],
|
[:T_SLASH, nil],
|
||||||
[:T_AXIS, 'self']
|
[:T_AXIS, 'self'],
|
||||||
|
[:T_IDENT, 'node'],
|
||||||
|
[:T_LPAREN, nil],
|
||||||
|
[:T_RPAREN, nil],
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -37,6 +37,10 @@ describe Oga::XPath::Lexer do
|
||||||
[:T_IDENT, 'wikimedia'],
|
[:T_IDENT, 'wikimedia'],
|
||||||
[:T_SLASH, nil],
|
[:T_SLASH, nil],
|
||||||
[:T_AXIS, 'descendant-or-self'],
|
[:T_AXIS, 'descendant-or-self'],
|
||||||
|
[:T_IDENT, 'node'],
|
||||||
|
[:T_LPAREN, nil],
|
||||||
|
[:T_RPAREN, nil],
|
||||||
|
[:T_SLASH, nil],
|
||||||
[:T_IDENT, 'editions']
|
[:T_IDENT, 'editions']
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
|
@ -120,16 +120,23 @@ describe Oga::XPath::Parser do
|
||||||
example 'parse the // axis' do
|
example 'parse the // axis' do
|
||||||
parse_xpath('//A').should == s(
|
parse_xpath('//A').should == s(
|
||||||
:absolute_path,
|
:absolute_path,
|
||||||
s(:axis, 'descendant-or-self', s(:test, nil, 'A'))
|
s(:axis, 'descendant-or-self', s(:call, 'node')),
|
||||||
|
s(:test, nil, 'A')
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
example 'parse the .. axis' do
|
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
|
end
|
||||||
|
|
||||||
example 'parse the . axis' do
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue