/*
 * Bernoulli Compiler
 * Copyright (c) Cornell University
 * Department of Computer Science
 * 
 * Kamen Yotov (kamen@yotov.org)
 * 
 * $Source: C:/CVS/kyotov/kyotov/Research/BC/Core/Grammars/Symbols/Symbol.cs,v $
 * $Revision: 1.5 $
 * $Date: 2002/07/26 19:10:58 $
 */

using System;

namespace BC.Core
{
	using Automatas;

	namespace Grammars
	{
		using Reductions;

		namespace Symbols
		{
			[Serializable]
			public abstract class Symbol: IFormattable, ICloneable
			{
				public string ToString (string f, IFormatProvider fp)
				{
					return Format(f);
				}

				public override string ToString ()
				{
					return Format("");
				}

				public abstract string Format (string f);

				public abstract object Result
				{
					get;
					set;
				}

				public virtual Node Node
				{
					get
					{
						return null;
					}
					set
					{
					}
				}

				public static Sequence operator + (Symbol s1, Symbol s2)
				{
					Sequence a = new Sequence();

					a.Add(s1);
					a.Add(s2);

					return a;
				}

				public static Alternatives operator | (Symbol s1, Symbol s2)
				{
					return (Alternative)s1 | (Alternative) s2;
				}

				public static Alternative operator + (Symbol s, Reduction r)
				{
					return (Sequence)s + r;
				}

				public static implicit operator Sequence (Symbol s)
				{
					return new Sequence(s);
				}

				public static implicit operator Alternative (Symbol s)
				{
					return (Sequence)s;
				}

				public static implicit operator Alternatives (Symbol s)
				{
					return (Alternative)s;
				}

				public object Clone ()
				{
					return this.MemberwiseClone();
				}

				public static bool Match (Symbol s, Symbol p)
				{
					if (s is Terminal && p is Terminal)
						return (s as Terminal).IsA(p as Terminal);
					else 
						return s.Equals(p);
				}
			}
		}
	}
}