001 /* 002 Copyright (C) 2003 Laurent Martelli <laurent@aopsys.com> 003 004 This program is free software; you can redistribute it and/or modify 005 it under the terms of the GNU Lesser General Public License as 006 published by the Free Software Foundation; either version 2 of the 007 License, or (at your option) any later version. 008 009 This program is distributed in the hope that it will be useful, 010 but WITHOUT ANY WARRANTY; without even the implied warranty of 011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 012 GNU Lesser General Public License for more details. 013 014 You should have received a copy of the GNU Lesser General Public 015 License along with this program; if not, write to the Free Software 016 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 017 USA */ 018 019 package org.objectweb.jac.core.parsers.acc; 020 021 import java.util.Iterator; 022 import java.util.Vector; 023 import org.apache.log4j.Logger; 024 025 /** 026 * Represents a non terminal rule 027 */ 028 public class NonTerminal extends SyntaxElement { 029 static Logger logger = Logger.getLogger("acc.parser"); 030 031 Vector children = new Vector(); 032 033 public NonTerminal(String name, SyntaxElement[] children) { 034 super(name, 035 children[0].getLeft(), 036 children[children.length-1].getRight()); 037 for (int i=0; i<children.length; i++) { 038 addChild(children[i]); 039 } 040 } 041 042 public NonTerminal(String name, SyntaxElement child) { 043 super(name,child.getLeft(),child.getRight()); 044 addChild(child); 045 } 046 047 public NonTerminal(String name) { 048 super(name,Integer.MAX_VALUE,-1); 049 } 050 051 /** 052 * Add child at the end 053 */ 054 public void addChild(SyntaxElement se) { 055 children.add(se); 056 childAdded(se); 057 } 058 059 /** 060 * Add child at the beginning 061 */ 062 public void insertChild(SyntaxElement se) { 063 children.add(0,se); 064 childAdded(se); 065 } 066 067 /** 068 * Returns the child at a given index 069 */ 070 public SyntaxElement getChild(int index) { 071 return (SyntaxElement)children.get(index); 072 } 073 074 /** 075 * Returns a child with a given name, or null. 076 */ 077 public SyntaxElement getChild(String name) { 078 Iterator it = children.iterator(); 079 while (it.hasNext()) { 080 SyntaxElement child = (SyntaxElement)it.next(); 081 if (child.getName().equals(name)) { 082 return child; 083 } 084 } 085 return null; 086 } 087 088 protected void childAdded(SyntaxElement se) { 089 se.setParent(this); 090 if (se.getLeft()<left) 091 left = se.getLeft(); 092 if (se.getRight()>right) 093 right = se.getRight(); 094 } 095 096 /** 097 * Returns the terminal syntax element of a given position 098 * @param position the position 099 * @return A Terminal se such that se.getLeft()<=position && 100 * se.getRight()>=position or null if there no such SyntaxElement. 101 */ 102 public Terminal getTerminalAt(int position) { 103 Iterator it = children.iterator(); 104 while (it.hasNext()) { 105 SyntaxElement se = (SyntaxElement)it.next(); 106 if (se.getLeft()<=position && se.getRight()>=position) { 107 logger.debug("Found "+se+" at "+position); 108 if (se instanceof Terminal) 109 return (Terminal)se; 110 else 111 return ((NonTerminal)se).getTerminalAt(position); 112 } 113 } 114 return null; 115 } 116 117 118 /** 119 * Returns the deepest syntax element at a given position 120 * @param position the position 121 * @return A SyntaxElement se such that se.getLeft()<=position && 122 * se.getRight()>=position or null if there no such SyntaxElement. 123 */ 124 public SyntaxElement getSyntaxElementAt(int position) { 125 Iterator it = children.iterator(); 126 while (it.hasNext()) { 127 SyntaxElement se = (SyntaxElement)it.next(); 128 if (se.getLeft()<=position && se.getRight()>=position) { 129 logger.debug("Found "+se+" at "+position); 130 if (se instanceof Terminal) 131 return se; 132 else 133 return ((NonTerminal)se).getSyntaxElementAt(position); 134 } 135 } 136 if (getLeft()<=position && getRight()>=position) 137 return this; 138 else 139 return null; 140 } 141 142 }