1
0
mirror of https://github.com/aportelli/LatAnalyze.git synced 2024-09-20 05:25:37 +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 ////////////////////////////////////////////////////////////////////// // access //////////////////////////////////////////////////////////////////////
string File::getName(void) const const string & File::getName(void) const
{ {
return name_; return name_;
} }
@ -116,10 +116,24 @@ void AsciiFile::save(const DMat &m, const std::string &name)
isParsed_ = false; isParsed_ = false;
fileStream_ << "#L latan_begin mat " << name << endl; fileStream_ << "#L latan_begin mat " << name << endl;
fileStream_ << m.cols() << endl; fileStream_ << m.cols() << endl;
fileStream_ << m << endl; fileStream_ << scientific << m << defaultfloat << endl;
fileStream_ << "#L latan_end mat " << 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) void AsciiFile::save(const RandGen::State &state, const std::string &name)
{ {
checkWritability(); 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 ((mode_ & Mode::read)&&(isOpen()))
{ {
if (!isParsed_) if (!isParsed_)
{ {
state_->isFirst = true;
parse(); parse();
} }
if (name.empty())
{
return state_->first;
}
else
{
return name;
}
} }
else else
{ {
@ -210,7 +233,7 @@ void AsciiFile::load(const string &name __dumb)
// parser ////////////////////////////////////////////////////////////////////// // parser //////////////////////////////////////////////////////////////////////
// Bison/Flex parser declaration //// Bison/Flex parser declaration
int _ioAscii_parse(AsciiFile::AsciiParserState *state); int _ioAscii_parse(AsciiFile::AsciiParserState *state);
void AsciiFile::parse() void AsciiFile::parse()

View File

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

View File

@ -69,12 +69,13 @@ BLANK [ \t]
%% %%
{LMARK} {BEGIN(MARK);} {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);} {FLOAT} {yylval->val_double = strTo<double>(yytext); RETTOK(FLOAT);}
({ALPHA}|{DIGIT})+ {strcpy(yylval->val_str,yytext); RETTOK(ID);} ({ALPHA}|{DIGIT})+ {strcpy(yylval->val_str,yytext); RETTOK(ID);}
<MARK>latan_begin {BEGIN(TYPE); RETTOK(OPEN);} <MARK>latan_begin {BEGIN(TYPE); RETTOK(OPEN);}
<MARK>latan_end {BEGIN(TYPE); RETTOK(CLOSE);} <MARK>latan_end {BEGIN(TYPE); RETTOK(CLOSE);}
<TYPE>mat {BEGIN(INITIAL); RETTOK(MAT);} <TYPE>mat {BEGIN(INITIAL); RETTOK(MAT);}
<TYPE>rs_sample {BEGIN(INITIAL); RETTOK(SAMPLE);}
<TYPE>rg_state {BEGIN(INITIAL); RETTOK(RG_STATE);} <TYPE>rg_state {BEGIN(INITIAL); RETTOK(RG_STATE);}
<*>\n {yylloc->last_column = 0;} <*>\n {yylloc->last_column = 0;}
<*>[ \t] <*>[ \t]

View File

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