Home | History | Annotate | Download | only in Antlr.Runtime.Debug
      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 
     47         public DebugEventHub(params IDebugEventListener[] listeners) {
     48             _listeners = new List<IDebugEventListener>(listeners);
     49         }
     50 
     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          */
     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 
     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 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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