001/*-------------------------------------------------------------------------+
002|                                                                          |
003| Copyright 2005-2011 the ConQAT Project                                   |
004|                                                                          |
005| Licensed under the Apache License, Version 2.0 (the "License");          |
006| you may not use this file except in compliance with the License.         |
007| You may obtain a copy of the License at                                  |
008|                                                                          |
009|    http://www.apache.org/licenses/LICENSE-2.0                            |
010|                                                                          |
011| Unless required by applicable law or agreed to in writing, software      |
012| distributed under the License is distributed on an "AS IS" BASIS,        |
013| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
014| See the License for the specific language governing permissions and      |
015| limitations under the License.                                           |
016+-------------------------------------------------------------------------*/
017package eu.cqse.check.framework.util.tokens;
018
019/**
020 * Base class for token patterns. Handles resetting the token stream's position
021 * if the pattern did not match and appending the patterns match to the match
022 * group, if a group index was set for this pattern.
023 */
024public abstract class TokenPatternBase {
025
026        /**
027         * The group index of this pattern or <code>null</code> if this pattern's match
028         * should not be appended to a group.
029         */
030        private Integer groupIndex = null;
031
032        /** @see #groupIndex */
033        public void setGroupIndex(Integer groupIndex) {
034                this.groupIndex = groupIndex;
035        }
036
037        /**
038         * Tries to match this pattern at the current position of the given stream.
039         * Returns a match object if successful, <code>null</code> otherwise. If the
040         * match was unsuccessful, the streams position is not modified.
041         */
042        /* package */TokenPatternMatch matches(TokenStream stream) {
043                int beforePosition = stream.getPosition();
044                TokenPatternMatch match = matchesLocally(stream);
045                if (match == null) {
046                        stream.setPosition(beforePosition);
047                } else if (groupIndex != null) {
048                        match.appendToGroup(groupIndex, beforePosition, stream.getPosition());
049                }
050                return match;
051        }
052
053        /** Utility method to create an empty match object. */
054        protected TokenPatternMatch createMatch(TokenStream stream) {
055                return new TokenPatternMatch(stream.getTokens());
056        }
057
058        /**
059         * Tries to match this pattern at the current position of the given stream.
060         * Returns a match object if successful, <code>null</code> otherwise. May modify
061         * the stream's position.
062         */
063        protected abstract TokenPatternMatch matchesLocally(TokenStream stream);
064}