#include "ExpressionParser.h"
#include <iostream>
#include <string>
#include <vector>
#include <map>
const char delimiter = '\t';
unsigned int read_csvline(std::istream &instream,
std::vector<std::string> &columns)
{
columns.clear();
std::string line;
if (!std::getline(instream, line, '\n').good()) {
return 0;
}
columns.push_back("");
for (std::string::const_iterator si = line.begin();
si != line.end(); ++si)
{
if (*si == delimiter)
columns.push_back("");
else
columns.back() += *si;
}
return columns.size();
}
class CSVRowSymbolTable : public stx::BasicSymbolTable
{
public:
const std::map<std::string, unsigned int> &headersmap;
const std::vector<std::string> &datacolumns;
CSVRowSymbolTable(const std::map<std::string, unsigned int> &_headersmap,
const std::vector<std::string> &_datacolumns)
: stx::BasicSymbolTable(),
headersmap(_headersmap),
datacolumns(_datacolumns)
{
}
virtual stx::AnyScalar lookupVariable(const std::string &varname) const
{
std::map<std::string, unsigned int>::const_iterator
varfind = headersmap.find(varname);
if (varfind == headersmap.end()) {
return stx::BasicSymbolTable::lookupVariable(varname);
}
if(varfind->second < datacolumns.size())
{
return stx::AnyScalar().setAutoString( datacolumns[varfind->second] );
}
else
{
return "";
}
}
};
int main(int argc, char *argv[])
{
std::string args;
for(int i = 1; i < argc; i++) {
if (!args.empty()) args += " ";
args += argv[i];
}
std::cerr << "Expression string: " << args << "\n";
stx::ParseTree pt;
try
{
pt = stx::parseExpression(args);
std::cerr << "Parsed expression: " << pt.toString() << "\n";
}
catch (stx::ExpressionParserException &e)
{
std::cerr << "ExpressionParserException: " << e.what() << "\n";
return 0;
}
std::cerr << "Reading CSV column headers from input\n";
std::vector<std::string> headers;
if (read_csvline(std::cin, headers) == 0) {
std::cerr << "Error read column headers: no input\n";
return 0;
}
std::cerr << "Read " << headers.size() << " column headers.\n";
std::map<std::string, unsigned int> headersmap;
for(unsigned int headnum = 0; headnum < headers.size(); ++headnum)
{
headersmap[ headers[headnum] ] = headnum;
if (headnum != 0) std::cout << delimiter;
std::cout << headers[headnum];
}
std::cout << "\n";
unsigned int linesprocessed = 0, linesskipped = 0;
std::vector<std::string> datacolumns;
CSVRowSymbolTable csvsymboltable(headersmap, datacolumns);
while( read_csvline(std::cin, datacolumns) > 0 )
{
try
{
linesprocessed++;
stx::AnyScalar val = pt.evaluate( csvsymboltable );
if (val.isBooleanType())
{
if (!val.getBoolean()) {
linesskipped++;
continue;
}
}
else {
std::cerr << "evaluated: " << val << "\n";
}
for(std::vector<std::string>::const_iterator
coliter = datacolumns.begin();
coliter != datacolumns.end(); ++coliter)
{
if (coliter != datacolumns.begin()) std::cout << delimiter;
std::cout << *coliter;
}
std::cout << "\n";
}
catch (stx::UnknownSymbolException &e)
{
std::cerr << "evaluated: UnknownSymbolException: " << e.what() << "\n";
}
catch (stx::ExpressionParserException &e)
{
std::cerr << "evaluated: ExpressionParserException: " << e.what() << "\n";
}
}
std::cerr << "Processed " << linesprocessed << " lines, "
<< "copied " << (linesprocessed - linesskipped) << " and "
<< "skipped " << linesskipped << " lines" << "\n";
}