1 /*
2  * [The "BSD licence"]
3  * Copyright (c) 2005-2008 Terence Parr
4  * All rights reserved.
5  *
6  * Conversion to C#:
7  * Copyright (c) 2008-2009 Sam Harwell, Pixel Mine, Inc.
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. The name of the author may not be used to endorse or promote products
19  *    derived from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 namespace Antlr.Runtime.Debug {
34     using System.Collections.Generic;
35 
36     /** <summary>
37      *  Broadcast debug events to multiple listeners.  Lets you debug and still
38      *  use the event mechanism to build parse trees etc...  Not thread-safe.
39      *  Don't add events in one thread while parser fires events in another.
40      *  </summary>
41      *
42      *  <seealso cref="DebugEventRepeater"/>
43      */
44     public class DebugEventHub : IDebugEventListener {
45         List<IDebugEventListener> _listeners = new List<IDebugEventListener>();
46 
DebugEventHub(params IDebugEventListener[] listeners)47         public DebugEventHub(params IDebugEventListener[] listeners) {
48             _listeners = new List<IDebugEventListener>(listeners);
49         }
50 
Initialize()51         public virtual void Initialize() {
52         }
53 
54         /** <summary>
55          *  Add another listener to broadcast events too.  Not thread-safe.
56          *  Don't add events in one thread while parser fires events in another.
57          *  </summary>
58          */
AddListener(IDebugEventListener listener)59         public virtual void AddListener(IDebugEventListener listener) {
60             _listeners.Add(listener);
61         }
62 
63         /* To avoid a mess like this:
64             public void enterRule(final String ruleName) {
65                 broadcast(new Code(){
66                     public void exec(DebugEventListener listener) {listener.enterRule(ruleName);}}
67                     );
68             }
69             I am dup'ing the for-loop in each.  Where are Java closures!? blech!
70          */
71 
EnterRule(string grammarFileName, string ruleName)72         public virtual void EnterRule(string grammarFileName, string ruleName) {
73             for (int i = 0; i < _listeners.Count; i++) {
74                 IDebugEventListener listener = _listeners[i];
75                 listener.EnterRule(grammarFileName, ruleName);
76             }
77         }
78 
ExitRule(string grammarFileName, string ruleName)79         public virtual void ExitRule(string grammarFileName, string ruleName) {
80             for (int i = 0; i < _listeners.Count; i++) {
81                 IDebugEventListener listener = _listeners[i];
82                 listener.ExitRule(grammarFileName, ruleName);
83             }
84         }
85 
EnterAlt(int alt)86         public virtual void EnterAlt(int alt) {
87             for (int i = 0; i < _listeners.Count; i++) {
88                 IDebugEventListener listener = _listeners[i];
89                 listener.EnterAlt(alt);
90             }
91         }
92 
EnterSubRule(int decisionNumber)93         public virtual void EnterSubRule(int decisionNumber) {
94             for (int i = 0; i < _listeners.Count; i++) {
95                 IDebugEventListener listener = _listeners[i];
96                 listener.EnterSubRule(decisionNumber);
97             }
98         }
99 
ExitSubRule(int decisionNumber)100         public virtual void ExitSubRule(int decisionNumber) {
101             for (int i = 0; i < _listeners.Count; i++) {
102                 IDebugEventListener listener = _listeners[i];
103                 listener.ExitSubRule(decisionNumber);
104             }
105         }
106 
EnterDecision(int decisionNumber, bool couldBacktrack)107         public virtual void EnterDecision(int decisionNumber, bool couldBacktrack) {
108             for (int i = 0; i < _listeners.Count; i++) {
109                 IDebugEventListener listener = _listeners[i];
110                 listener.EnterDecision(decisionNumber, couldBacktrack);
111             }
112         }
113 
ExitDecision(int decisionNumber)114         public virtual void ExitDecision(int decisionNumber) {
115             for (int i = 0; i < _listeners.Count; i++) {
116                 IDebugEventListener listener = _listeners[i];
117                 listener.ExitDecision(decisionNumber);
118             }
119         }
120 
Location(int line, int pos)121         public virtual void Location(int line, int pos) {
122             for (int i = 0; i < _listeners.Count; i++) {
123                 IDebugEventListener listener = _listeners[i];
124                 listener.Location(line, pos);
125             }
126         }
127 
ConsumeToken(IToken token)128         public virtual void ConsumeToken(IToken token) {
129             for (int i = 0; i < _listeners.Count; i++) {
130                 IDebugEventListener listener = _listeners[i];
131                 listener.ConsumeToken(token);
132             }
133         }
134 
ConsumeHiddenToken(IToken token)135         public virtual void ConsumeHiddenToken(IToken token) {
136             for (int i = 0; i < _listeners.Count; i++) {
137                 IDebugEventListener listener = _listeners[i];
138                 listener.ConsumeHiddenToken(token);
139             }
140         }
141 
LT(int index, IToken t)142         public virtual void LT(int index, IToken t) {
143             for (int i = 0; i < _listeners.Count; i++) {
144                 IDebugEventListener listener = _listeners[i];
145                 listener.LT(index, t);
146             }
147         }
148 
Mark(int index)149         public virtual void Mark(int index) {
150             for (int i = 0; i < _listeners.Count; i++) {
151                 IDebugEventListener listener = _listeners[i];
152                 listener.Mark(index);
153             }
154         }
155 
Rewind(int index)156         public virtual void Rewind(int index) {
157             for (int i = 0; i < _listeners.Count; i++) {
158                 IDebugEventListener listener = _listeners[i];
159                 listener.Rewind(index);
160             }
161         }
162 
Rewind()163         public virtual void Rewind() {
164             for (int i = 0; i < _listeners.Count; i++) {
165                 IDebugEventListener listener = _listeners[i];
166                 listener.Rewind();
167             }
168         }
169 
BeginBacktrack(int level)170         public virtual void BeginBacktrack(int level) {
171             for (int i = 0; i < _listeners.Count; i++) {
172                 IDebugEventListener listener = _listeners[i];
173                 listener.BeginBacktrack(level);
174             }
175         }
176 
EndBacktrack(int level, bool successful)177         public virtual void EndBacktrack(int level, bool successful) {
178             for (int i = 0; i < _listeners.Count; i++) {
179                 IDebugEventListener listener = _listeners[i];
180                 listener.EndBacktrack(level, successful);
181             }
182         }
183 
RecognitionException(RecognitionException e)184         public virtual void RecognitionException(RecognitionException e) {
185             for (int i = 0; i < _listeners.Count; i++) {
186                 IDebugEventListener listener = _listeners[i];
187                 listener.RecognitionException(e);
188             }
189         }
190 
BeginResync()191         public virtual void BeginResync() {
192             for (int i = 0; i < _listeners.Count; i++) {
193                 IDebugEventListener listener = _listeners[i];
194                 listener.BeginResync();
195             }
196         }
197 
EndResync()198         public virtual void EndResync() {
199             for (int i = 0; i < _listeners.Count; i++) {
200                 IDebugEventListener listener = _listeners[i];
201                 listener.EndResync();
202             }
203         }
204 
SemanticPredicate(bool result, string predicate)205         public virtual void SemanticPredicate(bool result, string predicate) {
206             for (int i = 0; i < _listeners.Count; i++) {
207                 IDebugEventListener listener = _listeners[i];
208                 listener.SemanticPredicate(result, predicate);
209             }
210         }
211 
Commence()212         public virtual void Commence() {
213             for (int i = 0; i < _listeners.Count; i++) {
214                 IDebugEventListener listener = _listeners[i];
215                 listener.Commence();
216             }
217         }
218 
Terminate()219         public virtual void Terminate() {
220             for (int i = 0; i < _listeners.Count; i++) {
221                 IDebugEventListener listener = _listeners[i];
222                 listener.Terminate();
223             }
224         }
225 
226 
227         #region Tree parsing stuff
228 
ConsumeNode(object t)229         public virtual void ConsumeNode(object t) {
230             for (int i = 0; i < _listeners.Count; i++) {
231                 IDebugEventListener listener = _listeners[i];
232                 listener.ConsumeNode(t);
233             }
234         }
235 
LT(int index, object t)236         public virtual void LT(int index, object t) {
237             for (int i = 0; i < _listeners.Count; i++) {
238                 IDebugEventListener listener = _listeners[i];
239                 listener.LT(index, t);
240             }
241         }
242 
243         #endregion
244 
245 
246         #region AST Stuff
247 
NilNode(object t)248         public virtual void NilNode(object t) {
249             for (int i = 0; i < _listeners.Count; i++) {
250                 IDebugEventListener listener = _listeners[i];
251                 listener.NilNode(t);
252             }
253         }
254 
ErrorNode(object t)255         public virtual void ErrorNode(object t) {
256             for (int i = 0; i < _listeners.Count; i++) {
257                 IDebugEventListener listener = _listeners[i];
258                 listener.ErrorNode(t);
259             }
260         }
261 
CreateNode(object t)262         public virtual void CreateNode(object t) {
263             for (int i = 0; i < _listeners.Count; i++) {
264                 IDebugEventListener listener = _listeners[i];
265                 listener.CreateNode(t);
266             }
267         }
268 
CreateNode(object node, IToken token)269         public virtual void CreateNode(object node, IToken token) {
270             for (int i = 0; i < _listeners.Count; i++) {
271                 IDebugEventListener listener = _listeners[i];
272                 listener.CreateNode(node, token);
273             }
274         }
275 
BecomeRoot(object newRoot, object oldRoot)276         public virtual void BecomeRoot(object newRoot, object oldRoot) {
277             for (int i = 0; i < _listeners.Count; i++) {
278                 IDebugEventListener listener = _listeners[i];
279                 listener.BecomeRoot(newRoot, oldRoot);
280             }
281         }
282 
AddChild(object root, object child)283         public virtual void AddChild(object root, object child) {
284             for (int i = 0; i < _listeners.Count; i++) {
285                 IDebugEventListener listener = _listeners[i];
286                 listener.AddChild(root, child);
287             }
288         }
289 
SetTokenBoundaries(object t, int tokenStartIndex, int tokenStopIndex)290         public virtual void SetTokenBoundaries(object t, int tokenStartIndex, int tokenStopIndex) {
291             for (int i = 0; i < _listeners.Count; i++) {
292                 IDebugEventListener listener = _listeners[i];
293                 listener.SetTokenBoundaries(t, tokenStartIndex, tokenStopIndex);
294             }
295         }
296 
297         #endregion
298     }
299 }
300