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 "DocComment.h" 39#include "EnumType.h" 40#include "HandleType.h" 41#include "MemoryType.h" 42#include "Method.h" 43#include "PointerType.h" 44#include "ScalarType.h" 45#include "Scope.h" 46#include "StringType.h" 47#include "VectorType.h" 48#include "FmqType.h" 49 50#include "hidl-gen_y-helpers.h" 51 52#include <assert.h> 53#include <algorithm> 54#include <hidl-util/StringHelper.h> 55 56using namespace android; 57using token = yy::parser::token; 58 59#define SCALAR_TYPE(kind) \ 60 { \ 61 yylval->type = new ScalarType(ScalarType::kind, *scope); \ 62 return token::TYPE; \ 63 } 64 65#define YY_DECL int yylex(YYSTYPE* yylval_param, YYLTYPE* yylloc_param, \ 66 yyscan_t yyscanner, android::AST* const ast, android::Scope** const scope) 67 68#ifndef YYSTYPE 69#define YYSTYPE yy::parser::semantic_type 70#endif 71 72#ifndef YYLTYPE 73#define YYLTYPE yy::parser::location_type 74#endif 75 76#define YY_USER_ACTION yylloc->step(); yylloc->columns(yyleng); 77 78%} 79 80%option yylineno 81%option noyywrap 82%option nounput 83%option noinput 84%option reentrant 85%option bison-bridge 86%option bison-locations 87 88%% 89 90\/\*([^*]|\*+[^*\/])*\*+\/ { 91 std::string str(yytext); 92 93 // Add the lines to location (to keep it updated) 94 yylloc->lines(std::count(str.begin(), str.end(), '\n')); 95 96 str = StringHelper::LTrim(str, "/"); 97 bool isDoc = StringHelper::StartsWith(str, "**"); 98 str = StringHelper::LTrimAll(str, "*"); 99 str = StringHelper::RTrim(str, "/"); 100 str = StringHelper::RTrimAll(str, "*"); 101 102 yylval->str = strdup(str.c_str()); 103 return isDoc ? token::DOC_COMMENT : token::MULTILINE_COMMENT; 104 } 105 106"//"[^\r\n]* { 107 ast->addUnhandledComment( 108 new DocComment(yytext, 109 convertYYLoc(*yylloc, ast), 110 CommentType::SINGLELINE)); 111 } 112 113"enum" { return token::ENUM; } 114"extends" { return token::EXTENDS; } 115"generates" { return token::GENERATES; } 116"import" { return token::IMPORT; } 117"interface" { return token::INTERFACE; } 118"package" { return token::PACKAGE; } 119"safe_union" { return token::SAFE_UNION; } 120"struct" { return token::STRUCT; } 121"typedef" { return token::TYPEDEF; } 122"union" { return token::UNION; } 123"bitfield" { yylval->templatedType = new BitFieldType(*scope); return token::TEMPLATED; } 124"vec" { yylval->templatedType = new VectorType(*scope); return token::TEMPLATED; } 125"oneway" { return token::ONEWAY; } 126 127"bool" { SCALAR_TYPE(KIND_BOOL); } 128"int8_t" { SCALAR_TYPE(KIND_INT8); } 129"uint8_t" { SCALAR_TYPE(KIND_UINT8); } 130"int16_t" { SCALAR_TYPE(KIND_INT16); } 131"uint16_t" { SCALAR_TYPE(KIND_UINT16); } 132"int32_t" { SCALAR_TYPE(KIND_INT32); } 133"uint32_t" { SCALAR_TYPE(KIND_UINT32); } 134"int64_t" { SCALAR_TYPE(KIND_INT64); } 135"uint64_t" { SCALAR_TYPE(KIND_UINT64); } 136"float" { SCALAR_TYPE(KIND_FLOAT); } 137"double" { SCALAR_TYPE(KIND_DOUBLE); } 138 139"death_recipient" { yylval->type = new DeathRecipientType(*scope); return token::TYPE; } 140"handle" { yylval->type = new HandleType(*scope); return token::TYPE; } 141"memory" { yylval->type = new MemoryType(*scope); return token::TYPE; } 142"pointer" { yylval->type = new PointerType(*scope); return token::TYPE; } 143"string" { yylval->type = new StringType(*scope); return token::TYPE; } 144 145"fmq_sync" { yylval->type = new FmqType("::android::hardware", "MQDescriptorSync", *scope, "fmq_sync"); return token::TEMPLATED; } 146"fmq_unsync" { yylval->type = new FmqType("::android::hardware", "MQDescriptorUnsync", *scope, "fmq_unsync"); return token::TEMPLATED; } 147 148"(" { return('('); } 149")" { return(')'); } 150"<" { return('<'); } 151">" { return('>'); } 152"{" { return('{'); } 153"}" { return('}'); } 154"[" { return('['); } 155"]" { return(']'); } 156":" { return(':'); } 157";" { return(';'); } 158"," { return(','); } 159"." { return('.'); } 160"=" { return('='); } 161"+" { return('+'); } 162"-" { return('-'); } 163"*" { return('*'); } 164"/" { return('/'); } 165"%" { return('%'); } 166"&" { return('&'); } 167"|" { return('|'); } 168"^" { return('^'); } 169"<<" { return(token::LSHIFT); } 170">>" { return(token::RSHIFT); } 171"&&" { return(token::LOGICAL_AND); } 172"||" { return(token::LOGICAL_OR); } 173"!" { return('!'); } 174"~" { return('~'); } 175"<=" { return(token::LEQ); } 176">=" { return(token::GEQ); } 177"==" { return(token::EQUALITY); } 178"!=" { return(token::NEQ); } 179"?" { return('?'); } 180"@" { return('@'); } 181"#" { return('#'); } 182 183{COMPONENT} { yylval->str = strdup(yytext); return token::IDENTIFIER; } 184{FQNAME} { yylval->str = strdup(yytext); return token::FQNAME; } 185 1860[xX]{H}+{IS}? { yylval->str = strdup(yytext); return token::INTEGER; } 1870{D}+{IS}? { yylval->str = strdup(yytext); return token::INTEGER; } 188{D}+{IS}? { yylval->str = strdup(yytext); return token::INTEGER; } 189L?\"(\\.|[^\\"])*\" { yylval->str = strdup(yytext); return token::STRING_LITERAL; } 190 191{D}+{E}{FS}? { yylval->str = strdup(yytext); return token::FLOAT; } 192{D}+\.{E}?{FS}? { yylval->str = strdup(yytext); return token::FLOAT; } 193{D}*\.{D}+{E}?{FS}? { yylval->str = strdup(yytext); return token::FLOAT; } 194 195\n|\r\n { yylloc->lines(); } 196[ \t\f\v] { /* ignore all other whitespace */ } 197 198. { yylval->str = strdup(yytext); return token::UNKNOWN; } 199 200%% 201 202namespace android { 203 204status_t parseFile(AST* ast, std::unique_ptr<FILE, std::function<void(FILE *)>> file) { 205 yyscan_t scanner; 206 yylex_init(&scanner); 207 208 yyset_in(file.get(), scanner); 209 210 Scope* scopeStack = ast->getMutableRootScope(); 211 int res = yy::parser(scanner, ast, &scopeStack).parse(); 212 213 yylex_destroy(scanner); 214 215 if (res != 0 || ast->syntaxErrors() != 0) { 216 return UNKNOWN_ERROR; 217 } 218 219 return OK; 220} 221 222} // namespace android 223