File: scannerbase.h

package info (click to toggle)
bisonc%2B%2B 6.09.02-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,984 kB
  • sloc: cpp: 9,375; ansic: 1,505; fortran: 1,134; makefile: 1,062; sh: 526; yacc: 84; lex: 60
file content (454 lines) | stat: -rw-r--r-- 13,011 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
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
// Generated by Flexc++ V2.18.00 on Tue, 03 Jun 2025 14:17:34 +0200

#ifndef ScannerBASE_H_INCLUDED
#define ScannerBASE_H_INCLUDED

#include <limits>
#include <iostream>
#include <deque>
#include <string>
#include <vector>
#include <memory>

// $insert baseIncludes
#include <sstream>
#include <set>
#include <iomanip>


class ScannerBase
{
                // idx: rule, value: tail length (NO_INCREMENTS if no tail)
    using VectorInt = std::vector<int>;

    static size_t const s_unavailable = std::numeric_limits<size_t>::max();
    static constexpr char const s_istream[] = "(istream)";

    enum 
    {
        AT_EOF = -1
    };

protected:
    enum Leave_
    {};

    enum class ActionType_
    {
        CONTINUE,               // transition succeeded, go on
        ECHO_CH,                // echo ch itself (d_matched empty)
        ECHO_FIRST,             // echo d_matched[0], push back the rest
        MATCH,                  // matched a rule
        RETURN,                 // no further continuation, lex returns 0.
    };

    enum class PostEnum_
    {
        END,                    // postCode called when lex_() ends 
        POP,                    // postCode called after switching files
        RETURN,                 // postCode called when lex_() returns
        WIP                     // postCode called when a non-returning rule
                                // was matched
    };

public:
    // $insert startcondenum
    enum class StartCondition_{
        INITIAL,
        xstring,
        pstring,
        pxstring,
        string,
        rawstring,
        comment,
        quote,
        block,
        typespec,
        typecomment,
    };

private:
    struct FinalData
    {
        size_t rule;
        size_t length;
    };
    struct Final
    {
        FinalData std;
        FinalData bol;
    };

        // class Input encapsulates all input operations. 
        // Its member get() returns the next input character
// $insert inputInterface

    class Input
    {
        std::deque<unsigned char> d_deque;  // pending input chars
        std::istream *d_in;                 // ptr for easy streamswitching
        size_t d_lineNr;                    // line count

        public:
            Input();
                                       // iStream: dynamically allocated
            Input(std::istream *iStream, size_t lineNr = 1);
            size_t get();                   // the next range
            void reRead(size_t ch);         // push back 'ch' (if < 0x100)
                                            // push back str from idx 'fmIdx'
            void reRead(std::string const &str, size_t fmIdx);
            size_t lineNr() const;
            size_t nPending() const;
            void setPending(size_t size);
            void close();                   // force closing the stream

        private:
            size_t next();                  // obtain the next character
    };

protected:

    struct StreamStruct
    {
        std::string pushedName;
        Input input;
    };

private:
    std::string d_cwd;
    std::vector<StreamStruct>    d_streamStack;

    std::string     d_filename;             // name of the currently processed
    static size_t   s_istreamNr;            // file. With istreams it receives
                                            // the name "<istream #>", where
                                            // # is the sequence number of the 
                                            // istream (starting at 1)
    int             d_startCondition = 0;
    int             d_lopSC = 0;

    size_t          d_state = 0;
    int             d_nextState;
    std::shared_ptr<std::ostream> d_out;
    bool            d_atBOL = true;         // the matched text starts at BOL
    Final d_final;

                                            // only used interactively:
    std::istream *d_in;                     // points to the input stream
    std::shared_ptr<std::istringstream> d_line; // holds line fm d_in
    
    std::string     d_matched;              // matched characters
    std::string     d_lopMatched;           // matched lop-rule characters 
    std::string::iterator d_lopIter;
    std::string::iterator d_lopTail;
    std::string::iterator d_lopEnd;

    size_t          d_lopPending;           // # pending input chars at lop1_
    bool            d_return;               // return after a rule's action 
    bool            d_more = false;         // set to true by more()

    size_t (ScannerBase::*d_get)() = &ScannerBase::getInput;

// $insert inputDeclaration

    Input           *d_input;               // input now in d_streamStack

protected:
    std::istream    *d_in_;
    int d_token_;                          // returned by lex_

    // $insert debugDecl
        static bool s_debug_;
        static std::ostringstream s_out_;
        static std::ostream &dflush_(std::ostream &out);
   private:


    int     const (*d_dfaBase_)[71];

    static int     const s_dfa_[][71];
    static int     const (*s_dfaBase_[])[71];
    enum: bool { s_interactive_ = false };
    enum: size_t {
        s_rangeOfEOF_           = 68,
        s_finIdx_               = 69,
        s_nRules_               = 110,
        s_maxSizeofStreamStack_ = 10
    };
    static size_t  const s_ranges_[];
    static size_t  const s_rf_[][2];

public:
    ScannerBase(ScannerBase const &other)             = delete;

    bool                debug()     const;
    std::string const  &filename()  const;
    std::string const  &cwd()       const;
    std::string const  &matched()   const;

    size_t              length()    const;
    size_t              lineNr()    const;

    void                setDebug(bool onOff);

    void                switchOstream(std::ostream &out);
    void                switchOstream(std::string const &outfilename);


    void                switchStreams(std::istream &in,
                                      std::ostream &out = std::cout);

    void                switchIstream(std::string const &infilename);
    void                switchStreams(std::string const &infilename,
                                      std::string const &outfilename);


// $insert interactiveDecl

protected:
    ScannerBase(std::istream &in, std::ostream &out, bool keepCwd = true);
    ScannerBase(std::string const &infilename, std::string const &outfilename, bool keepCwd = true);
    ~ScannerBase();

    bool            popStream();
    std::ostream   &out();
    void            echo() const;
    void            leave(int retValue) const;
    void toCwd() const;

//    `accept(n)' returns all but the first `n' characters of the current
// token back to the input stream, where they will be rescanned when the
// scanner looks for the next match.
//  So, it matches n of the characters in the input buffer, and so it accepts
//  n characters, rescanning the rest. 
    void            accept(size_t nChars = 0);      // former: less
    void            redo(size_t nChars = 0);        // rescan the last nChar
                                                    // characters, reducing
                                                    // length() by nChars
    void            more();
    void            push(size_t ch);                // push char to Input
    void            push(std::string const &txt);   // same: chars


    std::vector<StreamStruct> const &streamStack() const;

    void            pushStream(std::istream &curStream);
    void            pushStream(std::string const &curName);


    void            setFilename(std::string const &name);
    void            setMatched(std::string const &text);

    static std::string istreamName_();
        
        // members used by lex_(): they end in _ and should not be used
        // otherwise.

    ActionType_    actionType_(size_t range); // next action
    bool            return_();                 // 'return' from codeblock
    size_t          matched_(size_t ch);       // handles a matched rule
    size_t          getRange_(int ch);         // convert char to range
    size_t          get_();                    // next character
    size_t          state_() const;            // current state 
    void            continue_(int ch);         // handles a transition
    void            echoCh_(size_t ch);        // echoes ch, sets d_atBOL
    void            echoFirst_(size_t ch);     // handles unknown input
    void            updateFinals_();           // update a state's Final info
    void            noReturn_();               // d_return to false
    void            print_() const;            // optionally print token
    void            pushFront_(size_t ch);     // return char to Input
    void            reset_();                  // prepare for new cycle
                                                // next input stream:
    void            switchStream_(std::istream &in, size_t lineNr);   
    void            lopf_(size_t tail);        // matched fixed size tail
    void            lop1_(int lopSC);          // matched ab for a/b
    void            lop2_();                   // matches the LOP's b tail
    void            lop3_();                   // catch-all while matching b
    void            lop4_();                   // matches the LOP's a head

// $insert startconddecl
    StartCondition_ startCondition() const;   // current start condition
    void            begin(StartCondition_ startCondition);

private:
    static StartCondition_ constexpr SC(int sc);
    static int constexpr SC(StartCondition_ sc);

    size_t getInput();
    size_t getLOP();
    void p_pushStream(std::string const &name, std::istream *streamPtr);
    void setMatchedSize(size_t length);
    bool knownFinalState();
    static std::string chgWorkingDir(std::string const &filename);

    template <typename ReturnType, typename ArgType>
    static ReturnType constexpr as(ArgType value);
    static bool constexpr available(size_t value);
};

// $insert inputInline

inline size_t ScannerBase::Input::lineNr() const
{
    return d_lineNr;
}
inline size_t ScannerBase::Input::nPending() const
{
    return d_deque.size();
}
inline void ScannerBase::Input::setPending(size_t size)
{
    d_deque.erase(d_deque.begin(), d_deque.end() - size);
}
inline void ScannerBase::Input::close()
{
    delete d_in;
    d_in = 0;                   // switchStreams also closes
}


inline ScannerBase::~ScannerBase()
{
    d_input->close();
}

template <typename ReturnType, typename ArgType>
inline ReturnType constexpr ScannerBase::as(ArgType value)
{
    return static_cast<ReturnType>(value);
}

// $insert startcondimpl
inline ScannerBase::StartCondition_ constexpr ScannerBase::SC(int sc)
{
    return as<StartCondition_>(sc);
}

inline int constexpr ScannerBase::SC(StartCondition_ sc)
{
    return as<int>(sc);
}

inline ScannerBase::StartCondition_ ScannerBase::startCondition() const
{
    return SC(d_startCondition);
}

inline void ScannerBase::begin(StartCondition_ startCondition)
{
    if (s_debug_)
        s_out_ << "Switching to StartCondition_ # " << as<int>(startCondition) << '\n';
    // d_state is reset to 0 by reset_()
    d_dfaBase_ = s_dfaBase_[d_startCondition = SC(startCondition)];
}

inline bool ScannerBase::knownFinalState()
{
    return (d_atBOL && available(d_final.bol.rule)) ||
           available(d_final.std.rule);
}

inline bool constexpr ScannerBase::available(size_t value)
{   
    return value != std::numeric_limits<size_t>::max();
}

inline std::ostream &ScannerBase::out()
{
    return *d_out;
}

inline void ScannerBase::push(size_t ch)
{
    d_input->reRead(ch);
}

inline void ScannerBase::push(std::string const &str)
{
    d_input->reRead(str, 0);
}


inline std::vector<ScannerBase::StreamStruct> const &ScannerBase::streamStack() const
{
    return d_streamStack;
}



inline void ScannerBase::setFilename(std::string const &name)
{
    d_filename = name;
}

inline void ScannerBase::setMatched(std::string const &text)
{
    d_matched = text;
}

inline std::string const &ScannerBase::matched() const
{
    return d_matched;
}

inline std::string const &ScannerBase::cwd() const
{
    return d_cwd;
}

inline std::string const &ScannerBase::filename() const
{
    return d_filename;
}

inline void ScannerBase::echo() const
{
    *d_out << d_matched;
}

inline size_t ScannerBase::length() const
{
    return d_matched.size();
}

inline void ScannerBase::leave(int retValue) const
{
    throw as<Leave_>(retValue);
}

inline size_t ScannerBase::lineNr() const
{
    return d_input->lineNr();
}

inline void ScannerBase::more()
{
    d_more = true;
}

inline size_t ScannerBase::state_() const
{
    return d_state;
}

inline size_t ScannerBase::get_()
{
    return (this->*d_get)();
}

inline size_t ScannerBase::getInput()
{
    return d_input->get();
}

inline bool ScannerBase::return_()
{
    return d_return;
}

inline void ScannerBase::noReturn_()
{
    d_return = false;
}


#endif //  ScannerBASE_H_INCLUDED