1
0
mirror of https://github.com/aportelli/LatAnalyze.git synced 2024-09-19 21:25:36 +01:00

IO: more improvements and Sample implementation

This commit is contained in:
Antonin Portelli 2014-02-17 18:46:55 +00:00
parent 0b2aee8704
commit 34b3b36de4
4 changed files with 132 additions and 60 deletions

View File

@ -46,7 +46,7 @@ File::~File(void)
}
// access //////////////////////////////////////////////////////////////////////
string File::getName(void) const
const string & File::getName(void) const
{
return name_;
}
@ -116,10 +116,24 @@ void AsciiFile::save(const DMat &m, const std::string &name)
isParsed_ = false;
fileStream_ << "#L latan_begin mat " << name << endl;
fileStream_ << m.cols() << endl;
fileStream_ << m << endl;
fileStream_ << scientific << m << defaultfloat << endl;
fileStream_ << "#L latan_end mat " << endl;
}
void AsciiFile::save(const DMatSample &s, const std::string &name)
{
checkWritability();
isParsed_ = false;
fileStream_ << "#L latan_begin rs_sample " << name << endl;
fileStream_ << s.size() << endl;
save(s[central], name + "_C");
for (int i = 0; i < static_cast<int>(s.size()); ++i)
{
save(s[i], name + "_S_" + strFrom(i));
}
fileStream_ << "#L latan_end rs_sample " << endl;
}
void AsciiFile::save(const RandGen::State &state, const std::string &name)
{
checkWritability();
@ -186,14 +200,23 @@ void AsciiFile::open(const string &name, const unsigned int mode)
}
}
void AsciiFile::load(const string &name __dumb)
std::string AsciiFile::load(const string &name)
{
if ((mode_ & Mode::read)&&(isOpen()))
{
if (!isParsed_)
{
state_->isFirst = true;
parse();
}
if (name.empty())
{
return state_->first;
}
else
{
return name;
}
}
else
{
@ -210,7 +233,7 @@ void AsciiFile::load(const string &name __dumb)
// parser //////////////////////////////////////////////////////////////////////
// Bison/Flex parser declaration
//// Bison/Flex parser declaration
int _ioAscii_parse(AsciiFile::AsciiParserState *state);
void AsciiFile::parse()

View File

@ -22,7 +22,7 @@
#include <fstream>
#include <memory>
#include <stack>
#include <queue>
#include <sstream>
#include <string>
#include <unordered_map>
@ -61,11 +61,12 @@ public:
// destructor
virtual ~File(void);
// access
std::string getName(void) const;
unsigned int getMode(void) const;
const std::string & getName(void) const;
unsigned int getMode(void) const;
template <typename IoT>
const IoT & read(const std::string &name);
const IoT & read(const std::string &name = "");
virtual void save(const DMat &m, const std::string &name) = 0;
virtual void save(const DMatSample &state, const std::string &name) = 0;
virtual void save(const RandGen::State &state, const std::string &name) = 0;
// tests
virtual bool isOpen(void) const = 0;
@ -73,14 +74,19 @@ public:
virtual void close(void) = 0;
virtual void open(const std::string &name, const unsigned int mode) = 0;
protected:
// access
void setName(const std::string &name);
void setMode(const unsigned int mode);
// data access
void deleteData(void);
template <typename IoT>
const IoT& getData(const std::string &name) const;
// IO
virtual void load(const std::string &name) = 0;
void deleteData(void);
// error checking
void checkWritability(void);
private:
// data access
template <typename IoT>
const IoT& getData(const std::string &name = "") const;
// IO
virtual std::string load(const std::string &name = "") = 0;
protected:
std::string name_;
unsigned int mode_;
@ -91,9 +97,11 @@ protected:
template <typename IoT>
const IoT& File::read(const std::string &name)
{
load(name);
std::string dataName;
return getData<IoT>(name);
dataName = load(name);
return getData<IoT>(dataName);
}
template <typename IoT>
@ -105,7 +113,8 @@ const IoT& File::getData(const std::string &name) const
}
catch(std::out_of_range)
{
LATAN_ERROR(Definition, "no data with name '" + name + "'");
LATAN_ERROR(Definition, "no data with name '" + name + "' in file "
+ name_);
}
}
@ -123,12 +132,15 @@ public:
IoDataTable *data);
// destructor
virtual ~AsciiParserState(void);
// first element reference
bool isFirst;
std::string first;
// parsing buffers
DMat dMatBuf;
RandGen::State stateBuf;
std::stack<DMat> dMatStack;
std::stack<double> doubleStack;
std::stack<int> intStack;
DMatSample dMatSampleBuf;
std::queue<DMat> dMatQueue;
std::queue<double> doubleQueue;
std::queue<int> intQueue;
private:
// allocation/deallocation functions defined in IoAsciiLexer.lpp
virtual void initScanner(void);
@ -142,6 +154,7 @@ public:
virtual ~AsciiFile(void);
// access
virtual void save(const DMat &m, const std::string &name);
virtual void save(const DMatSample &s, const std::string &name);
virtual void save(const RandGen::State &state, const std::string &name);
// tests
virtual bool isOpen(void) const;
@ -150,7 +163,7 @@ public:
virtual void open(const std::string &name, const unsigned int mode);
private:
// IO
virtual void load(const std::string &name);
virtual std::string load(const std::string &name = "");
// parser
void parse(void);
private:

View File

@ -69,12 +69,13 @@ BLANK [ \t]
%%
{LMARK} {BEGIN(MARK);}
{INT} {yylval->val_int = strTo<int>(yytext); RETTOK(INT);}
{INT} {yylval->val_int = strTo<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);}
<*>\n {yylloc->last_column = 0;}
<*>[ \t]

View File

@ -32,7 +32,12 @@
using namespace std;
using namespace Latan;
#define STORE(ref) (*state->data)[(ref).first] = std::move((ref).second)
#define TEST_FIRST(name) \
if (state->isFirst)\
{\
state->first = (name);\
state->isFirst = false;\
}
%}
%pure-parser
@ -56,9 +61,9 @@
%token <val_double> FLOAT
%token <val_int> INT
%token <val_str> ID
%token OPEN CLOSE MAT RG_STATE
%token OPEN CLOSE MAT SAMPLE RG_STATE
%type <val_str> mat rg_state
%type <val_str> mat sample rg_state
%{
int _ioAscii_lex(YYSTYPE* lvalp, YYLTYPE* llocp, void* scanner);
@ -85,69 +90,99 @@ datas:
data:
mat
{(*state->data)[$1].reset(new DMat(state->dMatBuf));}
{
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
{(*state->data)[$1].reset(new RandGen::State(state->stateBuf));}
{
TEST_FIRST($1);
(*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;
const unsigned int nRow = state->doubleQueue.size()/$INT, nCol = $INT;
int i, j, r = 0;
r = 0;
state->dMatBuf.resize(nRow, nCol);
while (!state->doubleStack.empty())
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->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");
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 + 1;
if (state->dMatQueue.size() != nSample)
{
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
{
for (int i = 0; i < RLXG_STATE_SIZE; ++i)
if (state->intQueue.size() != RLXG_STATE_SIZE)
{
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");
}
LATAN_ERROR(Size, "random generator state '" + *state->streamName
+ ":" + $ID + "' has a wrong size");
}
if (!state->intStack.empty())
for (unsigned int i = 0; i < RLXG_STATE_SIZE; ++i)
{
LATAN_ERROR(Range, "random generator state '" +
*state->streamName + ":" + $ID + "' is too long");
state->stateBuf[i] = state->intQueue.front();
state->intQueue.pop();
}
strcpy($$, $ID);
}
;
mats:
mats mat
| mat
;
floats:
FLOAT floats {state->doubleStack.push($1);}
| INT floats {state->doubleStack.push(static_cast<double>($1));}
| FLOAT {state->doubleStack.push($1);}
| INT {state->doubleStack.push(static_cast<double>($1));}
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:
INT ints {state->intStack.push($1);}
| INT {state->intStack.push($1);}
ints INT {state->intQueue.push($INT);}
| INT {state->intQueue.push($INT);}
;