/* Copyright (C) 2003 MySQL AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

#ifndef ODBC_CODEGEN_SimpleParser_hpp
#define ODBC_CODEGEN_SimpleParser_hpp

#include <common/common.hpp>
#include "Code_root.hpp"
#include "Code_stmt.hpp"
#include "Code_select.hpp"
#include "Code_pred.hpp"
#include "Code_pred_op.hpp"
#include "Code_comp_op.hpp"
#include "Code_expr_row.hpp"
#include "Code_expr.hpp"
#include "Code_expr_op.hpp"
#include "Code_expr_func.hpp"
#include "Code_expr_column.hpp"
#include "Code_expr_const.hpp"
#include "Code_expr_param.hpp"
#include "Code_update.hpp"
#include "Code_set_row.hpp"
#include "Code_insert.hpp"
#include "Code_dml_row.hpp"
#include "Code_dml_column.hpp"
#include "Code_delete.hpp"
#include "Code_table_list.hpp"
#include "Code_table.hpp"
#include "Code_create_table.hpp"
#include "Code_create_index.hpp"
#include "Code_ddl_row.hpp"
#include "Code_ddl_column.hpp"
#include "Code_ddl_constr.hpp"
#include "Code_data_type.hpp"
#include "Code_drop_table.hpp"
#include "Code_drop_index.hpp"

#include "SimpleGram.tab.hpp"

class StmtArea;
class Plan_root;

class SimpleParser : public yyFlexLexer {
public:
    SimpleParser(Ctx& ctx, StmtArea& stmtArea, Plan_root* root);
    ~SimpleParser();
    Ctx& ctx();
    StmtArea& stmtArea();
    Plan_root* root();
    void yyparse();		// calls real yyparse
    int yylex();		// generated by flex
    YYSTYPE yylval();
    void pushState(int sc);	// push start condition
    void popState();		// pop start condition
    unsigned paramNumber() const;
    void parseError(const char* msg);
    // parser helpers - to avoid creating new Plan tree types
    Plan_ddl_column* curr(Plan_ddl_column* p);
    Plan_create_index* curr(Plan_create_index* p);
protected:
    virtual int LexerInput(char* buf, int max_size);
    virtual void LexerOutput(const char* buf, int size);
    virtual void LexerError(const char* msg);
private:
    Ctx& m_ctx;
    StmtArea& m_stmtArea;
    Plan_root* const m_root;
    unsigned m_textPos;		// position in sql text
    unsigned m_parsePos;	// parse position, to report error
    YYSTYPE m_yylval;		// token value
    BaseString m_string;	// storage for edited string token
    unsigned m_stacksize;	// state stack size
    unsigned m_paramNumber;	// parameter number
    // parser helpers
    Plan_ddl_column* m_ddl_column;
    Plan_create_index* m_create_index;
};

extern int SimpleParser_yyparse(void* simpleParserPtr);
#if YYDEBUG
extern int SimpleParser_yydebug;
#endif

inline
SimpleParser::SimpleParser(Ctx& ctx, StmtArea& stmtArea, Plan_root* root) :
    m_ctx(ctx),
    m_stmtArea(stmtArea),
    m_root(root),
    m_textPos(0),
    m_parsePos(0),
    m_stacksize(0),
    m_paramNumber(0),
    // parser helpers
    m_ddl_column(0)
{
}

inline Ctx&
SimpleParser::ctx()
{
    return m_ctx;
}

inline StmtArea&
SimpleParser::stmtArea()
{
    return m_stmtArea;
}

inline Plan_root*
SimpleParser::root()
{
    return m_root;
}

inline YYSTYPE
SimpleParser::yylval()
{
    return m_yylval;
}

inline unsigned
SimpleParser::paramNumber() const
{
    return m_paramNumber;
}

// parser helpers

inline Plan_ddl_column*
SimpleParser::curr(Plan_ddl_column* p)
{
    if (p != 0)
	m_ddl_column = p;
    ctx_assert(m_ddl_column != 0);
    return m_ddl_column;
}

inline Plan_create_index*
SimpleParser::curr(Plan_create_index* p)
{
    if (p != 0)
	m_create_index = p;
    ctx_assert(m_create_index != 0);
    return m_create_index;
}

#endif
