#pragma once

// Flex expects the signature of yylex to be defined in the macro YY_DECL, and
// the C++ parser expects it to be declared. We can factor both as follows.

#ifndef YY_DECL

#define YY_DECL                        \
    int NCssConfig::TConfigLexer::Lex( \
        YYSTYPE* yylval)
#endif

#ifndef __FLEX_LEXER_H
#define yyFlexLexer configFlexLexer
#include <contrib/tools/flex-old/FlexLexer.h>
#undef yyFlexLexer
#endif

#include <util/generic/utility.h>
#include <util/stream/output.h>

namespace NCssConfig {
#include "config_y.h"

    /** Scanner is a derived class to add some extra function to the scanner
 * class. Flex itself creates a class named yyFlexLexer, which is renamed using
 * macros to configFlexLexer. However we change the context of the generated
 * yylex() function to be contained within the Scanner class. This is required
 * because the yylex() defined in CSSFlexLexer has no parameters. */
    class TConfigLexer: public configFlexLexer {
        IInputStream& Inps;

    public:
        /** Create a new scanner object. The streams arg_yyin and arg_yyout default
     * to cin and cout, but that assignment is only made when initializing in
     * yylex(). */
        TConfigLexer(IInputStream& inps);

        /** Required for virtual functions */
        ~TConfigLexer() override;

        int LexerInput(char* buf, int max_size) override;
        /** This is the main lexing function. It is generated by flex according to
     * the macro declaration YY_DECL above. The generated bison parser then
     * calls this virtual function to fetch new tokens. */
        virtual int Lex(YYSTYPE* yylval);

        /** Enable debug output (via arg_yyout) if compiled into the scanner. */
        void SetDebug(bool b);
    };
}
