1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17D [0-9] 18L [a-zA-Z_] 19H [a-fA-F0-9] 20E [Ee][+-]?{D}+ 21FS (f|F|l|L) 22IS (u|U|l|L)* 23 24COMPONENT {L}({L}|{D})* 25DOT [.] 26AT [@] 27VERSION {AT}{D}+{DOT}{D}+ 28FQNAME ({COMPONENT}|{VERSION})(({DOT}|":"+){COMPONENT}|{VERSION})* 29 30%{ 31 32#include "Annotation.h" 33#include "AST.h" 34#include "ArrayType.h" 35#include "CompoundType.h" 36#include "ConstantExpression.h" 37#include "DeathRecipientType.h" 38#include "EnumType.h" 39#include "HandleType.h" 40#include "MemoryType.h" 41#include "Method.h" 42#include "PointerType.h" 43#include "ScalarType.h" 44#include "StringType.h" 45#include "VectorType.h" 46#include "RefType.h" 47#include "FmqType.h" 48 49#include "hidl-gen_y.h" 50 51#include <assert.h> 52 53using namespace android; 54using token = yy::parser::token; 55 56#define SCALAR_TYPE(kind) \ 57 do { \ 58 yylval->type = new ScalarType(ScalarType::kind); \ 59 return token::TYPE; \ 60 } while (0) 61 62#define YY_USER_ACTION yylloc->step(); yylloc->columns(yyleng); 63 64#pragma clang diagnostic push 65#pragma clang diagnostic ignored "-Wunused-parameter" 66#pragma clang diagnostic ignored "-Wdeprecated-register" 67 68%} 69 70%option yylineno 71%option noyywrap 72%option nounput 73%option noinput 74%option reentrant 75%option bison-bridge 76%option bison-locations 77 78%x COMMENT_STATE 79 80%% 81 82"/*" { BEGIN(COMMENT_STATE); } 83<COMMENT_STATE>"*/" { BEGIN(INITIAL); } 84<COMMENT_STATE>[\n] { yylloc->lines(); } 85<COMMENT_STATE>. { } 86 87"//"[^\r\n]* { /* skip C++ style comment */ } 88 89"enum" { return token::ENUM; } 90"extends" { return token::EXTENDS; } 91"generates" { return token::GENERATES; } 92"import" { return token::IMPORT; } 93"interface" { return token::INTERFACE; } 94"package" { return token::PACKAGE; } 95"struct" { return token::STRUCT; } 96"typedef" { return token::TYPEDEF; } 97"union" { return token::UNION; } 98"bitfield" { yylval->templatedType = new BitFieldType; return token::TEMPLATED; } 99"vec" { yylval->templatedType = new VectorType; return token::TEMPLATED; } 100"ref" { yylval->templatedType = new RefType; return token::TEMPLATED; } 101"oneway" { return token::ONEWAY; } 102 103"bool" { SCALAR_TYPE(KIND_BOOL); } 104"int8_t" { SCALAR_TYPE(KIND_INT8); } 105"uint8_t" { SCALAR_TYPE(KIND_UINT8); } 106"int16_t" { SCALAR_TYPE(KIND_INT16); } 107"uint16_t" { SCALAR_TYPE(KIND_UINT16); } 108"int32_t" { SCALAR_TYPE(KIND_INT32); } 109"uint32_t" { SCALAR_TYPE(KIND_UINT32); } 110"int64_t" { SCALAR_TYPE(KIND_INT64); } 111"uint64_t" { SCALAR_TYPE(KIND_UINT64); } 112"float" { SCALAR_TYPE(KIND_FLOAT); } 113"double" { SCALAR_TYPE(KIND_DOUBLE); } 114 115"death_recipient" { yylval->type = new DeathRecipientType; return token::TYPE; } 116"handle" { yylval->type = new HandleType; return token::TYPE; } 117"memory" { yylval->type = new MemoryType; return token::TYPE; } 118"pointer" { yylval->type = new PointerType; return token::TYPE; } 119"string" { yylval->type = new StringType; return token::TYPE; } 120 121"fmq_sync" { yylval->type = new FmqType("::android::hardware", "MQDescriptorSync"); return token::TEMPLATED; } 122"fmq_unsync" { yylval->type = new FmqType("::android::hardware", "MQDescriptorUnsync"); return token::TEMPLATED; } 123 124"(" { return('('); } 125")" { return(')'); } 126"<" { return('<'); } 127">" { return('>'); } 128"{" { return('{'); } 129"}" { return('}'); } 130"[" { return('['); } 131"]" { return(']'); } 132":" { return(':'); } 133";" { return(';'); } 134"," { return(','); } 135"." { return('.'); } 136"=" { return('='); } 137"+" { return('+'); } 138"-" { return('-'); } 139"*" { return('*'); } 140"/" { return('/'); } 141"%" { return('%'); } 142"&" { return('&'); } 143"|" { return('|'); } 144"^" { return('^'); } 145"<<" { return(token::LSHIFT); } 146">>" { return(token::RSHIFT); } 147"&&" { return(token::LOGICAL_AND); } 148"||" { return(token::LOGICAL_OR); } 149"!" { return('!'); } 150"~" { return('~'); } 151"<=" { return(token::LEQ); } 152">=" { return(token::GEQ); } 153"==" { return(token::EQUALITY); } 154"!=" { return(token::NEQ); } 155"?" { return('?'); } 156"@" { return('@'); } 157 158{COMPONENT} { yylval->str = strdup(yytext); return token::IDENTIFIER; } 159{FQNAME} { yylval->str = strdup(yytext); return token::FQNAME; } 160 1610[xX]{H}+{IS}? { yylval->str = strdup(yytext); return token::INTEGER; } 1620{D}+{IS}? { yylval->str = strdup(yytext); return token::INTEGER; } 163{D}+{IS}? { yylval->str = strdup(yytext); return token::INTEGER; } 164L?\"(\\.|[^\\"])*\" { yylval->str = strdup(yytext); return token::STRING_LITERAL; } 165 166{D}+{E}{FS}? { yylval->str = strdup(yytext); return token::FLOAT; } 167{D}+\.{E}?{FS}? { yylval->str = strdup(yytext); return token::FLOAT; } 168{D}*\.{D}+{E}?{FS}? { yylval->str = strdup(yytext); return token::FLOAT; } 169 170[\n] { yylloc->lines(); } 171. { /* ignore bad characters */ } 172 173%% 174 175#pragma clang diagnostic pop 176 177status_t parseFile(AST *ast) { 178 FILE *file = fopen(ast->getFilename().c_str(), "rb"); 179 180 if (file == nullptr) { 181 return -errno; 182 } 183 184 yyscan_t scanner; 185 yylex_init(&scanner); 186 187 yyset_in(file, scanner); 188 189 Scope* scopeStack = ast->getRootScope(); 190 int res = yy::parser(scanner, ast, &scopeStack).parse(); 191 192 yylex_destroy(scanner); 193 194 fclose(file); 195 file = nullptr; 196 197 if (res != 0 || ast->syntaxErrors() != 0) { 198 return UNKNOWN_ERROR; 199 } 200 201 return OK; 202} 203