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 17 D [0-9] 18 L [a-zA-Z_] 19 H [a-fA-F0-9] 20 E [Ee][+-]?{D}+ 21 FS (f|F|l|L) 22 IS (u|U|l|L)* 23 24 COMPONENT {L}({L}|{D})* 25 DOT [.] 26 PATH {COMPONENT}({DOT}{COMPONENT})* 27 AT [@] 28 VERSION {AT}{D}+{DOT}{D}+ 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 53 using namespace android; 54 using token = yy::parser::token; 55 56 int check_type(yyscan_t yyscanner, struct yyguts_t *yyg); 57 58 #define SCALAR_TYPE(kind) \ 59 do { \ 60 yylval->type = new ScalarType(ScalarType::kind); \ 61 return token::TYPE; \ 62 } while (0) 63 64 #define YY_USER_ACTION yylloc->step(); yylloc->columns(yyleng); 65 66 #pragma clang diagnostic push 67 #pragma clang diagnostic ignored "-Wunused-parameter" 68 #pragma clang diagnostic ignored "-Wdeprecated-register" 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 %x COMMENT_STATE 81 82 %% 83 84 "/*" { BEGIN(COMMENT_STATE); } 85 <COMMENT_STATE>"*/" { BEGIN(INITIAL); } 86 <COMMENT_STATE>[\n] { yylloc->lines(); } 87 <COMMENT_STATE>. { } 88 89 "//"[^\r\n]* { /* skip C++ style comment */ } 90 91 "enum" { return token::ENUM; } 92 "extends" { return token::EXTENDS; } 93 "generates" { return token::GENERATES; } 94 "import" { return token::IMPORT; } 95 "interface" { return token::INTERFACE; } 96 "package" { return token::PACKAGE; } 97 "struct" { return token::STRUCT; } 98 "typedef" { return token::TYPEDEF; } 99 "union" { return token::UNION; } 100 "bitfield" { yylval->templatedType = new BitFieldType; return token::TEMPLATED; } 101 "vec" { yylval->templatedType = new VectorType; return token::TEMPLATED; } 102 "ref" { yylval->templatedType = new RefType; return token::TEMPLATED; } 103 "oneway" { return token::ONEWAY; } 104 105 "bool" { SCALAR_TYPE(KIND_BOOL); } 106 "int8_t" { SCALAR_TYPE(KIND_INT8); } 107 "uint8_t" { SCALAR_TYPE(KIND_UINT8); } 108 "int16_t" { SCALAR_TYPE(KIND_INT16); } 109 "uint16_t" { SCALAR_TYPE(KIND_UINT16); } 110 "int32_t" { SCALAR_TYPE(KIND_INT32); } 111 "uint32_t" { SCALAR_TYPE(KIND_UINT32); } 112 "int64_t" { SCALAR_TYPE(KIND_INT64); } 113 "uint64_t" { SCALAR_TYPE(KIND_UINT64); } 114 "float" { SCALAR_TYPE(KIND_FLOAT); } 115 "double" { SCALAR_TYPE(KIND_DOUBLE); } 116 117 "death_recipient" { yylval->type = new DeathRecipientType; return token::TYPE; } 118 "handle" { yylval->type = new HandleType; return token::TYPE; } 119 "memory" { yylval->type = new MemoryType; return token::TYPE; } 120 "pointer" { yylval->type = new PointerType; return token::TYPE; } 121 "string" { yylval->type = new StringType; return token::TYPE; } 122 123 "fmq_sync" { yylval->type = new FmqType("::android::hardware", "MQDescriptorSync"); return token::TEMPLATED; } 124 "fmq_unsync" { yylval->type = new FmqType("::android::hardware", "MQDescriptorUnsync"); return token::TEMPLATED; } 125 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('|'); } 146 "^" { return('^'); } 147 "<<" { return(token::LSHIFT); } 148 ">>" { return(token::RSHIFT); } 149 "&&" { return(token::LOGICAL_AND); } 150 "||" { return(token::LOGICAL_OR); } 151 "!" { return('!'); } 152 "~" { return('~'); } 153 "<=" { return(token::LEQ); } 154 ">=" { return(token::GEQ); } 155 "==" { return(token::EQUALITY); } 156 "!=" { return(token::NEQ); } 157 "?" { return('?'); } 158 "@" { return('@'); } 159 160 {PATH}{VERSION}"::"{PATH} { yylval->str = strdup(yytext); return token::FQNAME; } 161 {VERSION}"::"{PATH} { yylval->str = strdup(yytext); return token::FQNAME; } 162 {PATH}{VERSION} { yylval->str = strdup(yytext); return token::FQNAME; } 163 {COMPONENT}({DOT}{COMPONENT})+ { yylval->str = strdup(yytext); return token::FQNAME; } 164 {COMPONENT} { yylval->str = strdup(yytext); return token::IDENTIFIER; } 165 166 {PATH}{VERSION}"::"{PATH}":"{COMPONENT} { yylval->str = strdup(yytext); return token::FQNAME; } 167 {VERSION}"::"{PATH}":"{COMPONENT} { yylval->str = strdup(yytext); return token::FQNAME; } 168 {PATH}":"{COMPONENT} { yylval->str = strdup(yytext); return token::FQNAME; } 169 170 0[xX]{H}+{IS}? { yylval->str = strdup(yytext); return token::INTEGER; } 171 0{D}+{IS}? { yylval->str = strdup(yytext); return token::INTEGER; } 172 {D}+{IS}? { yylval->str = strdup(yytext); return token::INTEGER; } 173 L?\"(\\.|[^\\"])*\" { yylval->str = strdup(yytext); return token::STRING_LITERAL; } 174 175 {D}+{E}{FS}? { yylval->str = strdup(yytext); return token::FLOAT; } 176 {D}+\.{E}?{FS}? { yylval->str = strdup(yytext); return token::FLOAT; } 177 {D}*\.{D}+{E}?{FS}? { yylval->str = strdup(yytext); return token::FLOAT; } 178 179 [\n] { yylloc->lines(); } 180 . { /* ignore bad characters */ } 181 182 %% 183 184 #pragma clang diagnostic pop 185 186 status_t parseFile(AST *ast) { 187 FILE *file = fopen(ast->getFilename().c_str(), "rb"); 188 189 if (file == NULL) { 190 return -errno; 191 } 192 193 yyscan_t scanner; 194 yylex_init_extra(ast, &scanner); 195 ast->setScanner(scanner); 196 197 yyset_in(file, scanner); 198 int res = yy::parser(ast).parse(); 199 200 yylex_destroy(scanner); 201 ast->setScanner(NULL); 202 203 fclose(file); 204 file = NULL; 205 206 if (res != 0 || ast->syntaxErrors() != 0) { 207 return UNKNOWN_ERROR; 208 } 209 210 return OK; 211 } 212