Production parseProduction (Model model) throws Exception
	{
		//if (!t.getToken().equals("(")) { model.error(t); throw new Exception(); };
		//t.advance();
		if (!t.getToken().equals("p") && !t.getToken().equals("p*")) model.recordError (t);
		t.advance();
		Symbol name = Symbol.get (t.getToken());
		t.advance();

		if (model.getProcedural().get(name) != null)
		{
			String oldname = name.getString();
			name = Symbol.getUnique (oldname);
			model.recordWarning ("production '"+oldname+"' exists; renaming second production as '"+name+"'", t);
		}

		Production p = new Production (name, model);
		Set<String> variables = new HashSet<String>();

		while (t.hasMoreTokens() && !t.getToken().equals("==>"))
		{
			BufferCondition bc = parseBufferCondition (model, variables);
			p.addBufferCondition (bc);
		}

		if (!t.getToken().equals("==>")) model.recordError (t);
		t.advance();

		while (t.hasMoreTokens() && !t.getToken().equals(")"))
		{
			BufferAction ba = parseBufferAction (model, variables);
			p.addBufferAction (ba);
		}

		if (!t.getToken().equals(")")) model.recordError (t);
		t.advance();

		lastProduction = name;
		return p;
	}