File: setfirst.cc

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 (60 lines) | stat: -rw-r--r-- 1,980 bytes parent folder | download | duplicates (9)
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
#include "nonterminal.ih"

        // For an empty production, the N gets <empty>. For non-empty
        // productions: add those element's first symbols, and stop if an
        // element has no empty production. If, at the end, the final element
        // has an empty production, add <empty> as well

void NonTerminal::setFirst(NonTerminal *nonTerminal)
{
    FirstSet &firstSet = nonTerminal->d_first;
    Production::Vector &prodVect = nonTerminal->d_production;

    if (!prodVect.size())               // empty production
        firstSet.addEpsilon();          // add epsilon to FirstSet
    else
    {
        bool hasEpsilon = false;        // include epsilon at the end?

        for                             // visit all elements of a production
        (
            Production::Vector::const_iterator it = prodVect.begin(); 
                it != prodVect.end(); 
                    ++it
        )    
        {
            Production const &production = **it;

            bool epsilon = true;        // epsilon in this rule's elements
            for 
            (
                auto symPtrIt = production.begin();
                    symPtrIt != production.end();
                        ++symPtrIt
            )
            {
                firstSet += (*symPtrIt)->firstSet();
                                        // add the element's firstSet
    
                                        // element without <e>
                if (!(*symPtrIt)->firstSet().hasEpsilon())
                {
                    epsilon = false;
                    break;              // and done, this productionrule
                }
            }
            hasEpsilon |= epsilon;      // once a production rule includes
                                        // epsilon, hasEpsilon remains true
        }
        if (hasEpsilon)
            firstSet.addEpsilon();
        else
            firstSet.rmEpsilon();
    }

    s_counter += firstSet.setSize();
}