| /* |
| * 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 "Scope.h" |
| #include "StringType.h" |
| #include "VectorType.h" |
| #include "RefType.h" |
| #include "FmqType.h" |
| |
| #include "hidl-gen_y.h" |
| |
| #include <assert.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::Scope** const scope) |
| |
| #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" |
| #pragma clang diagnostic ignored "-Wregister" |
| |
| %} |
| |
| %option yylineno |
| %option noyywrap |
| %option nounput |
| %option noinput |
| %option reentrant |
| %option bison-bridge |
| %option bison-locations |
| |
| %x COMMENT_STATE |
| |
| %% |
| |
| "/*" { BEGIN(COMMENT_STATE); } |
| <COMMENT_STATE>"*/" { BEGIN(INITIAL); } |
| <COMMENT_STATE>[\n] { yylloc->lines(); } |
| <COMMENT_STATE>. { } |
| |
| "//"[^\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(*scope); return token::TEMPLATED; } |
| "vec" { yylval->templatedType = new VectorType(*scope); return token::TEMPLATED; } |
| "ref" { yylval->templatedType = new RefType(*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); return token::TEMPLATED; } |
| "fmq_unsync" { yylval->type = new FmqType("::android::hardware", "MQDescriptorUnsync", *scope); 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|\r\n { yylloc->lines(); } |
| [ \t\f\v] { /* ignore all other whitespace */ } |
| |
| . { yylval->str = strdup(yytext); return token::UNKNOWN; } |
| |
| %% |
| |
| #pragma clang diagnostic pop |
| |
| 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->getRootScope(); |
| int res = yy::parser(scanner, ast, &scopeStack).parse(); |
| |
| yylex_destroy(scanner); |
| |
| if (res != 0 || ast->syntaxErrors() != 0) { |
| return UNKNOWN_ERROR; |
| } |
| |
| return OK; |
| } |
| |
| } // namespace android |