1
0
mirror of https://github.com/aportelli/LatAnalyze.git synced 2024-09-20 05:25:37 +01:00
LatAnalyze/lib/AsciiParser.ypp

196 lines
5.0 KiB
Plaintext
Raw Normal View History

2014-02-20 23:52:45 +00:00
/*
2014-03-12 19:54:27 +00:00
* AsciiParser.ypp, part of LatAnalyze 3
2014-02-20 23:52:45 +00:00
*
2015-06-11 14:04:54 +01:00
* Copyright (C) 2013 - 2015 Antonin Portelli
2014-02-20 23:52:45 +00:00
*
* 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/>.
*/
%{
2014-03-13 18:51:01 +00:00
#include <LatAnalyze/Global.hpp>
#include <LatAnalyze/AsciiFile.hpp>
#include <LatAnalyze/Mat.hpp>
#include <LatAnalyze/MatSample.hpp>
#include <LatAnalyze/RandGen.hpp>
2014-03-03 14:21:37 +00:00
#include <iostream>
#include <sstream>
#include <utility>
#include <cstring>
2014-02-20 23:52:45 +00:00
2015-05-23 14:44:43 +01:00
#if (defined __INTEL_COMPILER)
#pragma warning disable 1682 2259
#elif (defined __GNUC__)||(defined __clang__)
2015-02-24 16:59:22 +00:00
#pragma GCC diagnostic ignored "-Wshorten-64-to-32"
#pragma GCC diagnostic ignored "-Wconversion"
#pragma GCC diagnostic ignored "-Wsign-conversion"
2015-05-23 14:44:43 +01:00
#endif
2015-02-24 16:59:22 +00:00
2014-02-20 23:52:45 +00:00
using namespace std;
using namespace Latan;
#define TEST_FIRST(name) \
if (state->isFirst)\
{\
state->first = (name);\
state->isFirst = false;\
}
%}
%pure-parser
2015-02-24 16:59:22 +00:00
%name-prefix "_Ascii_"
2014-02-20 23:52:45 +00:00
%locations
%defines
%error-verbose
%parse-param { Latan::AsciiFile::AsciiParserState* state }
%initial-action {yylloc.last_column = 0;}
%lex-param { void* scanner }
%union
{
int val_int;
double val_double;
char val_char;
char val_str[256];
}
%token <val_char> ERR
%token <val_double> FLOAT
%token <val_int> INT
%token <val_str> ID
%token OPEN CLOSE MAT SAMPLE RG_STATE
%type <val_str> mat sample rg_state
%{
int _Ascii_lex(YYSTYPE* lvalp, YYLTYPE* llocp, void* scanner);
void _Ascii_error(YYLTYPE* locp, AsciiFile::AsciiParserState* state,
const char* err)
{
stringstream buf;
buf << *state->streamName << ":" << locp->first_line << ":"\
<< locp->first_column << ": " << err;
LATAN_ERROR(Parsing, buf.str());
}
#define scanner state->scanner
%}
%%
datas:
/* empty string */
| datas data
;
data:
mat
{
TEST_FIRST($1);
(*state->data)[$1].reset(new DMat(state->dMatQueue.front()));
state->dMatQueue.pop();
}
| sample
{
TEST_FIRST($1);
(*state->data)[$1].reset(new DMatSample(state->dMatSampleBuf));
}
| rg_state
{
TEST_FIRST($1);
(*state->data)[$1].reset(new RandGenState(state->stateBuf));
}
;
mat:
OPEN MAT ID INT floats CLOSE MAT
{
const unsigned int nRow = state->doubleQueue.size()/$INT, nCol = $INT;
Index i, j, r = 0;
2014-02-20 23:52:45 +00:00
if (state->doubleQueue.size() != nRow*nCol)
{
LATAN_ERROR(Size, "matrix '" + *state->streamName + ":" + $ID +
"' has a wrong size");
}
state->dMatQueue.push(DMat(nRow, nCol));
while (!state->doubleQueue.empty())
{
j = r % nCol;
i = (r - j)/nCol;
state->dMatQueue.back()(i, j) = state->doubleQueue.front();
state->doubleQueue.pop();
r++;
}
strcpy($$, $ID);
}
;
sample:
OPEN SAMPLE ID INT mats CLOSE SAMPLE
{
const unsigned int nSample = $INT;
2014-02-20 23:52:45 +00:00
if (state->dMatQueue.size() != nSample + DMatSample::offset)
2014-02-20 23:52:45 +00:00
{
LATAN_ERROR(Size, "sample '" + *state->streamName + ":" + $ID +
"' has a wrong size");
}
state->dMatSampleBuf.resize(nSample);
state->dMatSampleBuf[central] = state->dMatQueue.front();
state->dMatQueue.pop();
for (int i = 0; i < $INT; ++i)
{
state->dMatSampleBuf[i] = state->dMatQueue.front();
state->dMatQueue.pop();
}
strcpy($$, $ID);
}
rg_state:
OPEN RG_STATE ID ints CLOSE RG_STATE
{
if (state->intQueue.size() != RLXG_STATE_SIZE)
{
LATAN_ERROR(Size, "random generator state '" + *state->streamName
+ ":" + $ID + "' has a wrong size");
}
for (Index i = 0; i < RLXG_STATE_SIZE; ++i)
2014-02-20 23:52:45 +00:00
{
state->stateBuf[i] = state->intQueue.front();
state->intQueue.pop();
}
strcpy($$, $ID);
}
;
mats:
mats mat
| mat
;
floats:
floats FLOAT {state->doubleQueue.push($FLOAT);}
| floats INT {state->doubleQueue.push(static_cast<double>($INT));}
| FLOAT {state->doubleQueue.push($FLOAT);}
| INT {state->doubleQueue.push(static_cast<double>($INT));}
;
ints:
ints INT {state->intQueue.push($INT);}
| INT {state->intQueue.push($INT);}
;