File: parser

package info (click to toggle)
simrisc 16.05.00-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 4,568 kB
  • sloc: cpp: 6,877; fortran: 665; makefile: 112; ansic: 112; sh: 107
file content (207 lines) | stat: -rw-r--r-- 6,742 bytes parent folder | download
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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
enum VaryType   (enums/enums.h)
{
    VARY_MEAN,      // every value is OK
    VARY_NONNEG,    // varied values must be >= 0
    VARY_PROB       // varied values must be probabilities
};

ParamsSrc
    CONFIGFILE,
    ANALYSIS,
    NONE,

LineInfo
    ParamsSrc   src;        With Analysis: specifications: ANALYSIS,
                            when read from the config file: CONFIGFILE,
                            initially: NONE, set by initLineInfoVect
    uint16_t    lineNr;
    std::string txt;
    std::string tail;       text beyond the keyword

Lines:
    LineInfo const *get();  repeated calls get all lines, until 0 is returned
    unsigned size() const;
    operator bool() const;  size != 0



using Map = std::unordered_map<std::string, Parser * >;
using MapValue = Map::value_type;

Parser objects have two data members:

        LineInfoVect d_lines,

whose elements will contain the specifications of a parameter of the
configuration file (e.g., the line 'spread: false' of the section Scenario:,
or the 'agegroup:' lines of the section BreastDensities:

        Map d_map;

initially empty, but containing


Map s_map is defined in data.cc containing MapValues. Initialized with
MapValues usually referring to other mapValue. E.g.,

Map         MapValues
s_map = {
            scenario,
            costs,
            breastDensities,
            modalities,
            screening,
            tumor,
        }

Consider the entry 'costs': it's a MapValue with key 'Costs:' and value an
allocated Parser, constructed by Parser(Map &&tmp):
MapValue costs =
        {
            "Costs:",
            new Parser
            {
                { <-- an anonymous Parser::Map
                    {"biop:",       new Parser },
                    {"diameters:",  new Parser },
                    cosDiscount,
                }
            }
        };

costs's Parser receives an anonymous Parser::Map having three values. The
first two are MapValues whose value elements point to Parsers constructed by
the Parser's default constructor, and 'cosDiscount' is a MapValue whose value
element points to a Parser constructed by the Parser(Map &&tmp) constructor,
moving tmp to its d_map data member.

    The MapValues contain a keyword (Like "Scenario:") as their first element and
    a Parser * as second element. The resulting structure is a tree, where the
    leaves are Parser objects, reached via the MapValues.second elements.

The Parser's default constructor is called by the Analysis constructor for
each new Analysis. Parser() passes s_map to initLineInfoVects, which visits
all elements of the received Map. If an element's value points to a Parser
containing a non-empty d_map then initLineInfoVects is called recursively,
recceiving the non-empty d_map as its argument. If its d_map is empty (as with
{"biop:",       new Parser }) then an endpoint is reached, and the Parser's
d_lines receives a LineInfo{ NONE } element:

s_map =
{
  ...,
  costs:
    {
      "Costs:",
      new Parser
      {
        {
          {"biop:",       new Parser },
          {"diameters:",  new Parser },
          cosDiscount:
            {
               "Discount:",
               new Parser
               {
                 {
                   {"age:",        new Parser },
                   {"proportion:", new Parser },
                 }
               }
            }
        }
      }
    };
  ...,
  ...,
  ...,
  ...,
}

initLineInfoVects receives s_map, inspects costs:
    costs' parser has a non-empty d_map ->
        initLineInfoVects receives cost's parser's d_map:
          * inspects
                {"biop:", new Parser }, this parser has an empty d_map ->
                    the parser's d_lines receives a LineInfo{ NONE }
          * inspects
                {"diameter:", new Parser }, this parser has an empty d_map ->
                    the parser's d_lines receives a LineInfo{ NONE }
          * inspects
                cosDiscount: this parser has a non-empty d_map ->
                    initLineInfoVects receives  cosDiscount's parser's d_map:
                      * inspects (etc)

Once initLineInfoVects has completed, the Parsers at the deepest nesting level
have d_lines members having one element, with ParamSrc NONE.

When load1 and load2 read the actual configuration files these elements are
replaced by ParamSrc ANALYSIS elements (or by ParamSrc CONFIGFILE elements if
there's no ANALYSIS element) (-> addConfigLine)



------------------------------------------------------------------------------------

The following Parser members are all static
===========================================

any:
    Lines any(StringVect const &keywords);
        return any number (>= 1) of lines in Lines

extract:
    istringstream extract(Lines &&ines, Types &...dest)
        extract 'dest' variables from lines.get()->tail
        returns 'good' if ok, else if no lines then  eof() else fail() + error
        msg

    istringstream extract(LineInfo const &line, Types &...dest)
        same, extracting from available LineInfo:

    istringstream extract(Lines &&lines, Type *dest, size_t size)
        extract 'size' 'dest' elements from lines.get()->tail

    istringstream extract(StringVect const &keywords, Types &...dest)
        extract 'dest' variables from one configuration line at 'keywords'

hasSection:
    bool hasSection(StringVect const &keywords);

nonNegative:
    bool nonNegative(StringVect const &keywords, Type &dest)
        extracts dest (double or integral, >= 0) from exactly 1
        configuration line


one:
    Lines one(StringVect const &keywords);
        returns exactly 1 line in Lines (or exception)

    bool one(StringVect const &keywords, Type &dest);
        extracts exactly one value associated with keywords

positive:
    bool positive(StringVect const &keywords, double &dest)
        extracts dest (double > 0) from exactly 1 configuration line

proportion:
    bool proportion(StringVect const &keywords, double &dest)
        extracts count's dest (double, 0 <= dest <= 1)

VSDparameters:
    VSDvect VSDparameters(VaryType varyType, StringVect const &keywords,
                          initializer_list<char> const &required)
        required: type identifiers, like { 'a', 'b', 'c', 'd' }

        specs like Survival:
                #              value        spread      dist:
                type:  a        .00004475   .000004392  Normal

    VSDvect VSDparameters(VaryType varyType, StringVect const &keywords,
                          size_t nRequired)

        one line specs like Mammo:
        the 'nRequired' values are stored with SD = 0 in the VSDvect:
                #
                m:     .136    .136    .136    .136