/*
 * 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
