1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#!/usr/bin/ruby
2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# encoding: utf-8
3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin LICENSE
5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver[The "BSD licence"]
7324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverCopyright (c) 2009-2010 Kyle Yetter
8324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverAll rights reserved.
9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
10324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverRedistribution and use in source and binary forms, with or without
11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodification, are permitted provided that the following conditions
12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverare met:
13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1. Redistributions of source code must retain the above copyright
15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    notice, this list of conditions and the following disclaimer.
16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2. Redistributions in binary form must reproduce the above copyright
17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    notice, this list of conditions and the following disclaimer in the
18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    documentation and/or other materials provided with the distribution.
19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 3. The name of the author may not be used to endorse or promote products
20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    derived from this software without specific prior written permission.
21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
22324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverTHIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverIMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverOF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverIN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverINCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverNOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverTHIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end
34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodule ANTLR3
36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::DFA
38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
39324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverDFA is a class that implements a finite state machine that chooses between
40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruveralternatives in a rule based upon lookahead symbols from an input stream.
41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
42324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverDeterministic Finite Automata (DFA) are finite state machines that are capable
43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverof recognizing <i>regular languages</i>. For more background on the subject,
44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvercheck out http://en.wikipedia.org/wiki/Deterministic_finite-state_machine or
45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvercheck out general ANTLR documentation at http://www.antlr.org
46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
47324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverANTLR implements most of its decision logic directly using code branching
48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstructures in methods. However, for certain types of decisions, ANTLR will
49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvergenerate a special DFA class definition to implement a decision.
50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
51324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverConceptually, these state machines are defined by a number of states, each state
52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrepresented by an integer indexed upward from zero. State number +0+ is the
53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver<i>start state</i> of the machine; every prediction will begin in state +0+. At
54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvereach step, the machine examines the next symbol on the input stream, checks the
55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvervalue against the transition parameters associated with the current state, and
56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvereither moves to a new state number to repeat the process or decides that the
57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermachine cannot transition any further. If the machine cannot transition any
58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverfurther and the current state is defined as an <i>accept state</i>, an
59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruveralternative has been chosen successfully and the prediction procedure ends. If
60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverthe current state is not an <i>accept state</i>, the prediction has failed and
61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverthere is <i>no viable alternative</i>.
62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
63324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverIn generated code, ANTLR defines DFA states using seven parameters, each defined
64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruveras a member of seven seperate array constants -- +MIN+, +MAX+, +EOT+, +EOF+,
65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver+SPECIAL+, +ACCEPT+, and +TRANSITION+. The parameters that characterize state
66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver+s+ are defined by the value of these lists at index +s+.
67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
68324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverMIN[s]::
69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  The smallest value of the next input symbol that has 
70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  a transition for state +s+
71324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverMAX[s]::
72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  The largest value of the next input symbol that has 
73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  a transition for state +s+
74324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverTRANSITION[s]::
75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  A list that defines the next state number based upon
76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  the current input symbol.
77324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverEOT[s]::
78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  If positive, it specifies a state transition in 
79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  situations where a non-matching input symbol does
80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  not indicate failure.
81324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverSPECIAL[s]::
82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  If positive, it indicates that the prediction 
83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  algorithm must defer to a special code block 
84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  to determine the next state. The value is used
85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  by the special state code to determine the next
86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  state.
87324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverACCEPT[s]::
88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  If positive and there are no possible state
89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  transitions, this is the alternative number
90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  that has been predicted
91324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverEOF[s]::
92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  If positive and the input stream has been exhausted,
93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  this is the alternative number that has been predicted.
94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
95324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverFor more information on the prediction algorithm, check out the #predict method
96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverbelow.
97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end
99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass DFA
101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  include Constants
102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  include Error
103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  attr_reader :recognizer, :decision_number, :eot, :eof, :min, :max,
105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver              :accept, :special, :transition, :special_block
106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  class << self
108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    attr_reader :decision, :eot, :eof, :min, :max,
109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                :accept, :special, :transition
110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def unpack( *data )
112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      data.empty? and return [].freeze
113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      
114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      n = data.length / 2
115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      size = 0
116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      n.times { |i| size += data[ 2*i ] }
117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      if size > 1024
118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        values = Hash.new( 0 )
119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        data.each_slice( 2 ) do |count, value|
120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          values[ value ] += count
121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        end
122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        default = values.keys.max_by { |v| values[ v ] }
123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        
124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        unpacked = Hash.new( default )
125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        position = 0
126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        data.each_slice( 2 ) do |count, value|
127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          unless value == default
128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            count.times { |i| unpacked[ position + i ] = value }
129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          end
130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          position += count
131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        end
132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      else
133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        unpacked = []
134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        data.each_slice( 2 ) do |count, value|
135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          unpacked.fill( value, unpacked.length, count )
136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        end
137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      end
138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      
139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      return unpacked
140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def initialize( recognizer, decision_number = nil,
145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                 eot = nil, eof = nil, min = nil, max = nil,
146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                 accept = nil, special = nil,
147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                 transition = nil, &special_block )
148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @recognizer = recognizer
149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @decision_number = decision_number || self.class.decision
150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @eot = eot || self.class::EOT #.eot
151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @eof = eof || self.class::EOF #.eof
152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @min = min || self.class::MIN #.min
153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @max = max || self.class::MAX #.max
154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @accept = accept || self.class::ACCEPT #.accept
155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @special = special || self.class::SPECIAL #.special
156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @transition = transition || self.class::TRANSITION #.transition
157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @special_block = special_block
158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  rescue NameError => e
159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    raise unless e.message =~ /uninitialized constant/
160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    constant = e.name
161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    message = Util.tidy( <<-END )
162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    | No #{ constant } information provided.
163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    | DFA cannot be instantiated without providing state array information.
164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    | When DFAs are generated by ANTLR, this information should already be
165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    | provided in the DFA subclass constants.
166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    END
167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  if RUBY_VERSION =~ /^1\.9/
170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def predict( input )
172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      mark = input.mark
173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      state = 0
174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      
175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      50000.times do
176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        special_state = @special[ state ]
177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if special_state >= 0
178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          state = @special_block.call( special_state )
179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          if state == -1
180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            no_viable_alternative( state, input )
181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return 0
182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          end
183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          input.consume
184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          next
185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        end
186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        @accept[ state ] >= 1 and return @accept[ state ]
187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        
188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # look for a normal char transition
189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        
190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        c = input.peek.ord
191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # the @min and @max arrays contain the bounds of the character (or token type)
192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # ranges for the transition decisions
193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if c.between?( @min[ state ], @max[ state ] )
194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          # c - @min[state] is the position of the character within the range
195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          # so for a range like ?a..?z, a match of ?a would be 0,
196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          # ?c would be 2, and ?z would be 25
197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          next_state = @transition[ state ][ c - @min[ state ] ]
198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          if next_state < 0
199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if @eot[ state ] >= 0
200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver              state = @eot[ state ]
201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver              input.consume
202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver              next
203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            end
204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            no_viable_alternative( state, input )
205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return 0
206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          end
207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          
208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          state = next_state
209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          input.consume
210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          next
211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        end
212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        
213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if @eot[ state ] >= 0
214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          state = @eot[ state ]
215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          input.consume()
216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          next
217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        end
218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        
219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ( c == EOF && @eof[ state ] >= 0 ) and return @accept[ @eof[ state ] ]
220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        no_viable_alternative( state, input )
221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return 0
222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      end
223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      
224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      ANTLR3.bug!( Util.tidy( <<-END ) )
225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      | DFA BANG!
226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      |   The prediction loop has exceeded a maximum limit of 50000 iterations
227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      | ----
228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      | decision: #@decision_number
229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      | description: #{ description }
230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      END
231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    ensure
232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      input.rewind( mark )
233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  else
236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def predict( input )
238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      mark = input.mark
239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      state = 0
240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      
241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      50000.times do
242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        special_state = @special[ state ]
243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if special_state >= 0
244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          state = @special_block.call( special_state )
245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          if state == -1
246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            no_viable_alternative( state, input )
247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return 0
248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          end
249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          input.consume
250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          next
251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        end
252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        @accept[ state ] >= 1 and return @accept[ state ]
253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        
254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # look for a normal char transition
255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        
256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        c = input.peek
257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # the @min and @max arrays contain the bounds of the character (or token type)
258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # ranges for the transition decisions
259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if c.between?( @min[ state ], @max[ state ] )
260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          # c - @min[state] is the position of the character within the range
261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          # so for a range like ?a..?z, a match of ?a would be 0,
262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          # ?c would be 2, and ?z would be 25
263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          next_state = @transition[ state ][ c - @min[ state ] ]
264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          if next_state < 0
265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if @eot[ state ] >= 0
266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver              state = @eot[ state ]
267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver              input.consume
268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver              next
269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            end
270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            no_viable_alternative( state, input )
271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return 0
272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          end
273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          
274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          state = next_state
275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          input.consume()
276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          next
277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        end
278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if @eot[ state ] >= 0
279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          state = @eot[ state ]
280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          input.consume()
281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          next
282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        end
283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ( c == EOF && @eof[ state ] >= 0 ) and return @accept[ @eof[ state ] ]
284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        no_viable_alternative( state, input )
285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return 0
286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      end
287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      
288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      ANTLR3.bug!( Util.tidy( <<-END ) )
289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      | DFA BANG!
290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      |   The prediction loop has exceeded a maximum limit of 50000 iterations
291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      | ----
292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      | decision: #@decision_number
293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      | description: #{ description }
294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      END
295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    ensure
296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      input.rewind( mark )
297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def no_viable_alternative( state, input )
302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    raise( BacktrackingFailed ) if @recognizer.state.backtracking > 0
303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    except = NoViableAlternative.new( description, @decision_number, state, input )
304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    error( except )
305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    raise( except )
306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def error( except )
309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # overridable debugging hook
310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def special_state_transition( state, input )
313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return -1
314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def description
317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return "n/a"
318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend
320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend
321