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 "RefType.h" 49#include "FmqType.h" 50 51#include "hidl-gen_y.h" 52 53#include <assert.h> 54 55using namespace android; 56using token = yy::parser::token; 57 58static std::string gCurrentComment; 59 60#define SCALAR_TYPE(kind) \ 61 { \ 62 yylval->type = new ScalarType(ScalarType::kind, *scope); \ 63 return token::TYPE; \ 64 } 65 66#define YY_DECL int yylex(YYSTYPE* yylval_param, YYLTYPE* yylloc_param, \ 67 yyscan_t yyscanner, android::Scope** const scope) 68 69#define YY_USER_ACTION yylloc->step(); yylloc->columns(yyleng); 70 71%} 72 73%option yylineno 74%option noyywrap 75%option nounput 76%option noinput 77%option reentrant 78%option bison-bridge 79%option bison-locations 80 81%x COMMENT_STATE 82%x DOC_COMMENT_STATE 83 84%% 85 86"/**" { gCurrentComment.clear(); BEGIN(DOC_COMMENT_STATE); } 87<DOC_COMMENT_STATE>"*/" { 88 BEGIN(INITIAL); 89 yylval->docComment = new DocComment(gCurrentComment); 90 return token::DOC_COMMENT; 91 } 92<DOC_COMMENT_STATE>[^*\n]* { gCurrentComment += yytext; } 93<DOC_COMMENT_STATE>[\n] { gCurrentComment += yytext; yylloc->lines(); } 94<DOC_COMMENT_STATE>[*] { gCurrentComment += yytext; } 95 96"/*" { BEGIN(COMMENT_STATE); } 97<COMMENT_STATE>"*/" { BEGIN(INITIAL); } 98<COMMENT_STATE>[\n] { yylloc->lines(); } 99<COMMENT_STATE>. { } 100 101"//"[^\r\n]* { /* skip C++ style comment */ } 102 103"enum" { return token::ENUM; } 104"extends" { return token::EXTENDS; } 105"generates" { return token::GENERATES; } 106"import" { return token::IMPORT; } 107"interface" { return token::INTERFACE; } 108"package" { return token::PACKAGE; } 109"safe_union" { return token::SAFE_UNION; } 110"struct" { return token::STRUCT; } 111"typedef" { return token::TYPEDEF; } 112"union" { return token::UNION; } 113"bitfield" { yylval->templatedType = new BitFieldType(*scope); return token::TEMPLATED; } 114"vec" { yylval->templatedType = new VectorType(*scope); return token::TEMPLATED; } 115"ref" { yylval->templatedType = new RefType(*scope); return token::TEMPLATED; } 116"oneway" { return token::ONEWAY; } 117 118"bool" { SCALAR_TYPE(KIND_BOOL); } 119"int8_t" { SCALAR_TYPE(KIND_INT8); } 120"uint8_t" { SCALAR_TYPE(KIND_UINT8); } 121"int16_t" { SCALAR_TYPE(KIND_INT16); } 122"uint16_t" { SCALAR_TYPE(KIND_UINT16); } 123"int32_t" { SCALAR_TYPE(KIND_INT32); } 124"uint32_t" { SCALAR_TYPE(KIND_UINT32); } 125"int64_t" { SCALAR_TYPE(KIND_INT64); } 126"uint64_t" { SCALAR_TYPE(KIND_UINT64); } 127"float" { SCALAR_TYPE(KIND_FLOAT); } 128"double" { SCALAR_TYPE(KIND_DOUBLE); } 129 130"death_recipient" { yylval->type = new DeathRecipientType(*scope); return token::TYPE; } 131"handle" { yylval->type = new HandleType(*scope); return token::TYPE; } 132"memory" { yylval->type = new MemoryType(*scope); return token::TYPE; } 133"pointer" { yylval->type = new PointerType(*scope); return token::TYPE; } 134"string" { yylval->type = new StringType(*scope); return token::TYPE; } 135 136"fmq_sync" { yylval->type = new FmqType("::android::hardware", "MQDescriptorSync", *scope); return token::TEMPLATED; } 137"fmq_unsync" { yylval->type = new FmqType("::android::hardware", "MQDescriptorUnsync", *scope); return token::TEMPLATED; } 138 139"(" { return('('); } 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(token::LSHIFT); } 161">>" { return(token::RSHIFT); } 162"&&" { return(token::LOGICAL_AND); } 163"||" { return(token::LOGICAL_OR); } 164"!" { return('!'); } 165"~" { return('~'); } 166"<=" { return(token::LEQ); } 167">=" { return(token::GEQ); } 168"==" { return(token::EQUALITY); } 169"!=" { return(token::NEQ); } 170"?" { return('?'); } 171"@" { return('@'); } 172"#" { return('#'); } 173 174{COMPONENT} { yylval->str = strdup(yytext); return token::IDENTIFIER; } 175{FQNAME} { yylval->str = strdup(yytext); return token::FQNAME; } 176 1770[xX]{H}+{IS}? { yylval->str = strdup(yytext); return token::INTEGER; } 1780{D}+{IS}? { yylval->str = strdup(yytext); return token::INTEGER; } 179{D}+{IS}? { yylval->str = strdup(yytext); return token::INTEGER; } 180L?\"(\\.|[^\\"])*\" { yylval->str = strdup(yytext); return token::STRING_LITERAL; } 181 182{D}+{E}{FS}? { yylval->str = strdup(yytext); return token::FLOAT; } 183{D}+\.{E}?{FS}? { yylval->str = strdup(yytext); return token::FLOAT; } 184{D}*\.{D}+{E}?{FS}? { yylval->str = strdup(yytext); return token::FLOAT; } 185 186\n|\r\n { yylloc->lines(); } 187[ \t\f\v] { /* ignore all other whitespace */ } 188 189. { yylval->str = strdup(yytext); return token::UNKNOWN; } 190 191%% 192 193namespace android { 194 195status_t parseFile(AST* ast, std::unique_ptr<FILE, std::function<void(FILE *)>> file) { 196 yyscan_t scanner; 197 yylex_init(&scanner); 198 199 yyset_in(file.get(), scanner); 200 201 Scope* scopeStack = ast->getRootScope(); 202 int res = yy::parser(scanner, ast, &scopeStack).parse(); 203 204 yylex_destroy(scanner); 205 206 if (res != 0 || ast->syntaxErrors() != 0) { 207 return UNKNOWN_ERROR; 208 } 209 210 return OK; 211} 212 213} // namespace android 214