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