public string TryGetSort(IConsTerm term)
		{
			if (term.IsCons("cf", 1))
				return TryGetSort((IConsTerm)term[0]);
			if (term.IsCons("lex", 1))
				return TryGetSort((IConsTerm)term[0]);
			if (term.IsCons("sort", 1))
				return term[0].ToString();
			if (term.IsCons("parameterized-sort", 2))
				return GetParameterizedSortName(term);
			if (term.IsCons("char-class", 1))
				return null;
			if (term.IsCons("alt", 2))
				return GetAltSortName(term);
			return null;
		}
		/// <summary>
		/// Parses a shift action item.
		/// </summary>
		/// <param name="term">The term.</param>
		/// <returns>The parsed action item.</returns>
		/// <example>
		/// The term might look like this:
		/// <code>
		/// shift(22)
		/// </code>
		/// </example>
		private ActionItem ParseShift(IConsTerm term)
		{
			#region Contract
			Contract.Requires<ArgumentNullException>(term != null);
			Contract.Requires<ArgumentException>(term.IsCons("shift", 1));
			Contract.Ensures(Contract.Result<ActionItem>() != null);
			#endregion

			var nextState = new StateRef(term[0].ToInt32());

			return new ShiftActionItem(nextState);
		}
		/// <summary>
		/// Parses a reduce action item.
		/// </summary>
		/// <param name="term">The term.</param>
		/// <param name="labels">The labels in the parse table.</param>
		/// <returns>The parsed action item.</returns>
		/// <example>
		/// The term might look like this (without lookahead)
		/// <code>
		/// reduce(0,280,0)
		/// </code>
		/// or this (with lookahead)
		/// <code>
		/// reduce(0,280,0,[follow-restriction([char-class([42,47])])])
		/// </code>
		/// </example>
		private ActionItem ParseReduce(IConsTerm term, IReadOnlyList<Label> labels)
		{
			#region Contract
			Contract.Requires<ArgumentNullException>(term != null);
			Contract.Requires<ArgumentException>(term.IsCons("reduce", 3) || term.IsCons("reduce", 4));
			Contract.Requires<ArgumentNullException>(labels != null);
			Contract.Ensures(Contract.Result<ActionItem>() != null);
			#endregion

			int productionArity = term[0].ToInt32();
			var label = new LabelRef(term[1].ToInt32() - SpoofaxParseTableFormat.LabelBase);
			ProductionType status = (ProductionType)term[2].ToInt32();
			bool isRecover = labels[label.Index].Production.IsRecover;
			bool isCompletion = labels[label.Index].Production.IsCompletion;
			var followRestriction = term.SubTerms.Count == 4 ? ParseLookaheadCharRanges((IListTerm)term[3]) : ArrayExt.Empty<IReadOnlySet<CodePoint>>();

			// Redundant information. Let's check it while we're at it.
			var production = labels[label.Index].Production;
			Contract.Assert(production.Arity == productionArity);
			Contract.Assert(production.IsCompletion == isCompletion);
			Contract.Assert(production.IsRecover == isRecover);
			Contract.Assert(production.Type == status);

			return new ReduceActionItem(label, followRestriction);
		}
		/// <summary>
		/// Parses an accept action item.
		/// </summary>
		/// <param name="term">The term.</param>
		/// <returns>The parsed action item.</returns>
		/// <example>
		/// The term might look like this:
		/// <code>
		/// accept()
		/// </code>
		/// </example>
		private ActionItem ParseAccept(IConsTerm term)
		{
			#region Contract
			Contract.Requires<ArgumentNullException>(term != null);
			Contract.Requires<ArgumentException>(term.IsCons("accept", 0));
			Contract.Ensures(Contract.Result<ActionItem>() != null);
			#endregion

			return new AcceptActionItem();
		}