Class: LL1Analyzer

Inherits:
Object show all
Defined in:
lib/antlr4/LL1Analyzer.rb

Constant Summary collapse

HIT_PRED =

Special value added to the lookahead sets to indicate that we hit

a predicate during analysis if {@code seeThruPreds==false}.
Token::INVALID_TYPE

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(atn) ⇒ LL1Analyzer

Returns a new instance of LL1Analyzer.



8
9
10
# File 'lib/antlr4/LL1Analyzer.rb', line 8

def initialize(atn)
    @atn = atn
end

Instance Attribute Details

#atnObject

Returns the value of attribute atn.



7
8
9
# File 'lib/antlr4/LL1Analyzer.rb', line 7

def atn
  @atn
end

Instance Method Details

#_LOOK(s, stopState, ctx, look, lookBusy, calledRuleStack, seeThruPreds, addEOF) ⇒ Object

* Compute set of tokens that can follow s in the ATN in the specified ctx.

<p>If ctx is null and stopState or the end of the rule containing s is reached, Token#EPSILON is added to the result set. If ctx is not null and addEOF is true and stopState or the end of the outermost rule is reached, Token#EOF is added to the result set.</p>

BlockEndState to detect epsilon paths through a closure. not be used. from causing a stack overflow. Outside code should pass new HashSet<ATNConfig> for this argument. ATN from causing a stack overflow. Outside code should pass new BitSet() for this argument. implicitly true and “see through them”, otherwise false to treat semantic predicates as opaque and add #HIT_PRED to the result if one is encountered. outermost context is reached. This parameter has no effect if ctx is null. /

Parameters:

  • s

    the ATN state.

  • stopState

    the ATN state to stop at. This can be a

  • ctx

    The outer context, or null if the outer context should

  • look

    The result lookahead set.

  • lookBusy

    A set used for preventing epsilon closures in the ATN

  • calledRuleStack

    A set used for preventing left recursion in the

  • seeThruPreds (@code true)

    to true semantic predicates as

  • addEOF

    Add Token#EOF to the result if the end of the



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
# File 'lib/antlr4/LL1Analyzer.rb', line 103

def _LOOK(s, stopState, ctx, look, lookBusy, \
                 calledRuleStack, seeThruPreds, addEOF)
    c = ATNConfig.new(s, 0, ctx)

    return if lookBusy.member? c
  
    lookBusy.add(c)

    if s == stopState then
        if ctx.nil?  then
            look.addOne(Token::EPSILON)
            return
        elsif ctx.isEmpty() and addEOF
            look.addOne(Token::EOF)
            return
        end
    end

    if s.kind_of? RuleStopState then
        if ctx.nil? then 
            look.addOne(Token::EPSILON)
            return
        elsif ctx.isEmpty() and addEOF
            look.addOne(Token::EOF)
            return
        end
        if PredictionContext.EMPTY != ctx
            # run thru all possible stack tops in ctx
            for i in 0..ctx.length-1  do
                returnState = self.atn.states[ctx.getReturnState(i)]
                removed = calledRuleStack.member? returnState.ruleIndex 
                begin
                    calledRuleStack.delete(returnState.ruleIndex)
                    self._LOOK(returnState, stopState, ctx.getParent(i), look, lookBusy, calledRuleStack, seeThruPreds, addEOF)
                ensure 
                    calledRuleStack.add(returnState.ruleIndex) if removed
                end
            end
            return
        end
    end
    for t in s.transitions do 
        if t.class == RuleTransition then
            next if calledRuleStack.member? t.target.ruleIndex 

            newContext = SingletonPredictionContext.create(ctx, t.followState.stateNumber)

            begin
                calledRuleStack.add(t.target.ruleIndex)
                self._LOOK(t.target, stopState, newContext, look, lookBusy, calledRuleStack, seeThruPreds, addEOF)
            ensure  
                calledRuleStack.remove(t.target.ruleIndex)
            end
        elsif t.kind_of? AbstractPredicateTransition then
            if seeThruPreds
                self._LOOK(t.target, stopState, ctx, look, lookBusy, calledRuleStack, seeThruPreds, addEOF)
            else
                look.addOne(LL1Analyzer::HIT_PRED)
            end
        elsif t.isEpsilon
            self._LOOK(t.target, stopState, ctx, look, lookBusy, calledRuleStack, seeThruPreds, addEOF)
        elsif t.class == WildcardTransition
            look.addRange( Token::MIN_USER_TOKEN_TYPE..self.atn.maxTokenType )
        else
            set = t.label
            if not set.nil? then
                if t.kind_of? NotSetTransition then
                    set = set.complement IntervalSet.of(Token::MIN_USER_TOKEN_TYPE, self.atn.maxTokenType)
                end
                look.addSet(set)
            end
        end
    end
end

#getDecisionLookahead(s) ⇒ Object

* Calculates the SLL(1) expected lookahead set for each outgoing transition of an ATNState. The returned array has one element for each outgoing transition in s. If the closure from transition i leads to a semantic predicate before matching a symbol, the element at index i of the result will be null.

/

Parameters:

  • s

    the ATN state

Returns:

  • the expected symbols for each outgoing transition of s.



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/antlr4/LL1Analyzer.rb', line 22

def getDecisionLookahead(s)
    return nil if s.nil? 

    count = s.transitions.length()
    look = Array.new
    for alt in 0..count-1
        look[alt] = Set.new()
        lookBusy = Set.new()
        seeThruPreds = false # fail to get lookahead upon pred
        self._LOOK(s.transition(alt).target, nil, PredictionContext.EMPTY, \
              look[alt], lookBusy, Set.new(), seeThruPreds, false)
        # Wipe out lookahead for this alternative if we found nothing
        # or we had a predicate when we !seeThruPreds
        if look[alt].length==0 or look[alt].member? LL1Analyzer::HIT_PRED then
            look[alt] = nil
        end
    end
    return look
end

#LOOK(s, stopState = nil, ctx = nil) ⇒ Object

* Compute set of tokens that can follow s in the ATN in the specified ctx.

<p>If ctx is null and the end of the rule containing s is reached, Token#EPSILON is added to the result set. If ctx is not null and the end of the outermost rule is reached, Token#EOF is added to the result set.</p>

BlockEndState to detect epsilon paths through a closure. should be ignored

specified ctx. /

Parameters:

  • s

    the ATN state

  • stopState (defaults to: nil)

    the ATN state to stop at. This can be a

  • ctx (defaults to: nil)

    the complete parser context, or null if the context

Returns:

  • The set of tokens that can follow s in the ATN in the



60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/antlr4/LL1Analyzer.rb', line 60

def LOOK(s, stopState=nil, ctx=nil )
    r = IntervalSet.new()
    seeThruPreds = true # ignore preds; get all lookahead
    if not ctx.nil? then
        lookContext = PredictionContextFromRuleContext.new(s.atn, ctx) 
    else 
        lookContext = nil
    end
    # lookContext = PredictionContextFromRuleContext(s.atn, ctx) if ctx is not None else None
    self._LOOK(s, stopState, lookContext, r, Set.new(), Set.new(), seeThruPreds, true)
    return r
end