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.shallowparser.languages.opencl; 018 019import static eu.cqse.check.framework.shallowparser.languages.base.EGenericParserStates.IN_EXPRESSION; 020 021import java.util.EnumSet; 022import java.util.List; 023 024import eu.cqse.check.framework.scanner.ETokenType; 025import eu.cqse.check.framework.scanner.IToken; 026import eu.cqse.check.framework.shallowparser.TokenStreamUtils; 027import eu.cqse.check.framework.shallowparser.framework.ParserState; 028import eu.cqse.check.framework.shallowparser.languages.base.EGenericParserStates; 029import eu.cqse.check.framework.shallowparser.languages.cpp.CppLambdaRecognizer; 030 031/** 032 * Recognizer that finds OpenCL block literals and C++ lambdas and continues 033 * parsing within these. 034 */ 035public class OpenCLLambdaAndBlockLiteralRecognizer extends CppLambdaRecognizer { 036 037 /** Constructor. */ 038 public OpenCLLambdaAndBlockLiteralRecognizer(EnumSet<ETokenType> typeOrIdentifier) { 039 super(typeOrIdentifier); 040 } 041 042 /** {@inheritDoc} */ 043 @Override 044 protected int matchesLocally(ParserState<EGenericParserStates> parserState, List<IToken> tokens, int startOffset) { 045 int index = matchBlockLiteralStart(parserState, tokens, startOffset); 046 // if we could not match a block literal, try to match a c++ lambda 047 if (index == NO_MATCH) { 048 return super.matchesLocally(parserState, tokens, startOffset); 049 } 050 return index; 051 } 052 053 /** 054 * Matches the circumflex that may start a block literal. If there is one we let 055 * the parser decide what to do with it. 056 */ 057 private static int matchBlockLiteralStart(ParserState<EGenericParserStates> parserState, List<IToken> tokens, 058 int startOffset) { 059 if (TokenStreamUtils.hasTokenTypeSequence(tokens, startOffset, ETokenType.XOR)) { 060 return parserState.parse(IN_EXPRESSION, tokens, startOffset); 061 } 062 063 return NO_MATCH; 064 } 065}