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