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.scanner.ETokenType.CONSTANT; 020import static eu.cqse.check.framework.scanner.ETokenType.GLOBAL; 021import static eu.cqse.check.framework.scanner.ETokenType.HALF; 022import static eu.cqse.check.framework.scanner.ETokenType.INTPTR_T; 023import static eu.cqse.check.framework.scanner.ETokenType.KERNEL; 024import static eu.cqse.check.framework.scanner.ETokenType.LBRACE; 025import static eu.cqse.check.framework.scanner.ETokenType.LOCAL; 026import static eu.cqse.check.framework.scanner.ETokenType.LPAREN; 027import static eu.cqse.check.framework.scanner.ETokenType.PRIVATE; 028import static eu.cqse.check.framework.scanner.ETokenType.PTRDIFF_T; 029import static eu.cqse.check.framework.scanner.ETokenType.RBRACE; 030import static eu.cqse.check.framework.scanner.ETokenType.READONLY; 031import static eu.cqse.check.framework.scanner.ETokenType.READWRITE; 032import static eu.cqse.check.framework.scanner.ETokenType.RPAREN; 033import static eu.cqse.check.framework.scanner.ETokenType.SIZE_T; 034import static eu.cqse.check.framework.scanner.ETokenType.UCHAR; 035import static eu.cqse.check.framework.scanner.ETokenType.UINT; 036import static eu.cqse.check.framework.scanner.ETokenType.UINTPTR_T; 037import static eu.cqse.check.framework.scanner.ETokenType.ULONG; 038import static eu.cqse.check.framework.scanner.ETokenType.USHORT; 039import static eu.cqse.check.framework.scanner.ETokenType.WRITEONLY; 040import static eu.cqse.check.framework.scanner.ETokenType.XOR; 041import static eu.cqse.check.framework.shallowparser.languages.base.EGenericParserStates.IN_EXPRESSION; 042import static eu.cqse.check.framework.shallowparser.languages.base.EGenericParserStates.IN_METHOD; 043 044import java.util.EnumSet; 045 046import eu.cqse.check.framework.scanner.ETokenType; 047import eu.cqse.check.framework.shallowparser.SubTypeNames; 048import eu.cqse.check.framework.shallowparser.framework.EShallowEntityType; 049import eu.cqse.check.framework.shallowparser.framework.RecognizerBase; 050import eu.cqse.check.framework.shallowparser.languages.base.EGenericParserStates; 051import eu.cqse.check.framework.shallowparser.languages.cpp.CppShallowParser; 052 053/** 054 * Shallow parser for OpenCL C/C++. 055 * 056 * Supports all features of {@link CppShallowParser}. Further it recognizes 057 * OpenCL specific keywords and supports parsing block literal expressions. 058 */ 059public class OpenCLShallowParser extends CppShallowParser { 060 061 /** Token types that are part of a primitive type. */ 062 public static final EnumSet<ETokenType> OPENCL_PRIMITIVE_TYPES = EnumSet.of(UCHAR, USHORT, UINT, ULONG, HALF, 063 SIZE_T, PTRDIFF_T, INTPTR_T, UINTPTR_T); 064 065 /** Token types for types or identifiers. */ 066 public static final EnumSet<ETokenType> OPENCL_TYPE_OR_IDENTIFIER = EnumSet 067 .copyOf(CppShallowParser.BASE_TYPE_OR_IDENTIFIER); 068 069 /** 070 * Token types that are modifiers in front of a type declaration or method. 071 */ 072 public static final EnumSet<ETokenType> OPENCL_METHOD_AND_TYPE_DECLARATION_MODIFIERS = EnumSet.of(GLOBAL, LOCAL, 073 CONSTANT, PRIVATE, KERNEL, READONLY, WRITEONLY, READWRITE); 074 075 static { 076 OPENCL_PRIMITIVE_TYPES.addAll(CppShallowParser.PRIMITIVE_TYPES); 077 OPENCL_TYPE_OR_IDENTIFIER.addAll(OPENCL_PRIMITIVE_TYPES); 078 OPENCL_METHOD_AND_TYPE_DECLARATION_MODIFIERS.addAll(CppShallowParser.METHOD_AND_TYPE_DECLARATION_MODIFIERS); 079 } 080 081 /** {@inheritDoc} */ 082 @Override 083 protected EnumSet<ETokenType> getPrimitiveTypes() { 084 return OPENCL_PRIMITIVE_TYPES; 085 } 086 087 /** {@inheritDoc} */ 088 @Override 089 protected EnumSet<ETokenType> getTypeOrIdentifier() { 090 return OPENCL_TYPE_OR_IDENTIFIER; 091 } 092 093 /** {@inheritDoc} */ 094 @Override 095 public EnumSet<ETokenType> getMethodAndTypeDeclarationModifiers() { 096 return OPENCL_METHOD_AND_TYPE_DECLARATION_MODIFIERS; 097 } 098 099 /** {@inheritDoc} */ 100 @Override 101 protected RecognizerBase<EGenericParserStates> getSubExpressionRecognizer() { 102 return new OpenCLLambdaAndBlockLiteralRecognizer(getTypeOrIdentifier()); 103 } 104 105 /** {@inheritDoc} */ 106 @Override 107 protected void createSubExpressionRules() { 108 RecognizerBase<EGenericParserStates> blockStart = inState(IN_EXPRESSION).sequence(XOR); 109 finishBlockRecognizer(typePattern(blockStart)); 110 finishBlockRecognizer(blockStart); 111 super.createSubExpressionRules(); 112 } 113 114 /** {@inheritDoc} */ 115 @Override 116 protected void createSimpleStatementRule() { 117 contributeExpandedMacroRule(); 118 contributeSimpleStatementRules(getValidIdentifiers(), getStatementStartTokens()); 119 } 120 121 /** 122 * Appends rules for parsing the parameter specification and body of a block 123 * literal to the given recognizer. 124 */ 125 private static void finishBlockRecognizer(RecognizerBase<EGenericParserStates> currentState) { 126 currentState.skipNested(LPAREN, RPAREN).sequence(LBRACE) 127 .createNode(EShallowEntityType.METHOD, SubTypeNames.BLOCK_LITERAL).parseUntil(IN_METHOD) 128 .sequence(RBRACE).endNode(); 129 } 130}