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}