/*
 * AsciiLexer.lpp, part of LatAnalyze 3
 *
 * Copyright (C) 2013 - 2020 Antonin Portelli
 *
 * LatAnalyze 3 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 3 of the License, or
 * (at your option) any later version.
 *
 * LatAnalyze 3 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 LatAnalyze 3.  If not, see <http://www.gnu.org/licenses/>.
 */

%option reentrant
%option prefix="_Ascii_"
%option bison-bridge
%option bison-locations
%option noyywrap
%option yylineno

%{
	#include <LatAnalyze/Io/AsciiFile.hpp>
	#include "AsciiParser.hpp"
    
    using namespace std;
    using namespace Latan;
    
	#define YY_EXTRA_TYPE  AsciiFile::AsciiParserState*
	#define YY_USER_ACTION \
    yylloc->first_line   = yylloc->last_line = yylineno;\
    yylloc->first_column = yylloc->last_column + 1;\
    yylloc->last_column  = yylloc->first_column + yyleng - 1;

	#define YY_INPUT(buf, result, max_size) \
	{ \
        (*yyextra->stream).read(buf,max_size);\
        result = (*yyextra->stream).gcount();\
	}
    
    #define YY_DEBUG 0
    #if (YY_DEBUG == 1)
    #define RETTOK(tok) cout << #tok << "(" << yytext << ")" << endl; return tok
    #else
    #define RETTOK(tok) return tok
    #endif
%}

DIGIT   [0-9]
ALPHA   [a-zA-Z_+./-]
SIGN    \+|-
EXP     e|E
INT     {SIGN}?{DIGIT}+
FLOAT   {SIGN}?(({DIGIT}+\.{DIGIT}*)|({DIGIT}*\.{DIGIT}+))({EXP}{SIGN}?{INT}+)?
LMARK   #L
BLANK   [ \t]

%x MARK TYPE

%%

{LMARK}            {BEGIN(MARK);}
{INT}              {yylval->val_int    = strTo<long int>(yytext); RETTOK(INT);}
{FLOAT}            {yylval->val_double = strTo<double>(yytext); RETTOK(FLOAT);}
({ALPHA}|{DIGIT})+ {strcpy(yylval->val_str,yytext); RETTOK(ID);}
<MARK>latan_begin  {BEGIN(TYPE); RETTOK(OPEN);}
<MARK>latan_end    {BEGIN(TYPE); RETTOK(CLOSE);}
<TYPE>mat          {BEGIN(INITIAL); RETTOK(MAT);}
<TYPE>rs_sample    {BEGIN(INITIAL); RETTOK(SAMPLE);}
<TYPE>rg_state     {BEGIN(INITIAL); RETTOK(RG_STATE);}
<*>\r*\n           {yylloc->last_column = 0;}
<*>[ \t]
<*>.               {yylval->val_char = yytext[0]; RETTOK(ERR);}

%%

void AsciiFile::AsciiParserState::initScanner()
{
	yylex_init(&scanner);
	yyset_extra(this, scanner);
}

void AsciiFile::AsciiParserState::destroyScanner()
{
	yylex_destroy(scanner);
}
