1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
|
#ifndef INCLUDED_PARSER_
#define INCLUDED_PARSER_
#include <iostream>
#include <unordered_map>
#include <string>
#include <vector>
#include <sstream>
#include "../extractable/extractable.h"
//#include "../unsignedcastable/unsignedcastable.h"
#include "../typedefs/typedefs.h"
#include "../err/err.h"
#include "../globals/globals.h"
#include "../vsd/vsd.h"
class ConfigLines;
struct Parser
{
struct OptionInfo
{
std::string name;
std::string value;
uint16_t lineNr;
};
using OptionsVect = std::vector<OptionInfo>;
private:
using Map = std::unordered_map<std::string, Parser * >;
// each element holds the specs
LineInfoVect d_lines; // of one series of keywords
Map d_map;
static Map s_map;
public:
class Lines
{
friend class Parser;
unsigned d_size; // initial size
LineInfoVect::const_iterator d_iter; // first and last elements
LineInfoVect::const_iterator d_end; // of a selected vector
public:
// by repeated calls get all lines,
// from the first to the last until
// 0 is returned
LineInfo const *get(); // linesget.cc
unsigned size() const;
operator bool() const; // size() != 0
private:
// no lines found
Lines(LineInfoVect const &lines); // lineslines1.cc
// >= 1 line found
// lineslines2.cc
Lines(LineInfoVect::const_iterator const &begin,
LineInfoVect::const_iterator const &end);
Lines(Lines const &other) = default;
LineInfoVect::const_iterator begin() const; // .ih
LineInfoVect::const_iterator end() const; // .ih
};
using MapValue = Map::value_type;
Parser(); // 1.
Parser(Map &&tmp); // 2.
~Parser();
// any number (>= 1) lines is OK
static Lines any(StringVect const &keywords);
// extract 'dest' variables from lines.get()->tail
// returns 'good' if ok, else if no lines then
// eof() else fail() + error msg
template <Extractable ...Types> // .f
static std::istringstream extract(Lines &&ines,
Types &...dest);
// same as 1.f, but LineInfo is already available
// extracts from line.tail
template <Extractable ...Types> // .f
static std::istringstream extract(LineInfo const &line,
Types &...dest);
// extract 'size' 'dest' elements from lines.get()->tail
// return values as with extract1.f
template <Extractable Type> // .f
static std::istringstream extract(Lines &&lines, Type *dest,
size_t size);
// extract 'dest' values from one configuration line at 'keywords'
template <Extractable ...Types> // .f
static std::istringstream extract(StringVect const &keywords,
Types &...dest);
static bool hasSection(StringVect const &keywords);
// analysis file
void load(std::istream &in, uint16_t startLineNr, // 1.
StringVect &labels,
OptionsVect &options);
void load(std::string const &fname); // configuration file 2.
// requires specs like Survival:
// type: a .00004475 .000004392 Normal
// type: b 1.85867 .0420 Normal
static VSDvect VSDparameters( // 1.cc
VaryType varyType, StringVect const &keywords,
std::initializer_list<char> const &required);
// exactly 1 configuration line is required
static Lines one(StringVect const &keywords);
// requires one line specs like Mammo:
// m: .136 .136 .136 .136
static VSDvect VSDparameters( // 2.cc
VaryType varyType, StringVect const &keywords,
size_t nRequired);
// exactly 1 line is required. // .f
static bool nonNegative(StringVect const &keywords, double &dest);
template <std::integral Type> // .f
static bool nonNegative(StringVect const &keywords, Type &dest);
// extract exactly one value associated with keywords
template <Extractable Type> // .f
static bool one(StringVect const &keywords, Type &dest);
static bool positive(StringVect const &keywords, double &dest); // .f
// exactly 1 line is required
static bool proportion(StringVect const &keywords, double &dest);
private:
// add the next parser line to the
// appropriate map-section
static void addConfigLine(std::vector<Map *> &mapPtrVect,
ConfigLines &lines, ParamsSrc src);
static bool atLeast(double minimum,
StringVect const &keywords, double &dest);
static std::string checkRedo(ConfigLines &configLine);
// deepest nesting level in the map
static bool endPoint(Map::value_type const &mapValue);
template <Extractable Type, Extractable ...Types> // .f
static bool extract(std::istream &in, Type &first, Types &...more);
static bool extract(std::istream &in); // .f
// define d_lines[0]
// at s_map's deepest
static void initLineInfoVects(Map &map); // nesting levels
static LineInfoVect const &keywordsLines(StringVect const &keywords);
static Lines lines(StringVect const &keywords); // 1.
static void locateError(std::vector<Map *> &mapPtrVect,
ConfigLines &lines, ParamsSrc src);
static std::string sectionList(StringVect const &keywords);
static void setLabels(ConfigLines &parser, StringVect &labels);
static void setOptions(ConfigLines &parser, OptionsVect &options);
static void rmLineInfoVectors(Map &map);
};
#include "parser.f"
#endif
|