Lexing/parsing of XPath variable references.

This commit is contained in:
Yorick Peterse 2014-09-02 10:52:08 +02:00
parent 3dcd0e4584
commit 5a0e8c5480
4 changed files with 46 additions and 1 deletions

View File

@ -316,6 +316,19 @@ module Oga
emit(:T_TYPE_TEST, ts, te - 2)
}
# Variables
#
# XPath 1.0 allows the use of variables in expressions. Oddly enough you
# can not assign variables in an expression, you can only refer to them.
# This means that libraries themselves have to expose an interface for
# setting variables.
#
var = '$' identifier;
action emit_variable {
emit(:T_VAR, ts + 1, te)
}
main := |*
operator;
whitespace | slash | lparen | rparen | comma | colon;
@ -325,6 +338,7 @@ module Oga
'[' => { add_token(:T_LBRACK) };
']' => { add_token(:T_RBRACK) };
var => emit_variable;
string => emit_string;
integer => emit_integer;
float => emit_float;

View File

@ -6,7 +6,7 @@ class Oga::XPath::Parser
token T_AXIS T_COLON T_COMMA T_FLOAT T_INT T_IDENT T_TYPE_TEST
token T_LBRACK T_RBRACK T_LPAREN T_RPAREN T_SLASH T_STRING
token T_PIPE T_AND T_OR T_ADD T_DIV T_MOD T_EQ T_NEQ T_LT T_GT T_LTE T_GTE
token T_SUB T_MUL
token T_SUB T_MUL T_VAR
options no_result_var
@ -42,6 +42,7 @@ rule
| call
| path
| absolute_path
| variable
;
path_member
@ -139,6 +140,10 @@ rule
number
: T_INT { s(:int, val[0]) }
| T_FLOAT { s(:float, val[0]) }
variable
: T_VAR { s(:var, val[0]) }
;
end
---- inner

View File

@ -0,0 +1,9 @@
require 'spec_helper'
describe Oga::XPath::Lexer do
context 'variables' do
example 'lex a variable reference' do
lex_xpath('$foo').should == [[:T_VAR, 'foo']]
end
end
end

View File

@ -0,0 +1,17 @@
require 'spec_helper'
describe Oga::XPath::Parser do
context 'variables' do
example 'parse a variable reference' do
parse_xpath('$foo').should == s(:var, 'foo')
end
example 'parse a variable reference in a predicate' do
parse_xpath('foo[$bar]').should == s(
:axis,
'child',
s(:test, nil, 'foo', s(:var, 'bar'))
)
end
end
end