diff --git a/lib/oga/xpath/parser.y b/lib/oga/xpath/parser.y index c8baf8d..eb66f90 100644 --- a/lib/oga/xpath/parser.y +++ b/lib/oga/xpath/parser.y @@ -32,6 +32,7 @@ rule | axis | string | number + | call ; node_test @@ -61,6 +62,16 @@ rule | T_AXIS { s(:axis, val[0]) } ; + call + : T_IDENT T_LPAREN T_RPAREN { s(:call, val[0]) } + | T_IDENT T_LPAREN call_args T_RPAREN { s(:call, val[0], *val[2]) } + ; + + call_args + : xpath { val } + | xpath T_COMMA call_args { [val[0], *val[2]] } + ; + string : T_STRING { s(:string, val[0]) } ; diff --git a/spec/oga/xpath/parser/calls_spec.rb b/spec/oga/xpath/parser/calls_spec.rb new file mode 100644 index 0000000..b675c8a --- /dev/null +++ b/spec/oga/xpath/parser/calls_spec.rb @@ -0,0 +1,28 @@ +require 'spec_helper' + +describe Oga::XPath::Parser do + context 'function calls' do + example 'parse a function call without arguments' do + parse_xpath('count()').should == s(:path, s(:call, 'count')) + end + + example 'parse a function call with a single argument' do + parse_xpath('count(/foo)').should == s( + :path, + s(:call, 'count', s(:absolute, s(:path, s(:test, nil, 'foo')))) + ) + end + + example 'parse a function call with two arguments' do + parse_xpath('count(/foo, "bar")').should == s( + :path, + s( + :call, + 'count', + s(:absolute, s(:path, s(:test, nil, 'foo'))), + s(:path, s(:string, 'bar')) + ) + ) + end + end +end