| /* | 
 |  * 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 "DocComment.h" | 
 | #include "EnumType.h" | 
 | #include "HandleType.h" | 
 | #include "MemoryType.h" | 
 | #include "Method.h" | 
 | #include "PointerType.h" | 
 | #include "ScalarType.h" | 
 | #include "Scope.h" | 
 | #include "StringType.h" | 
 | #include "VectorType.h" | 
 | #include "FmqType.h" | 
 |  | 
 | #include "hidl-gen_y-helpers.h" | 
 |  | 
 | #include <assert.h> | 
 | #include <algorithm> | 
 | #include <hidl-util/StringHelper.h> | 
 |  | 
 | using namespace android; | 
 | using token = yy::parser::token; | 
 |  | 
 | #define SCALAR_TYPE(kind)                                        \ | 
 |     {                                                            \ | 
 |         yylval->type = new ScalarType(ScalarType::kind, *scope); \ | 
 |         return token::TYPE;                                      \ | 
 |     } | 
 |  | 
 | #define YY_DECL int yylex(YYSTYPE* yylval_param, YYLTYPE* yylloc_param,  \ | 
 |     yyscan_t yyscanner, android::AST* const ast, android::Scope** const scope) | 
 |  | 
 | #define YY_USER_ACTION yylloc->step(); yylloc->columns(yyleng); | 
 |  | 
 | %} | 
 |  | 
 | %option yylineno | 
 | %option noyywrap | 
 | %option nounput | 
 | %option noinput | 
 | %option reentrant | 
 | %option bison-bridge | 
 | %option bison-locations | 
 |  | 
 | %% | 
 |  | 
 | \/\*([^*]|\*+[^*\/])*\*+\/  { | 
 |                                 std::string str(yytext); | 
 |  | 
 |                                 // Add the lines to location (to keep it updated) | 
 |                                 yylloc->lines(std::count(str.begin(), str.end(), '\n')); | 
 |  | 
 |                                 str = StringHelper::LTrim(str, "/"); | 
 |                                 bool isDoc = StringHelper::StartsWith(str, "**"); | 
 |                                 str = StringHelper::LTrimAll(str, "*"); | 
 |                                 str = StringHelper::RTrim(str, "/"); | 
 |                                 str = StringHelper::RTrimAll(str, "*"); | 
 |  | 
 |                                 yylval->str = strdup(str.c_str()); | 
 |                                 return isDoc ? token::DOC_COMMENT : token::MULTILINE_COMMENT; | 
 |                             } | 
 |  | 
 | "//"[^\r\n]*        { | 
 |                         ast->addUnhandledComment( | 
 |                                 new DocComment(yytext, | 
 |                                                convertYYLoc(*yylloc, ast), | 
 |                                                CommentType::SINGLELINE)); | 
 |                     } | 
 |  | 
 | "enum"              { return token::ENUM; } | 
 | "extends"           { return token::EXTENDS; } | 
 | "generates"         { return token::GENERATES; } | 
 | "import"            { return token::IMPORT; } | 
 | "interface"         { return token::INTERFACE; } | 
 | "package"           { return token::PACKAGE; } | 
 | "safe_union"        { return token::SAFE_UNION; } | 
 | "struct"            { return token::STRUCT; } | 
 | "typedef"           { return token::TYPEDEF; } | 
 | "union"             { return token::UNION; } | 
 | "bitfield"          { yylval->templatedType = new BitFieldType(*scope); return token::TEMPLATED; } | 
 | "vec"               { yylval->templatedType = new VectorType(*scope); 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(*scope); return token::TYPE; } | 
 | "handle"            { yylval->type = new HandleType(*scope); return token::TYPE; } | 
 | "memory"            { yylval->type = new MemoryType(*scope); return token::TYPE; } | 
 | "pointer"           { yylval->type = new PointerType(*scope); return token::TYPE; } | 
 | "string"            { yylval->type = new StringType(*scope); return token::TYPE; } | 
 |  | 
 | "fmq_sync"          { yylval->type = new FmqType("::android::hardware", "MQDescriptorSync", *scope, "fmq_sync"); return token::TEMPLATED; } | 
 | "fmq_unsync"        { yylval->type = new FmqType("::android::hardware", "MQDescriptorUnsync", *scope, "fmq_unsync"); 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('@'); } | 
 | "#"                 { 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|\r\n             { yylloc->lines(); } | 
 | [ \t\f\v]           { /* ignore all other whitespace */ } | 
 |  | 
 | .                   { yylval->str = strdup(yytext); return token::UNKNOWN; } | 
 |  | 
 | %% | 
 |  | 
 | namespace android { | 
 |  | 
 | status_t parseFile(AST* ast, std::unique_ptr<FILE, std::function<void(FILE *)>> file) { | 
 |     yyscan_t scanner; | 
 |     yylex_init(&scanner); | 
 |  | 
 |     yyset_in(file.get(), scanner); | 
 |  | 
 |     Scope* scopeStack = ast->getMutableRootScope(); | 
 |     int res = yy::parser(scanner, ast, &scopeStack).parse(); | 
 |  | 
 |     yylex_destroy(scanner); | 
 |  | 
 |     if (res != 0 || ast->syntaxErrors() != 0) { | 
 |         return UNKNOWN_ERROR; | 
 |     } | 
 |  | 
 |     return OK; | 
 | } | 
 |  | 
 | }  // namespace android |