diff --git a/lib/oga/xpath/parser.y b/lib/oga/xpath/parser.y index 98bce91..c210251 100644 --- a/lib/oga/xpath/parser.y +++ b/lib/oga/xpath/parser.y @@ -35,6 +35,11 @@ rule ; expression + : expression_members + | T_LPAREN expression_members T_RPAREN { val[1] } + ; + + expression_members : node_test_as_axis | operator | axis diff --git a/spec/oga/xpath/parser/grouping_spec.rb b/spec/oga/xpath/parser/grouping_spec.rb new file mode 100644 index 0000000..29250a8 --- /dev/null +++ b/spec/oga/xpath/parser/grouping_spec.rb @@ -0,0 +1,41 @@ +require 'spec_helper' + +describe Oga::XPath::Parser do + context 'grouping of expressions' do + example 'parse "A + (B + C)"' do + parse_xpath('A + (B + C)').should == s( + :add, + s(:axis, 'child', s(:test, nil, 'A')), + s( + :add, + s(:axis, 'child', s(:test, nil, 'B')), + s(:axis, 'child', s(:test, nil, 'C')) + ) + ) + end + + example 'parse "A or (B or C)"' do + parse_xpath('A or (B or C)').should == s( + :or, + s(:axis, 'child', s(:test, nil, 'A')), + s( + :or, + s(:axis, 'child', s(:test, nil, 'B')), + s(:axis, 'child', s(:test, nil, 'C')) + ) + ) + end + + example 'parse "(A or B) and C"' do + parse_xpath('(A or B) and C').should == s( + :and, + s( + :or, + s(:axis, 'child', s(:test, nil, 'A')), + s(:axis, 'child', s(:test, nil, 'B')) + ), + s(:axis, 'child', s(:test, nil, 'C')) + ) + end + end +end