/* * IoAsciiParser.ypp, part of LatAnalyze 3 * * Copyright (C) 2013 - 2014 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 . */ %{ #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace Latan; #define STORE(ref) (*state->data)[(ref).first] = std::move((ref).second) %} %pure-parser %name-prefix="_ioAscii_" %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 ERR %token FLOAT %token INT %token ID %token OPEN CLOSE MAT RG_STATE %type mat rg_state %{ int _ioAscii_lex(YYSTYPE* lvalp, YYLTYPE* llocp, void* scanner); void _ioAscii_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 {(*state->data)[$1].reset(new DMat(state->dMatBuf));} | rg_state {(*state->data)[$1].reset(new RandGen::State(state->stateBuf));} ; mat: OPEN MAT ID INT floats CLOSE MAT { const int nRow = state->doubleStack.size()/$INT, nCol = $INT; int r, i, j; r = 0; state->dMatBuf.resize(nRow, nCol); while (!state->doubleStack.empty()) { j = r % nCol; i = (r - j)/nCol; state->dMatBuf(i, j) = state->doubleStack.top(); state->doubleStack.pop(); ++r; } if (r != nRow*nCol) { LATAN_ERROR(Range, "matrix '" + *state->streamName + ":" + $ID + "' has a wrong size"); } strcpy($$, $ID); } ; rg_state: OPEN RG_STATE ID ints CLOSE RG_STATE { for (int i = 0; i < RLXG_STATE_SIZE; ++i) { if (!state->intStack.empty()) { state->stateBuf[i] = state->intStack.top(); state->intStack.pop(); } else { LATAN_ERROR(Range, "random generator state '" + *state->streamName + ":" + $ID + "' is too short"); } } if (!state->intStack.empty()) { LATAN_ERROR(Range, "random generator state '" + *state->streamName + ":" + $ID + "' is too long"); } strcpy($$, $ID); } ; floats: FLOAT floats {state->doubleStack.push($1);} | INT floats {state->doubleStack.push(static_cast($1));} | FLOAT {state->doubleStack.push($1);} | INT {state->doubleStack.push(static_cast($1));} ; ints: INT ints {state->intStack.push($1);} | INT {state->intStack.push($1);} ;