1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#!/usr/bin/ruby
2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# encoding: utf-8
3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrequire 'antlr3'
5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodule ANTLR3
7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::FilterMode
8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
9324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverIf a lexer grammar specifies the <tt>filter = true</t> option, the generated
10324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverLexer code will include this module. It modifies the standard
11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver<tt>next_token</tt> to catch RecognitionErrors and skip ahead in the input until
12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverthe token! method can match a token without raising a RecognitionError.
13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
14324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverSee http://www.antlr.org/wiki/display/ANTLR3/Lexical+filters for more info on
15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverlexer filter mode.
16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end
18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodule FilterMode
19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def next_token
20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # if at end-of-file, return the EOF token
21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @input.peek == ANTLR3::EOF and return ANTLR3::EOF_TOKEN
22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @state.token                = nil
24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @state.channel              = ANTLR3::DEFAULT_CHANNEL
25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @state.token_start_position = @input.index
26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @state.token_start_column   = @input.column
27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @state.token_start_line     = @input.line
28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @state.text                 = nil
29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @state.backtracking         = 1
30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    m = @input.mark
32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    token!
33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @input.release( m )
34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    emit
35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return @state.token
36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  rescue ANTLR3::BacktrackingFailed
37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # token! backtracks with synpred at backtracking==2
38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # and we set the synpredgate to allow actions at level 1.
39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @input.rewind( m )
40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @input.consume # advance one char and try again
41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    retry
42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  rescue ANTLR3::Error::RecognitionError => re
43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # shouldn't happen in backtracking mode, but...
44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    report_error( re )
45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    recover( re )
46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  ensure
47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @state.backtracking = 0
48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def memoize( rule, start_index, success )
51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    super( rule, start_index, success ) if @state.backtracking > 1
52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def already_parsed_rule?( rule )
55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @state.backtracking > 1 ? super( rule ) : false
56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend
58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend
59