TokenVisitor.java :  » J2EE » hgcommons » biz » hammurapi » antlr » Java Open Source

Java Open Source » J2EE » hgcommons 
hgcommons » biz » hammurapi » antlr » TokenVisitor.java
/*
 * hgcommons 7
 * Hammurapi Group Common Library 
 * Copyright (C) 2003  Hammurapi Group
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * URL: http://www.hammurapi.biz/hammurapi-biz/ef/xmenu/hammurapi-group/products/products/hgcommons/index.html
 * e-Mail: support@hammurapi.biz 
*/
package biz.hammurapi.antlr;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

import antlr.Token;
import biz.hammurapi.util.DispatchException;
import biz.hammurapi.util.PoliteVisitor;


/**
* Visits Token and dispatches invocations by
* node names.
* @author Pavel Vlasov
* @version $Revision: 1.2 $
*/
public class TokenVisitor implements PoliteVisitor {
  private Method[] visitMethods;
  private Method[] leaveMethods;
  
  /**
   * @param tokenTypeNames - can be obtained from Parser.
   * @param visitPrefix - visit method name prefix. E.g. if prefix is <code>visit_</code> 
   * then visit of Token with type name <code>LITERAL_throws</code> will be dispatched
   * to method <code>visit_LITERAL_throws</code> if such method is present.
   * @param leavePrefix - leave method name prefix.
   */
  public TokenVisitor(String[] tokenTypeNames, String visitPrefix, String leavePrefix) {    
    Class thisClass=this.getClass();
    for (int i=0, mc=thisClass.getMethods().length; i<mc; i++) {
      Method m=thisClass.getMethods()[i];
      if (!m.getName().equals(visitPrefix) 
          && Modifier.isPublic(m.getModifiers())
          && m.getName().startsWith(visitPrefix) 
          && m.getParameterTypes().length==1 
          && Token.class.isAssignableFrom(m.getParameterTypes()[0])
          && (boolean.class.equals(m.getReturnType()) || void.class.equals(m.getReturnType()))) {
        for (int j=0; j<tokenTypeNames.length; j++) {
          if (m.getName().substring(visitPrefix.length()).equals(tokenTypeNames[j])) {
            visitMethods[j]=m;
          }
        }
      }
      
      if (!m.getName().equals(leavePrefix) 
          && Modifier.isPublic(m.getModifiers())
          && m.getName().startsWith(leavePrefix) 
          && m.getParameterTypes().length==1 
          && Token.class.isAssignableFrom(m.getParameterTypes()[0])
          && void.class.equals(m.getReturnType())) {
        for (int j=0; j<tokenTypeNames.length; j++) {
          if (m.getName().substring(leavePrefix.length()).equals(tokenTypeNames[j])) {
            leaveMethods[j]=m;
          }
        }
      }                  
    }
  }
  
  public boolean visit(Object target) {
    if (target instanceof AST) {
      Method m=visitMethods[((AST) target).getType()];
      if (m==null) {
        return true;
      }
      
      try {
        Object ret = m.invoke(this, new Object[] {target});
        return ret instanceof Boolean ? ((Boolean) ret).booleanValue() : true;
      } catch (IllegalArgumentException e) {
        throw new DispatchException(e);
      } catch (IllegalAccessException e) {
        throw new DispatchException(e);
      } catch (InvocationTargetException e) {
        throw new DispatchException(e);
      }
    }
    
    return false;
  }

  public void leave(Object target) {
    if (target instanceof Token) {
      Method m=visitMethods[((Token) target).getType()];
      if (m!=null) {
        try {
          m.invoke(this, new Object[] {target});
        } catch (IllegalArgumentException e) {
          throw new DispatchException(e);
        } catch (IllegalAccessException e) {
          throw new DispatchException(e);
        } catch (InvocationTargetException e) {
          throw new DispatchException(e);
        }
      }
    }
  }    
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.