File: parser.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 (356 lines) | stat: -rw-r--r-- 15,260 bytes parent folder | download | duplicates (2)
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
#ifndef Parser_h_included
#define Parser_h_included

// $insert baseclass
#include "parserbase.h"
// $insert scanner.h
#include "../scanner/scanner.h"

#include <unordered_map>

class NonTerminal;
class Terminal;
class Symbol;
struct Options;
class AtDollar;

namespace FBB
{
    class Mstream;
}

#undef Parser

class Parser: public ParserBase
{
            // actions to taken given tokens returned by the lexical scanner
    using ActionMap = std::unordered_map<size_t, void (Parser::*)()>;
    using Iterator = ActionMap::iterator;
    using Value = ActionMap::value_type;

    using StrStrMap = std::unordered_map<std::string, std::string>;

    enum SemType        // s_autoTypeLable must be synchronized with this
    {                   // enum
        SINGLE,
        UNION,
        POLYMORPHIC
    };
    static char const *s_autoTypeLabel[];

            // data members that are self-explanatory are not explicitly
            // described here.

    FBB::Arg &d_arg;
    Options &d_options;

    // $insert scannerobject
    Scanner d_scanner;
    std::string const &d_matched;

    Rules      &d_rules;
    Symtab      d_symtab;

    std::string d_expect;

    std::string d_field;                // %union field or %polymorphic
                                        // Tag_ value in %type specifications

    bool        d_typeDirective = false;// true following %type
    bool        d_negativeDollarIndicesOK = false;

    SemType     d_semType = SINGLE;     // see set{union,polymorphic}decl.cc

        // ADfun: pointer to member function handling @ and $ constructions
    using ADfun = bool (Parser::*)
                        (int nElements, Block &block, AtDollar const &atd);

        // ADmap: unordered map returning a function given an 
        //                                              AtDollar::Pattern
    using ADmap = std::unordered_map<int, ADfun>;

    ADmap *d_atDollar = &s_single;

    Terminal::Association d_association;

        // associations between tags (keys) and types (values) of
        // polymorphic semantic values
    StrStrMap d_polymorphic;

    static size_t s_nHidden;          // number of hidden nonterminals
    static std::ostringstream s_hiddenName;

    static std::string s_semanticValue; // name of the semantic value variable
                                        // used by the generated parser
    static std::string s_semanticValueStack;  
                                        // name of the semantic value stack
                                        // used by the generated parser
    static char s_locationValueStack[];  
                                    // name of the location value stack
                                    // used by the generated parser
    static char s_locationValue[];
                                    // name of the location value variable
                                    // used by the generated parser (@0)

    static std::string  s_stype;   // generic semantic value for POLYMORPHIC
                                    
    static std::string const s_undefined;


    static ADmap s_single;
    static ADmap s_union;
    static ADmap s_polymorphic;

    using ActionBlockInstaller = void (Parser::*)(std::string const &ruleType, 
                                                 Production const &prod);

    static ActionBlockInstaller s_defaultAction[2][3][3];

    public:
        Parser(Rules &rules);
        int parse();
        void cleanup();             // do cleanup following parse();
        StrStrMap releasePolymorphic();

    private:
        void updateDefaultActionLineNr();

        void checkField(std::string const &field);  // see inc/typename

        static void warnDefaultAction(Production const &prod);

        void installDefaultAction(Production const &prod, 
                                  std::string const &rhs);
        void defaultPolymorphicAction(Production const &prod);

        static std::string const &nameOf(std::string const &typeName);  //  ih

            // see s_defaultAction[] for details
        static int typeIndex(std::string const &typeName);  // 0: "", 
                                                            // 1: s_stype
                                                            // 2: other types
            // no action block is installed
        void blkNop(std::string const &ruleType, Production const &prod);

            // no action block + error message
        void blkErr(std::string const &ruleType, Production const &prod);

            // a $$ = STYPE_{} action block
        void blkSTYPE(std::string const &ruleType, Production const &prod);

            // a $$ = $1.get... action block
        void blkAssign(std::string const &ruleType, Production const &prod);

            // a $$ = $1 action block
        void blkDirect(std::string const &ruleType, Production const &prod);

            // with equal types: blkAssign, otherwise blkErr
        void blkCheck(std::string const &ruleType, Production const &prod);


            // warns that no action block is installed
        void blkNopW(std::string const &ruleType, Production const &prod);

            // warns and blkSTYPE
        void blkSTYPEW(std::string const &ruleType, Production const &prod);

            // warns and blkAssign
        void blkAssignW(std::string const &ruleType, Production const &prod);

            // warns and blkDirect
        void blkDirectW(std::string const &ruleType, Production const &prod);

            // with equal types blkAssignW, otherwise blkErr
        void blkCheckW(std::string const &ruleType, Production const &prod);

        std::ostream &stdWmsg(AtDollar const &atd) const;
        std::ostream &stdEmsg(AtDollar const &atd) const;
        void warnNegativeDollarIndices(AtDollar const &atd) const;

        int indexToOffset(int idx, int nElements) const;
        bool existingTag(AtDollar const &atd) const;    // false and emsg if
                                                        // not an existing tag

        void errNoUnionPtr(AtDollar const &atd);
        bool errNoTag(int nElements, Block &block, AtDollar const &atd);
        bool errIndexTooLarge(AtDollar const &atd, int nElements) const;

        void warnForceLSP(size_t lineNr) const;
        void warnMissingSemval() const;

        void substituteBlock(int nElements, Block &block);

            // replacement members (see also handleProductionElement)
            // the dval*Replace return true for midRule actions, 
            // because that prevents the missingSemval warning.
        bool dvalReplace(bool midRule, Block &block, AtDollar const &atd, 
                                       char const *suffix);
        bool svsReplace(int nElements, Block &block, AtDollar const &atd, 
                                                    char const *suffix);
        bool dvalUnionReplace(bool midRule, Block &block, AtDollar const &atd, 
                                                    char const *suffix);
        bool svsUnionReplace(int nElements, Block &block, AtDollar const &atd, 
                                                    char const *suffix);
        bool dvalPolyReplace(bool midRule, Block &block, AtDollar const &atd, 
                                                    char const *suffix);
        bool svsPolyReplace(int nElements, Block &block, AtDollar const &atd, 
                                                    char const *suffix);

        bool svsUnionTagReplace(int nElements, Block &block, AtDollar 
                                            const &atd, char const *suffix);
        bool svsPolyTagReplace(int nElements, Block &block, AtDollar 
                                            const &atd, char const *suffix);

            // returns s_semanticValueStack[index]:
        std::string svsElement(int nElements, int nr) const; // nr, not index!

            // empty, or tag associated with a production rule's element
            // requires: nr > 0                                 
        std::string const &productionTag(int nr) const;                 //  ih

            // $- and @-handlers
                                                                // @@
        bool loc(int nElements, Block &block, AtDollar const &atd);

                                                                // @nr
        bool locEl(int nElements, Block &block, AtDollar const &atd);

        // Wrt the dval* functions below:
        // 'refByScanner' means that the syntax used $$, but the scanner
        // changed that into _$$. In those cases mid-action rules should issue
        // warnings if the terminal has an associated type. Otherwise, an
        // explicit _$$ was used and no warning needs to be issued.
        
        // mid-rule actions (nElements < 0) should not issue missing Semval
        // warnings This is realized by returning true if nElements < 0

                                                                // $$
        bool dval(int nElements, Block &block, AtDollar const &atd);
        bool dvalUnion(int nElements, Block &block, AtDollar const &atd);
        bool dvalRefUnion(int nElements, Block &block, AtDollar const &atd);
        bool dvalPoly(int nElements, Block &block, AtDollar const &atd);

                                                                // $$(
        bool dvalPar(int nElements, Block &block, AtDollar const &atd);
        bool dvalUnionPar(int nElements, Block &block, AtDollar const &atd);
        bool dvalPolyPar(int nElements, Block &block, AtDollar const &atd);

                                                                // $$.
        bool dvalMem(int nElements, Block &block, AtDollar const &atd);
        bool dvalUnionMem(int nElements, Block &block, AtDollar const &atd);
        bool dvalPolyMem(int nElements, Block &block, AtDollar const &atd);

                                                                // $$->
        bool dvalPtr(int nElements, Block &block, AtDollar const &atd);
        bool dvalUnionPtr(int nElements, Block &block, AtDollar const &atd);
        bool dvalPolyPtr(int nElements, Block &block, AtDollar const &atd);

                                                        // $nr _$nr $-nr _$-nr
        bool svs(int nElements, Block &block, AtDollar const &atd);
        bool svsUnion(int nElements, Block &block, AtDollar const &atd);
        bool svsRefUnion(int nElements, Block &block, AtDollar const &atd);
        bool svsPoly(int nElements, Block &block, AtDollar const &atd);

                                                        // $nr. $-nr.
        bool svsMem(int nElements, Block &block, AtDollar const &atd);
        bool svsUnionMem(int nElements, Block &block, AtDollar const &atd);
        bool svsPolyMem(int nElements, Block &block, AtDollar const &atd);

                                                        // $nr-> $-nr->
        bool svsPtr(int nElements, Block &block, AtDollar const &atd);
        bool svsUnionPtr(int nElements, Block &block, AtDollar const &atd);
        bool svsPolyPtr(int nElements, Block &block, AtDollar const &atd);

                                                        // $<TAG>-nr
        bool svsUnionTag(int nElements, Block &block, AtDollar const &atd);
        bool svsPolyTag(int nElements, Block &block, AtDollar const &atd);

                                                        // $<TAG>-nr.
        bool svsUnionTagMem(int nElements, Block &block, AtDollar const &atd);
        bool svsPolyTagMem(int nElements, Block &block, AtDollar const &atd);

                                                        // $<TAG>-nr->
        bool svsUnionTagPtr(int nElements, Block &block, AtDollar const &atd);
        bool svsPolyTagPtr(int nElements, Block &block, AtDollar const &atd);


        // ================================================================

        void defaultAction() const;                                     // ih
        void constructorChecks() const;                                 // ih
        void warnTagMismatches() const;                                 // ih
        std::string warnAutoTag(bool midRule, AtDollar const &atd) const;

        void addPolymorphic(std::string const &tag, 
                            std::string const &typeSpec);

        void addIncludeQuotes(std::string *target); // ensure ".." or <..> 
                                                    // around target name
        void checkEmptyBlocktype();                                     // ih
        void checkFirstType();

        Symbol *defineNonTerminal(std::string const &name, 
                                  std::string const &stype);
        void definePathname(std::string *target);
        void defineTerminal(std::string const &name, Symbol::Type type);
        void defineTokenName(std::string const &name, bool hasValue);
        void expectRules();

        void setExpectedConflicts();                                    // ih
        void setLocationDecl();
        void setNegativeDollarIndices();                                // ih
        STYPE_ setPrecedence(size_t type);
        void setUnionDecl();
                                        

        size_t extractIndex(int *idx, size_t pos);
        size_t extractType(std::string *type, size_t pos, Block &block);

        STYPE_ handleProductionElements(STYPE_ &first, 
                                         STYPE_ const &second);
        void handleProductionElement(STYPE_ &last);


        void installAction(Block &block);

        void multiplyDefined(Symbol const *sp);

        void nestedBlock(Block &block); // define inner block as pseudo N

        std::string nextHiddenName();

        void setStart();
        void setPolymorphicDecl();

        void openRule(std::string const &ruleName);

        void predefine(Terminal const *terminal);   // Used by Parser() to 
                                                    // pre-enter into d_symtab

        NonTerminal *requireNonTerminal(std::string const &name);

        Symbol *useSymbol();
        Terminal *useTerminal();

        void error();                   // called on (syntax) errors
        void exceptionHandler(std::exception const &exc);               // ih

        int lex();                      // returns the next token from  // ih
                                        // the lexical scanner. 
        void print();                   // use, e.g., d_token, d_loc    // ih
                                                         
                                                         
    // support functions for parse():                    
        void executeAction_(int ruleNr);                
        void errorRecovery_();                          
        void nextCycle_();                              
        void nextToken_();                              
        void print_();                                     
                                        // used in, e.g., handleDollar
                                        // to obtain # elements for
                                        // end- or mid-rule actions
        static int nComponents(int nElements);                          // ih
};

#endif