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