1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#!/usr/bin/ruby
2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# encoding: utf-8
3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrequire 'antlr3'
5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin LICENSE
7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver[The "BSD licence"]
9324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverCopyright (c) 2009-2010 Kyle Yetter
10324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverAll rights reserved.
11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
12324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverRedistribution and use in source and binary forms, with or without
13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodification, are permitted provided that the following conditions
14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverare met:
15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1. Redistributions of source code must retain the above copyright
17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    notice, this list of conditions and the following disclaimer.
18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2. Redistributions in binary form must reproduce the above copyright
19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    notice, this list of conditions and the following disclaimer in the
20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    documentation and/or other materials provided with the distribution.
21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 3. The name of the author may not be used to endorse or promote products
22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    derived from this software without specific prior written permission.
23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
24324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverTHIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverIMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverOF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverIN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverINCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverNOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverTHIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end
36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodule ANTLR3
38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::Debug
40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
41324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverNamespace for all debugging-related class and module definitions.
42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end
44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodule Debug
46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
47324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverDEFAULT_PORT = 49100
48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# since there are many components to the debug-mode
50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# section of the antlr3 runtime library, most of which
51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# are not used simultaneously, debug.rb contains the
52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# base of the debug library and the various listeners
53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# and tree-related code are autloaded on-demand
54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverautoload :EventSocketProxy, 'antlr3/debug/socket'
55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverautoload :RemoteEventSocketListener, 'antlr3/debug/socket'
56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverautoload :TraceEventListener, 'antlr3/debug/trace-event-listener'
57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverautoload :RecordEventListener, 'antlr3/debug/record-event-listener'
58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverautoload :RuleTracer, 'antlr3/debug/rule-tracer'
59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverautoload :EventHub, 'antlr3/debug/event-hub'
60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverautoload :TreeAdaptor, 'antlr3/tree/debug'
61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverautoload :TreeNodeStream, 'antlr3/tree/debug'
62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
63324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverRecognizerSharedState = Struct.new( 
64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # the rule invocation depth
65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  :rule_invocation_stack,
66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # a boolean flag to indicate whether or not the current decision is cyclic
67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  :cyclic_decision,
68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # a stack that tracks follow sets for error recovery
69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  :following,
70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # a flag indicating whether or not the recognizer is in error recovery mode
71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  :error_recovery,
72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # the index in the input stream of the last error
73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  :last_error_index,
74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # tracks the backtracking depth
75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  :backtracking,
76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # if a grammar is compiled with the memoization option, this will
77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # be set to a hash mapping previously parsed rules to cached indices
78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  :rule_memory,
79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # tracks the number of syntax errors seen so far
80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  :syntax_errors,
81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # holds newly constructed tokens for lexer rules
82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  :token,
83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # the input stream index at which the token starts
84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  :token_start_position,
85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # the input stream line number at which the token starts
86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  :token_start_line,
87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # the input stream column at which the token starts
88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  :token_start_column,
89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # the channel value of the target token
90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  :channel,
91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # the type value of the target token
92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  :type,
93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # the text of the target token
94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  :text
95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver)
96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::Debug::RecognizerSharedState
98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
99324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverANTLR3::Debug::RecognizerSharedState is identical to
100324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverANTLR3::RecognizerSharedState, but adds additional fields used for recognizers
101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvergenerated in debug or profiling mode.
102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end
104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass RecognizerSharedState
105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def initialize
106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    super( [], false, [], false, -1, 0, nil, 0, nil, -1 )
107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # ^-- same as this --v 
108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # self.following = []
109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # self.error_recovery = false
110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # self.last_error_index = -1
111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # self.backtracking = 0
112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # self.syntax_errors = 0
113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # self.rule_level = 0
114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # self.token_start_position = -1
115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def reset!
118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    self.following.clear
119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    self.error_recovery = false
120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    self.last_error_index = -1
121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    self.backtracking = 0
122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    self.rule_memory and rule_memory.clear
123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    self.syntax_errors = 0
124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    self.token = nil
125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    self.token_start_position = -1
126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    self.token_start_line = nil
127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    self.token_start_column = nil
128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    self.channel = nil
129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    self.type = nil
130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    self.text = nil
131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    self.rule_invocation_stack.clear
132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend
135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::Debug::ParserEvents
137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
138324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverParserEvents adds debugging event hook methods and functionality that is
139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrequired by the code ANTLR generated when called with the <tt>-debug</tt>
140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverswitch.
141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end
143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodule ParserEvents
144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  include ANTLR3::Error
145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def self.included( klass )
147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    super
148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if klass.is_a?( ::Class )
149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      def klass.debug?
150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        true
151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      end
152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  attr_reader :debug_listener
157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def initialize( stream, options = {} )
159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @debug_listener = options[ :debug_listener ] ||= begin
160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      EventSocketProxy.new( self, options ).handshake
161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    options[ :state ] ||= Debug::RecognizerSharedState.new
163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    super( stream, options )
164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if @input.is_a?( Debug::TokenStream )
165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @input.debug_listener ||= @debug_listener
166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    else
167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @input = Debug::TokenStream.wrap( @input, @debug_listener )
168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def rule_level
172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @state.rule_invocation_stack.length
173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def cyclic_decision?
176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @state.cyclic_decision
177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def cyclic_decision=( flag )
180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @state.cyclic_decision = flag
181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # custom attribute writer for debug_listener
184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # propegates the change in listener to the
185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # parser's debugging input stream
186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def debug_listener=( dbg )
187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @debug_listener = dbg
188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @input.debug_listener = dbg rescue nil
189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def begin_resync
192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @debug_listener.begin_resync
193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    super
194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def end_resync
197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @debug_listener.end_resync
198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    super
199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # TO-DO: is this pointless?
202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def resync
203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    begin_resync
204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    yield( self )
205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  ensure
206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end_resync
207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def begin_backtrack
210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @debug_listener.begin_backtrack( @state.backtracking )
211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def end_backtrack( successful )
214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @debug_listener.end_backtrack( @state.backtracking, successful )
215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def backtrack
218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @state.backtracking += 1
219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @debug_listener.begin_backtrack( @state.backtracking )
220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    start = @input.mark
221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    success =
222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      begin yield
223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      rescue BacktrackingFailed then false
224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      else true
225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      end
226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return success
227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  ensure
228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @input.rewind( start )
229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @debug_listener.end_backtrack( @state.backtracking, ( success rescue nil ) )
230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @state.backtracking -= 1
231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def report_error( exc )
234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    ANTLR3::RecognitionError === exc and
235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @debug_listener.recognition_exception( exc )
236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    super
237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def missing_symbol( error, expected_type, follow )
240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    symbol = super
241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @debug_listener.consume_node( symbol )
242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return( symbol )
243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def in_rule( grammar_file, rule_name )
246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @state.rule_invocation_stack.empty? and @debug_listener.commence
247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @debug_listener.enter_rule( grammar_file, rule_name )
248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @state.rule_invocation_stack.push( grammar_file, rule_name )
249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    yield
250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  ensure
251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @state.rule_invocation_stack.pop( 2 )
252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @debug_listener.exit_rule( grammar_file, rule_name )
253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @state.rule_invocation_stack.empty? and @debug_listener.terminate
254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def rule_invocation_stack
257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @state.rule_invocation_stack.each_slice( 2 ).to_a
258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def predicate?( description )
261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    result = yield
262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @debug_listener.semantic_predicate( result, description )
263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return result
264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def in_alternative( alt_number )
267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @debug_listener.enter_alternative( alt_number )
268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def in_subrule( decision_number )
271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @debug_listener.enter_subrule( decision_number )
272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    yield
273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  ensure
274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @debug_listener.exit_subrule( decision_number )
275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def in_decision( decision_number )
278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @debug_listener.enter_decision( decision_number )
279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    yield
280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  ensure
281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @debug_listener.exit_decision( decision_number )
282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend
284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::Debug::TokenStream
287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
288324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverA module that wraps token stream methods with debugging event code. A debuggable
289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverparser will <tt>extend</tt> its input stream with this module if the stream is
290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvernot already a Debug::TokenStream.
291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end
293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodule TokenStream
294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def self.wrap( stream, debug_listener = nil )
296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    stream.extend( self )
297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    stream.instance_eval do
298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @initial_stream_state = true
299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @debug_listener = debug_listener
300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @last_marker = nil
301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return( stream )
303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  attr_reader :last_marker
305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  attr_accessor :debug_listener
306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def consume
308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @initial_stream_state and consume_initial_hidden_tokens
309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    a = index + 1 # the next position IF there are no hidden tokens in between
310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    t = super
311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    b = index     # the actual position after consuming
312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @debug_listener.consume_token( t ) if @debug_listener
313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # if b > a, report the consumption of hidden tokens
315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    for i in a...b
316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @debug_listener.consume_hidden_token at( i )
317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # after a token stream fills up its buffer
322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # by exhausting its token source, it may
323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # skip to an initial position beyond the first
324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # actual token, if there are hidden tokens
325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # at the beginning of the stream.
326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  #
327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # This private method is used to
328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # figure out if any hidden tokens
329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # were skipped initially, and then
330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # report their consumption to
331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # the debug listener
332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def consume_initial_hidden_tokens
333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    first_on_channel_token_index = self.index
334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    first_on_channel_token_index.times do |index|
335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @debug_listener.consume_hidden_token at( index )
336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @initial_stream_state = false
338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  private :consume_initial_hidden_tokens
341324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
342324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  ############################################################################################
343324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  ###################################### Stream Methods ######################################
344324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  ############################################################################################
345324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
346324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def look( steps = 1 )
347324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @initial_stream_state and consume_initial_hidden_tokens
348324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    token = super( steps )
349324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @debug_listener.look( steps, token )
350324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return token
351324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
352324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
353324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def peek( steps = 1 )
354324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    look( steps ).type
355324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
356324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
357324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def mark
358324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @last_marker = super
359324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @debug_listener.mark( @last_marker )
360324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return @last_marker
361324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
362324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
363324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def rewind( marker = nil, release = true )
364324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @debug_listener.rewind( marker )
365324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    super
366324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
367324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend
368324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
369324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::Debug::EventListener
370324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
371324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverA listener that simply records text representations of the events. Useful for debugging the
372324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverdebugging facility ;) Subclasses can override the record() method (which defaults to printing
373324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverto stdout) to record the events in a different way.
374324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
375324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end
376324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodule EventListener
377324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  PROTOCOL_VERSION = '2'
378324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # The parser has just entered a rule. No decision has been made about
379324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # which alt is predicted.  This is fired AFTER init actions have been
380324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # executed.  Attributes are defined and available etc...
381324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # The grammarFileName allows composite grammars to jump around among
382324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # multiple grammar files.
383324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
384324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def enter_rule( grammar_file, rule_name )
385324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # do nothing
386324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
387324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
388324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # Because rules can have lots of alternatives, it is very useful to
389324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # know which alt you are entering.  This is 1..n for n alts.
390324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
391324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def enter_alternative( alt )
392324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # do nothing
393324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
394324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
395324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # This is the last thing executed before leaving a rule.  It is
396324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # executed even if an exception is thrown.  This is triggered after
397324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # error reporting and recovery have occurred (unless the exception is
398324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # not caught in this rule).  This implies an "exitAlt" event.
399324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # The grammarFileName allows composite grammars to jump around among
400324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # multiple grammar files.
401324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
402324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def exit_rule( grammar_file, rule_name )
403324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # do nothing
404324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
405324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
406324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # Track entry into any (...) subrule other EBNF construct
407324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
408324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def enter_subrule( decision_number )
409324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # do nothing
410324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
411324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
412324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def exit_subrule( decision_number )
413324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # do nothing
414324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
415324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
416324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # Every decision, fixed k or arbitrary, has an enter/exit event
417324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # so that a GUI can easily track what look/consume events are
418324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # associated with prediction.  You will see a single enter/exit
419324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # subrule but multiple enter/exit decision events, one for each
420324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # loop iteration.
421324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
422324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def enter_decision( decision_number )
423324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # do nothing
424324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
425324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
426324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def exit_decision( decision_number )
427324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # do nothing
428324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
429324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
430324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # An input token was consumed; matched by any kind of element.
431324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # Trigger after the token was matched by things like match(), matchAny().
432324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
433324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def consume_token( tree )
434324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # do nothing
435324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
436324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
437324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # An off-channel input token was consumed.
438324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # Trigger after the token was matched by things like match(), matchAny().
439324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # (unless of course the hidden token is first stuff in the input stream).
440324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
441324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def consume_hidden_token( tree )
442324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # do nothing
443324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
444324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
445324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # Somebody (anybody) looked ahead.  Note that this actually gets
446324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # triggered by both peek and look calls.  The debugger will want to know
447324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # which Token object was examined.  Like consumeToken, this indicates
448324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # what token was seen at that depth.  A remote debugger cannot look
449324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # ahead into a file it doesn't have so look events must pass the token
450324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # even if the info is redundant.
451324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
452324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def look( i, tree )
453324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # do nothing
454324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
455324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
456324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # The parser is going to look arbitrarily ahead; mark this location,
457324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # the token stream's marker is sent in case you need it.
458324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
459324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def mark( marker )
460324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # do nothing
461324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
462324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
463324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # After an arbitrairly long look as with a cyclic DFA (or with
464324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # any backtrack), this informs the debugger that stream should be
465324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # rewound to the position associated with marker.
466324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
467324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def rewind( marker = nil )
468324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # do nothing
469324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
470324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
471324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def begin_backtrack( level )
472324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # do nothing
473324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
474324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
475324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def end_backtrack( level, successful )
476324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # do nothing
477324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
478324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
479324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def backtrack( level )
480324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    begin_backtrack( level )
481324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    successful = yield( self )
482324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end_backtrack( level, successful )
483324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
484324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
485324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # To watch a parser move through the grammar, the parser needs to
486324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # inform the debugger what line/charPos it is passing in the grammar.
487324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # For now, this does not know how to switch from one grammar to the
488324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # other and back for island grammars etc...
489324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # This should also allow breakpoints because the debugger can stop
490324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # the parser whenever it hits this line/pos.
491324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
492324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def location( line, position )
493324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # do nothing
494324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
495324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
496324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # A recognition exception occurred such as NoViableAltError.  I made
497324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # this a generic event so that I can alter the exception hierachy later
498324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # without having to alter all the debug objects.
499324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # Upon error, the stack of enter rule/subrule must be properly unwound.
500324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # If no viable alt occurs it is within an enter/exit decision, which
501324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # also must be rewound.  Even the rewind for each mark must be unwount.
502324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # In the Java target this is pretty easy using try/finally, if a bit
503324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # ugly in the generated code.  The rewind is generated in DFA.predict()
504324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # actually so no code needs to be generated for that.  For languages
505324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # w/o this "finally" feature (C++?), the target implementor will have
506324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # to build an event stack or something.
507324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # Across a socket for remote debugging, only the RecognitionError
508324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # data fields are transmitted.  The token object or whatever that
509324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # caused the problem was the last object referenced by look.  The
510324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # immediately preceding look event should hold the unexpected Token or
511324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # char.
512324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # Here is a sample event trace for grammar:
513324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # b : C ({;}A|B) // {;} is there to prevent A|B becoming a set
514324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # | D
515324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # ;
516324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # The sequence for this rule (with no viable alt in the subrule) for
517324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # input 'c c' (there are 3 tokens) is:
518324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # commence
519324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # look
520324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # enterRule b
521324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # location 7 1
522324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # enter decision 3
523324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # look
524324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # exit decision 3
525324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # enterAlt1
526324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # location 7 5
527324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # look
528324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # consumeToken [c/<4>,1:0]
529324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # location 7 7
530324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # enterSubRule 2
531324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # enter decision 2
532324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # look
533324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # look
534324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # recognitionError NoViableAltError 2 1 2
535324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # exit decision 2
536324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # exitSubRule 2
537324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # beginResync
538324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # look
539324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # consumeToken [c/<4>,1:1]
540324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # look
541324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # endResync
542324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # look(-1)
543324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # exitRule b
544324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # terminate
545324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
546324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def recognition_exception( exception )
547324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # do nothing
548324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
549324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
550324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # Indicates the recognizer is about to consume tokens to resynchronize
551324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # the parser.  Any consume events from here until the recovered event
552324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # are not part of the parse--they are dead tokens.
553324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
554324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def begin_resync()
555324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # do nothing
556324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
557324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
558324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # Indicates that the recognizer has finished consuming tokens in order
559324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # to resychronize.  There may be multiple beginResync/endResync pairs
560324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # before the recognizer comes out of errorRecovery mode (in which
561324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # multiple errors are suppressed).  This will be useful
562324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # in a gui where you want to probably grey out tokens that are consumed
563324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # but not matched to anything in grammar.  Anything between
564324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # a beginResync/endResync pair was tossed out by the parser.
565324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
566324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def end_resync()
567324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # do nothing
568324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
569324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
570324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def resync
571324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    begin_resync
572324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    yield( self )
573324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end_resync
574324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
575324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
576324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # A semantic predicate was evaluate with this result and action text
577324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
578324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def semantic_predicate( result, predicate )
579324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # do nothing
580324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
581324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
582324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # Announce that parsing has begun.  Not technically useful except for
583324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # sending events over a socket.  A GUI for example will launch a thread
584324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # to connect and communicate with a remote parser.  The thread will want
585324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # to notify the GUI when a connection is made.  ANTLR parsers
586324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # trigger this upon entry to the first rule (the ruleLevel is used to
587324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # figure this out).
588324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
589324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def commence(  )
590324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # do nothing
591324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
592324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
593324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # Parsing is over; successfully or not.  Mostly useful for telling
594324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # remote debugging listeners that it's time to quit.  When the rule
595324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # invocation level goes to zero at the end of a rule, we are done
596324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # parsing.
597324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
598324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def terminate(  )
599324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # do nothing
600324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
601324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
602324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # Input for a tree parser is an AST, but we know nothing for sure
603324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # about a node except its type and text (obtained from the adaptor).
604324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # This is the analog of the consumeToken method.  Again, the ID is
605324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # the hashCode usually of the node so it only works if hashCode is
606324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # not implemented.  If the type is UP or DOWN, then
607324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # the ID is not really meaningful as it's fixed--there is
608324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # just one UP node and one DOWN navigation node.
609324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
610324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def consume_node( tree )
611324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # do nothing
612324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
613324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
614324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # A nil was created (even nil nodes have a unique ID...
615324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # they are not "null" per se).  As of 4/28/2006, this
616324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # seems to be uniquely triggered when starting a new subtree
617324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # such as when entering a subrule in automatic mode and when
618324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # building a tree in rewrite mode.
619324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # If you are receiving this event over a socket via
620324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # RemoteDebugEventSocketListener then only tree.ID is set.
621324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
622324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def flat_node( tree )
623324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # do nothing
624324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
625324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
626324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # Upon syntax error, recognizers bracket the error with an error node
627324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # if they are building ASTs.
628324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
629324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def error_node( tree )
630324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # do nothing
631324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
632324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
633324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # Announce a new node built from token elements such as type etc...
634324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # If you are receiving this event over a socket via
635324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # RemoteDebugEventSocketListener then only tree.ID, type, text are
636324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # set.
637324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
638324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def create_node( node, token = nil )
639324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # do nothing
640324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
641324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
642324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # Make a node the new root of an existing root.
643324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # Note: the newRootID parameter is possibly different
644324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # than the TreeAdaptor.becomeRoot() newRoot parameter.
645324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # In our case, it will always be the result of calling
646324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # TreeAdaptor.becomeRoot() and not root_n or whatever.
647324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # The listener should assume that this event occurs
648324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # only when the current subrule (or rule) subtree is
649324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # being reset to newRootID.
650324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # If you are receiving this event over a socket via
651324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # RemoteDebugEventSocketListener then only IDs are set.
652324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # @see antlr3.tree.TreeAdaptor.becomeRoot()
653324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
654324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def become_root( new_root, old_root )
655324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # do nothing
656324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
657324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
658324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # Make childID a child of rootID.
659324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # If you are receiving this event over a socket via
660324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # RemoteDebugEventSocketListener then only IDs are set.
661324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # @see antlr3.tree.TreeAdaptor.addChild()
662324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
663324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def add_child( root, child )
664324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # do nothing
665324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
666324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
667324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # Set the token start/stop token index for a subtree root or node.
668324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # If you are receiving this event over a socket via
669324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  # RemoteDebugEventSocketListener then only tree.ID is set.
670324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
671324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def set_token_boundaries( tree, token_start_index, token_stop_index )
672324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # do nothing
673324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
674324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
675324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def examine_rule_memoization( rule )
676324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # do nothing
677324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
678324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
679324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def on( event_name, &block )
680324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    sclass = class << self; self; end
681324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    sclass.send( :define_method, event_name, &block )
682324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
683324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
684324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  EVENTS = [ 
685324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    :add_child, :backtrack, :become_root, :begin_backtrack,
686324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    :begin_resync, :commence, :consume_hidden_token,
687324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    :consume_node, :consume_token, :create_node, :end_backtrack,
688324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    :end_resync, :enter_alternative, :enter_decision, :enter_rule,
689324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    :enter_sub_rule, :error_node, :exit_decision, :exit_rule,
690324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    :exit_sub_rule, :flat_node, :location, :look, :mark,
691324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    :recognition_exception, :resync, :rewind,
692324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    :semantic_predicate, :set_token_boundaries, :terminate
693324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  ].freeze
694324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
695324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend
696324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend
697324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend
698