From 46646e2acedd340a5734dd3ee6bc31dc10bfc044 Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Sun, 26 Oct 2014 22:38:05 +0100 Subject: [PATCH] Support for custom grouping of XPath expressions. This allows the use of expressions such as "(A or B) and C". This fixes #59. --- lib/oga/xpath/parser.y | 5 ++++ spec/oga/xpath/parser/grouping_spec.rb | 41 ++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 spec/oga/xpath/parser/grouping_spec.rb 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