/* -----------------------------------------------------------------------------
 * sql.yy
 *
 * A simple context-free grammar to parse SQL files and translating
 * CREATE FUNCTION statements into C++ function declarations.
 * This allows .sql files to be documented by documentation tools like Doxygen.
 *
 * Revision History:
 * 0.3: Florian Schoppmann, 29 Jan 2011, CREATE AGGREGATE supported, return
 *                                       types inferred from final function,
 *                                       line numbers are preserved
 * 0.2:          "        , 16 Jan 2011, Converted to C++
 * 0.1:          "        , 10 Jan 2011, Initial version, support for CREATE
 *                                       FUNCTION.
 * -----------------------------------------------------------------------------
 */

/* The %code directive needs bison >= 2.4 */
%require "2.4"

%code requires {
    #include <map>
    #include <fstream>
    #include <cstring>

    /*
     * FIXME: We should not disable warnings. Without this option, we would
     * get the following warnings:
     * 1) deprecated conversion from string constant to 'char*'
     * 2) ignoring return value of '...', declared with attribute
     *    warn_unused_result
     */
    #if defined(__GNUC__)
        #if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))
            #pragma GCC diagnostic ignored "-Wwrite-strings"
        #endif
        #if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
            #pragma GCC diagnostic ignored "-Wunused-result"
        #endif

        #pragma GCC diagnostic ignored "-Wconversion"
    #endif

    #ifdef COMPILING_SCANNER
        /* Flex expects the signature of yylex to be defined in the macro
         * YY_DECL. */
        #define YY_DECL                                        \
            int                                                \
            bison::SQLScanner::lex(                            \
                bison::SQLParser::semantic_type *yylval,    \
                bison::SQLParser::location_type *yylloc,    \
                bison::SQLDriver *driver                    \
            )
    #else
        /* In the parser, we need to call the lexer and therefore need the
         * lexer class declaration. */
        #define yyFlexLexer SQLFlexLexer
        #undef yylex
        #include "FlexLexer.h"
        #undef yyFlexLexer
    #endif

    namespace bison {

    /* Forward declaration because referenced by generated class declaration
     * SQLParser */
    class SQLDriver;

    }
}

%code provides {
    namespace bison {

    class SQLScanner;

    class SQLDriver
    {
    public:
        class CountingOStream {
        public:
            CountingOStream();
            CountingOStream &advance(int line);
            CountingOStream &operator<<(const char *str);
            CountingOStream &operator<<(char c);

            int     currentLine;
        };

        SQLDriver(const std::string &inExeName, const std::string &inFilename);
        virtual ~SQLDriver();
        void error(const SQLParser::location_type &l, const std::string &m);
        void error(const std::string &m);

        CountingOStream                 cout;
        std::map<std::string, char *>    fnToReturnType;
        SQLScanner                        *scanner;
        std::string                     exeName;
        std::string                     filename;
    };

    /* We need to subclass because SQLFlexLexer's yylex function does not have
     * the proper signature */
    class SQLScanner : public SQLFlexLexer
    {
    public:
        SQLScanner(std::istream *arg_yyin = 0, std::ostream* arg_yyout = 0);
        virtual ~SQLScanner();
        static inline char *strlowerdup(const char *inString);
        int lex(SQLParser::semantic_type *yylval,
            SQLParser::location_type *yylloc, SQLDriver *driver);
        void preScannerAction(SQLParser::semantic_type *yylval,
            SQLParser::location_type *yylloc, SQLDriver *driver);
        void more();

        char            *stringLiteralQuotation;
        unsigned long   oldLength;
    };

    class TaggedStr
    {
    public:
        TaggedStr(int inTag, char *inStr) : tag(inTag), str(inStr) { };
        virtual ~TaggedStr() { };

        int        tag;
        char    *str;
    };

    } // namespace bison

    /* "Connect" the bison parser in the driver to the flex scanner class
     * object. The C++ scanner generated by flex is a bit ugly, therefore
     * this sort of hack here.
     */
    #undef yylex
    #define yylex driver->scanner->lex
}

/* write out a header file containing the token defines */
%defines

/* use C++ and its skeleton file */
%skeleton "lalr1.cc"

/* keep track of the current position within the input */
%locations
%initial-action {
    // Initialize the initial location.
    @$.begin.filename = @$.end.filename = &driver->filename;
};

/* The name of the parser class. */
%define parser_class_name "SQLParser"

/* Declare that an argument declared by the braced-code `argument-declaration'
 * is an additional yyparse argument. The `argument-declaration' is used when
 * declaring functions or prototypes. The last identifier in
 * `argument-declaration' must be the argument name. */
%parse-param { SQLDriver *driver }

/* Declare that the braced-code argument-declaration is an additional yylex
 * argument declaration. */
%lex-param   { SQLDriver *driver }

/* namespace to enclose parser in */
%name-prefix="bison"

%union
{
    char            *str;
    class TaggedStr    *tStr;
    int                i;
}

%token            END        0    "end of file"
%token <str>    IDENTIFIER    "identifier"

%token <str>    COMMENT

%token            CREATE_FUNCTION
%token            CREATE_AGGREGATE

/* Function tokens */
%token            IN
%token            OUT
%token            INOUT

%token            RETURNS
%token            SETOF

%token            AS
%token            LANGUAGE
%token            IMMUTABLE
%token            STABLE
%token            VOLATILE
%token            CALLED_ON_NULL_INPUT
%token            RETURNS_NULL_ON_NULL_INPUT
%token            SECURITY_INVOKER
%token            SECURITY_DEFINER

%token          DEFAULT

/* Aggregate tokens */
%token    <i>        SFUNC
%token    <i>        PREFUNC
%token    <i>        FINALFUNC
%token            SORTOP
%token            STYPE
%token            INITCOND

/* types with more than 1 word */
%token            BIT
%token            CHARACTER
%token            DOUBLE
%token            PRECISION
%token            TIME
%token            VARYING
%token            VOID
%token            WITH
%token            WITHOUT
%token            ZONE

%token    <str>    INTEGER_LITERAL
%token  <str>   FLOAT_LITERAL
%token    <str>    STRING_LITERAL
%token  <str>   NULL_KEYWORD

/* Special tokens, for extending SQL syntax in C commands */
%token          BEGIN_SPECIAL
%token          END_SPECIAL

%type   <str>   expr
%type   <str>   prefixExpr
%type    <str>    qualifiedIdent
%type    <str>    optFnArgList fnArgList fnArgument
%type   <str>   optDefaultArgument defaultArgument
%type    <str>    optAggArgList aggArgList aggArgument
%type    <str>    argname    type baseType optLength optArray array
%type    <str>    returnDecl retType
%type    <tStr>    aggOptionList aggOption
%type    <i>        aggFunc


%% /* Grammar rules and actions follow. */

input:
    | input stmt
    | input COMMENT { driver->cout.advance(@2.begin.line) << $2; }
    | input '\n' { driver->cout << '\n'; }
;

stmt:
      ';'
    | createFnStmt ';'
    | createAggStmt ';'
;

createFnStmt:
      CREATE_FUNCTION qualifiedIdent '(' optFnArgList ')' returnDecl fnOptions {
        driver->cout.advance(@1.begin.line) << $6 << ' ' << $2 << '(' << $4 << ") { };";
        driver->fnToReturnType.insert(std::pair<std::string,char *>($2, $6));
    }
;

createAggStmt:
      CREATE_AGGREGATE qualifiedIdent '(' optAggArgList ')' '(' aggOptionList ')' {
        driver->cout.advance(@1.begin.line) << "@aggregate "
            << ($7 == NULL ? "" : $7->str) << ' ' << $2 << '(' << $4 << ") { };";
    }
;

qualifiedIdent:
      IDENTIFIER
    | IDENTIFIER '.' IDENTIFIER {
        $$ = $3;
    }
;

optFnArgList: { $$ = ""; }
    | fnArgList
;

optAggArgList:
      '*' { $$ = ""; }
    | aggArgList
;

fnArgList:
      fnArgList ',' fnArgument {
        /* Yes, we'll leak memory. And we'll fail if there is not enough.
         * We ignore all that here and below. */
        asprintf(&($$), "%s, %s", $1, $3);
    }
    | fnArgument
;

aggArgList:
      aggArgList ',' aggArgument {
        asprintf(&($$), "%s, %s", $1, $3);
    }
    | aggArgument

fnArgument:
      type optDefaultArgument {
        asprintf(&($$), "%s%s", $1, $2);
    }
    | argname type optDefaultArgument {
        asprintf(&($$), "%s %s%s", $2, $1, $3);
    }
    | argmode argname type optDefaultArgument {
        asprintf(&($$), "%s %s%s", $3, $2, $4);
    }
;

optDefaultArgument: { $$ = ""; }
    | defaultArgument
    | BEGIN_SPECIAL defaultArgument END_SPECIAL { $$ = $2; }
;

defaultArgument:
      DEFAULT expr {
        asprintf(&($$), " = %s", $2);
    }
    | '=' expr {
        asprintf(&($$), " = %s", $2);
    }
;

aggArgument:
      type optDefaultArgument
    | argname type optDefaultArgument {
        asprintf(&($$), "%s %s%s", $2, $1, $3);
    }
;

argmode:
      IN
    | OUT
    | INOUT
;

argname:
      IDENTIFIER
    | BEGIN_SPECIAL IDENTIFIER END_SPECIAL { $$ = $2; }
;

type:
      baseType optArray {
        asprintf(&($$), "%s%s", $1, $2);
    }
;

baseType:
      qualifiedIdent
    | BIT VARYING optLength {
        asprintf(&($$), "varbit%s", $3);
    }
    | CHARACTER VARYING optLength {
        asprintf(&($$), "varchar%s", $3);
    }
    | DOUBLE PRECISION { $$ = "float8"; }
    | VOID { $$ = "void"; }
;

optArray: { $$ = ""; }
    | array;

optLength: { $$ = ""; }
    | '(' INTEGER_LITERAL ')' {
        asprintf(&($$), "(%s)", $2);
    }
;

array:
      '[' ']' { $$ = "[]"; }
    | '[' INTEGER_LITERAL ']' {
        asprintf(&($$), "[%s]", $2);
    }
    | array '[' ']' {
        asprintf(&($$), "%s[]", $1);
    }
    | array '[' INTEGER_LITERAL ']' {
        asprintf(&($$), "%s[%s]", $1, $3);
    }
;

returnDecl: { $$ = "void"; }
    | RETURNS retType { $$ = $2; }
;

retType:
      type
    | SETOF type {
        asprintf(&($$), "set<%s>", $2);
    }
;

fnOptions:
    | fnOptions fnOption;

fnOption:
      AS STRING_LITERAL
    | AS STRING_LITERAL ',' STRING_LITERAL
    | LANGUAGE STRING_LITERAL
    | LANGUAGE IDENTIFIER
    | IMMUTABLE
    | STABLE
    | VOLATILE
    | CALLED_ON_NULL_INPUT
    | RETURNS_NULL_ON_NULL_INPUT
    | SECURITY_INVOKER
    | SECURITY_DEFINER
;

aggOptionList:
      aggOptionList ',' aggOption {
        if ($1 == NULL)
            $$ = $3;
        else if ($3 == NULL)
            $$ = $1;
        else if ($1->tag == token::FINALFUNC)
            $$ = $1;
        else
            $$ = $3;
    }
    | aggOption
;

aggOption:
      aggFunc '=' qualifiedIdent {
        $$ = new TaggedStr($1, driver->fnToReturnType[$3]);
    }
    | STYPE '=' type { $$ = new TaggedStr(token::STYPE, $3); }
    | INITCOND '=' expr { $$ = NULL; }
    /* FIXME: SORTOP not yet supported at this point */
;

aggFunc:
      SFUNC
    | PREFUNC
    | FINALFUNC
;

expr:
      INTEGER_LITERAL
    | FLOAT_LITERAL
    | STRING_LITERAL
    | IDENTIFIER
    | NULL_KEYWORD
    | prefixExpr
    /* FIXME: Support more or ignore completely */
;

prefixExpr:
      '+' expr {
        asprintf(&($$), "+%s", $2);
    }
    | '-' expr {
        asprintf(&($$), "-%s", $2);
    }
;

%%

namespace bison{

SQLDriver::SQLDriver(const std::string &inExeName,
    const std::string &inFilename)
    :   exeName(inExeName), filename(inFilename) { }

SQLDriver::~SQLDriver() { }

void SQLDriver::error(const SQLParser::location_type &l, const std::string &m) {
    std::cerr << exeName << ":" << l << ": " << m << std::endl;
}

void SQLDriver::error(const std::string &m) {
    std::cerr << m << std::endl;
}

SQLDriver::CountingOStream::CountingOStream() : currentLine(1) {
}

SQLDriver::CountingOStream &SQLDriver::CountingOStream::advance(int line) {
    while (currentLine < line) {
        std::cout.put('\n');
        currentLine++;
    }
    return *this;
}

SQLDriver::CountingOStream &SQLDriver::CountingOStream::operator<<(
    const char *str) {

    for (int i = 0; str[i] != 0; i++)
        if (str[i] == '\n')
            currentLine++;

    std::cout << str;
    return *this;
}

SQLDriver::CountingOStream &SQLDriver::CountingOStream::operator<<(char c) {
    if (c == '\n') currentLine++;
    std::cout.put(c);
    return *this;
}


void SQLParser::error(const SQLParser::location_type &l,
    const std::string &m) {

    driver->error(l, m);
}

} // namespace bison

/* This implementation of SQLFlexLexer::yylex() is required because it is
 * declared in FlexLexer.h. The scanner's "real" yylex function is generated by
 * flex and "connected" via YY_DECL. */
#ifdef yylex
    #undef yylex
#endif
int SQLFlexLexer::yylex()
{
    std::cerr <<
        "Error: SQLFlexLexer::yylex() was called. Use SQLScanner::lex() instead"
        << std::endl;
    return 0;
}

int    main(int argc, char **argv)
{
    std::istream        *inStream = NULL;
    std::string         filename = "<stdin>";
    bool                error = false;
    bool                customFileName = false;

    for (int i = 1; i < argc; i++) {
        if (std::strcmp(argv[1], "-f") == 0) {
            if (i < argc - 1) {
                filename = argv[++i];
                customFileName = true;
            } else {
                error = true;
                break;
            }
        } else if (inStream == NULL) {
            inStream = new std::ifstream(argv[i]);
            if (!customFileName)
                filename = argv[i];
        }
    }
    if (error) {
        std::cerr << "Usage: " << argv[0] << " [-f customFileName] [inputFile]"
            << std::endl;
        return 1;
    }

    bison::SQLDriver    driver(argv[0], filename);
    bison::SQLScanner    scanner(inStream); driver.scanner = &scanner;
    bison::SQLParser    parser(&driver);

    int result = parser.parse();

    if (inStream != NULL)
        delete inStream;

    if (result != 0)
        return result;

    std::cout << '\n';

    /*
    std::cout << "// List of functions:\n";
    for (std::map<std::string,char *>::iterator it = driver.fnToReturnType.begin();
        it != driver.fnToReturnType.end(); it++)
        std::cout << "// " << (*it).first << ": return type " << (*it).second << std::endl;
    */
    return 0;
}
