public Object clone() {
		Grammar g;
		try {
			g = (Grammar) getClass().newInstance();
		} catch (Throwable e) {
			System.err.println("Warning: clone of grammar failed!");
			return null;
		}

		HashMap map = new HashMap(); // old variables to new variables

		String[] variables = getVariables();
		for (int v = 0; v < variables.length; v++) {
			String variable = variables[v];
			String nvariable = new String(variables[v]);
			map.put(variable, nvariable);
			g.addVariable(nvariable);
		}

		/** set start variable. */
		g.setStartVariable((String) map.get(getStartVariable()));

		String[] terminals = getTerminals();
		for (int t = 0; t < terminals.length; t++) {
			g.addTerminal(new String(terminals[t]));
		}

		Production[] productions = getProductions();
		for (int p = 0; p < productions.length; p++) {
			String rhs = productions[p].getRHS();
			String lhs = productions[p].getLHS();
			g.addProduction(new Production(rhs, lhs));
		}

		return g;
	}