// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.google.gdata.util.parser; /** * The <code>Intersection</code> parser provides one of the more powerful * pieces of functionality in the parser framework. It returns a successful * match only if both the <code>left</code> and <code>right</code> sub-parsers * match. Additionally, the amount of parse data passed to the * <code>right</code> parser is restricted to the size of the match for the * <code>left</code> parser. This allows certain types of recursively defined * grammars to be more easily specified. Note that this definition of * intersection is not the same as a set-theoretic definition. In particular, * this definition is not commutative. * * Parser i = Parser.intersection(Chset.ALPHA.plus(), Chset.ALNUM.plus()); * i.parse("a", null) -> matches "a" * i.parse("a1", null) -> matches "a" * * Parser j = Parser.intersection(Chset.ALNUM.plus(), Chset.ALPHA.plus()); * j.parse("a", null) -> matches "a" * j.parse("a1", null) -> no match, because ALNUM+ matches "a1" which doesn't * match ALPHA+ * * @param <T> * @see Parser * */ public class Intersection<T> extends Parser<T> { private Parser<? super T> left; private Parser<? super T> right; /** * Class constructor. * * @param left The <code>Parser</code> that is first matched against the * parse buffer. It restricts the region of the parse buffer that is matched * against the <code>right</code> parser. * * @param right The <code>Parser</code> that is matched against the parse * buffer if the <code>left</code> parses has already matched. */ public Intersection(Parser<? super T> left, Parser<? super T> right) { this.left = left; this.right = right; } /** * Matches the prefix of the buffer (<code>buf[start,end)</code>) being * parsed against the <code>left</code> and <code>right</code> sub-parsers. * * @see Parser#parse */ @Override public int parse(char[] buf, int start, int end, T data) { int left_hit = left.parse(buf, start, end, data); if (left_hit != NO_MATCH) { int right_hit = right.parse(buf, start, start + left_hit, data); if (left_hit == right_hit) { return left_hit; } } return NO_MATCH; } }