/* * 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 "RefType.h" #include "FmqType.h" #include "hidl-gen_y.h" #include <assert.h> using namespace android; using token = yy::parser::token; static std::string gCurrentComment; #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 %x DOC_COMMENT_STATE %% "/**" { gCurrentComment.clear(); BEGIN(DOC_COMMENT_STATE); } <DOC_COMMENT_STATE>"*/" { BEGIN(INITIAL); yylval->docComment = new DocComment(gCurrentComment); return token::DOC_COMMENT; } <DOC_COMMENT_STATE>[^*\n]* { gCurrentComment += yytext; } <DOC_COMMENT_STATE>[\n] { gCurrentComment += yytext; yylloc->lines(); } <DOC_COMMENT_STATE>[*] { gCurrentComment += yytext; } "/*" { 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