/* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ D [0-9] L [a-zA-Z_] H [a-fA-F0-9] E [Ee][+-]?{D}+ FS (f|F|l|L) IS (u|U|l|L)* COMPONENT {L}({L}|{D})* DOT [.] AT [@] VERSION {AT}{D}+{DOT}{D}+ FQNAME ({COMPONENT}|{VERSION})(({DOT}|":"+){COMPONENT}|{VERSION})* %{ #include "Annotation.h" #include "AST.h" #include "ArrayType.h" #include "CompoundType.h" #include "ConstantExpression.h" #include "DeathRecipientType.h" #include "EnumType.h" #include "HandleType.h" #include "MemoryType.h" #include "Method.h" #include "PointerType.h" #include "ScalarType.h" #include "StringType.h" #include "VectorType.h" #include "RefType.h" #include "FmqType.h" #include "hidl-gen_y.h" #include using namespace android; using token = yy::parser::token; #define SCALAR_TYPE(kind) \ do { \ yylval->type = new ScalarType(ScalarType::kind); \ return token::TYPE; \ } while (0) #define YY_USER_ACTION yylloc->step(); yylloc->columns(yyleng); #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-parameter" #pragma clang diagnostic ignored "-Wdeprecated-register" %} %option yylineno %option noyywrap %option nounput %option noinput %option reentrant %option bison-bridge %option bison-locations %x COMMENT_STATE %% "/*" { BEGIN(COMMENT_STATE); } "*/" { BEGIN(INITIAL); } [\n] { yylloc->lines(); } . { } "//"[^\r\n]* { /* skip C++ style comment */ } "enum" { return token::ENUM; } "extends" { return token::EXTENDS; } "generates" { return token::GENERATES; } "import" { return token::IMPORT; } "interface" { return token::INTERFACE; } "package" { return token::PACKAGE; } "struct" { return token::STRUCT; } "typedef" { return token::TYPEDEF; } "union" { return token::UNION; } "bitfield" { yylval->templatedType = new BitFieldType; return token::TEMPLATED; } "vec" { yylval->templatedType = new VectorType; return token::TEMPLATED; } "ref" { yylval->templatedType = new RefType; return token::TEMPLATED; } "oneway" { return token::ONEWAY; } "bool" { SCALAR_TYPE(KIND_BOOL); } "int8_t" { SCALAR_TYPE(KIND_INT8); } "uint8_t" { SCALAR_TYPE(KIND_UINT8); } "int16_t" { SCALAR_TYPE(KIND_INT16); } "uint16_t" { SCALAR_TYPE(KIND_UINT16); } "int32_t" { SCALAR_TYPE(KIND_INT32); } "uint32_t" { SCALAR_TYPE(KIND_UINT32); } "int64_t" { SCALAR_TYPE(KIND_INT64); } "uint64_t" { SCALAR_TYPE(KIND_UINT64); } "float" { SCALAR_TYPE(KIND_FLOAT); } "double" { SCALAR_TYPE(KIND_DOUBLE); } "death_recipient" { yylval->type = new DeathRecipientType; return token::TYPE; } "handle" { yylval->type = new HandleType; return token::TYPE; } "memory" { yylval->type = new MemoryType; return token::TYPE; } "pointer" { yylval->type = new PointerType; return token::TYPE; } "string" { yylval->type = new StringType; return token::TYPE; } "fmq_sync" { yylval->type = new FmqType("::android::hardware", "MQDescriptorSync"); return token::TEMPLATED; } "fmq_unsync" { yylval->type = new FmqType("::android::hardware", "MQDescriptorUnsync"); return token::TEMPLATED; } "(" { return('('); } ")" { return(')'); } "<" { return('<'); } ">" { return('>'); } "{" { return('{'); } "}" { return('}'); } "[" { return('['); } "]" { return(']'); } ":" { return(':'); } ";" { return(';'); } "," { return(','); } "." { return('.'); } "=" { return('='); } "+" { return('+'); } "-" { return('-'); } "*" { return('*'); } "/" { return('/'); } "%" { return('%'); } "&" { return('&'); } "|" { return('|'); } "^" { return('^'); } "<<" { return(token::LSHIFT); } ">>" { return(token::RSHIFT); } "&&" { return(token::LOGICAL_AND); } "||" { return(token::LOGICAL_OR); } "!" { return('!'); } "~" { return('~'); } "<=" { return(token::LEQ); } ">=" { return(token::GEQ); } "==" { return(token::EQUALITY); } "!=" { return(token::NEQ); } "?" { return('?'); } "@" { return('@'); } {COMPONENT} { yylval->str = strdup(yytext); return token::IDENTIFIER; } {FQNAME} { yylval->str = strdup(yytext); return token::FQNAME; } 0[xX]{H}+{IS}? { yylval->str = strdup(yytext); return token::INTEGER; } 0{D}+{IS}? { yylval->str = strdup(yytext); return token::INTEGER; } {D}+{IS}? { yylval->str = strdup(yytext); return token::INTEGER; } L?\"(\\.|[^\\"])*\" { yylval->str = strdup(yytext); return token::STRING_LITERAL; } {D}+{E}{FS}? { yylval->str = strdup(yytext); return token::FLOAT; } {D}+\.{E}?{FS}? { yylval->str = strdup(yytext); return token::FLOAT; } {D}*\.{D}+{E}?{FS}? { yylval->str = strdup(yytext); return token::FLOAT; } [\n] { yylloc->lines(); } . { /* ignore bad characters */ } %% #pragma clang diagnostic pop status_t parseFile(AST *ast) { FILE *file = fopen(ast->getFilename().c_str(), "rb"); if (file == nullptr) { return -errno; } yyscan_t scanner; yylex_init(&scanner); yyset_in(file, scanner); Scope* scopeStack = ast->getRootScope(); int res = yy::parser(scanner, ast, &scopeStack).parse(); yylex_destroy(scanner); fclose(file); file = nullptr; if (res != 0 || ast->syntaxErrors() != 0) { return UNKNOWN_ERROR; } return OK; }