/*
* File:        ElftosbLexer.h
*
* Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
* See included license file for license details.
*/

// This header just wraps the standard flex C++ header to make it easier to include
// without having to worry about redefinitions of the class name every time.

#if !defined(_ElftosbLexer_h_)
#define _ElftosbLexer_h_

#include "ElftosbAST.h"
#include "FlexLexer.h"
#include "elftosb_parser.tab.hpp"
#include <vector>
#include <string>
#include <stdexcept>
#include "Blob.h"

using namespace std;

namespace elftosb
{

/*!
* \brief Exception class for syntax errors.
*/
class syntax_error : public std::runtime_error
{
public:
       explicit syntax_error(const std::string & __arg) : std::runtime_error(__arg) {}
};

/*!
* \brief Exception class for lexical errors.
*/
class lexical_error : public std::runtime_error
{
public:
       explicit lexical_error(const std::string & __arg) : std::runtime_error(__arg) {}
};

/*!
* \brief Lexical scanner class for elftosb command files.
*
* This class is a subclass of the standard C++ lexer class produced by
* Flex. It's primary purpose is to provide a clean way to report values
* for symbols, without using the yylval global. This is necessary because
* the parser produced by Bison is a "pure" parser.
*
* In addition, this class manages a list of source names generated by
* parsing. The lexer uses this list to determine if an identifier is
* a source name or a constant identifier.
*/
class ElftosbLexer : public yyFlexLexer
{
public:
       //! \brief Constructor.
       ElftosbLexer(istream & inputStream);

       //! \brief Lexer interface. Returns one token.
       virtual int yylex();

       //! \brief Returns the value for the most recently produced token in \a value.
       virtual void getSymbolValue(YYSTYPE * value);

       //! \brief Returns the current token's location in \a loc.
       inline token_loc_t & getLocation() { return m_location; }

       //! \name Source names
       //@{
       void addSourceName(std::string * ident);
       bool isSourceName(std::string * ident);
       //@}

protected:
       YYSTYPE m_symbolValue;  //!< Value for the current token.
       int m_line;     //!< Current line number.
       token_loc_t m_location; //!< Location for the current token.
       Blob * m_blob;  //!< The binary object value as its being constructed.
       int m_blobFirstLine;    //!< Line number for the first character of a blob.

       typedef std::vector<std::string> string_vector_t;
       string_vector_t m_sources;      //!< Vector of source identifiers;

       //! \brief Throw an elftosb::lexical_error exception.
       virtual void LexerError(const char * msg);

       //! \brief Process a string containing escape sequences.
       int processStringEscapes(const char * in, char * out);
};

}; // namespace elftosb

#endif // _ElftosbLexer_h_