//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// PLEASE DO NOT EDIT WITHOUT THE EXPLICIT CONSENT OF THE AUTHOR! \\
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
using System.Text;
namespace Ilog.Language.Syntax
{
/**
* This is the class of dummy tag symbols used in defining a
* precedence and associativity for a grammar rule using
* %prec.
*
* @version Last modified on Sat May 21 21:10:28 2005 by hak
* @author Hassan Aït-Kaci
* @copyright © 2000 ILOG, S.A.
*/
internal class RuleTag : Taggable
{
/**
* Constructs a RuleTag with specified precedence and specifier.
*/
internal RuleTag (int precedence, string specifier)
// throws NonFatalParseErrorException
{
this.precedence = precedence;
Decode(specifier);
}
/** This rule tag's precedence. */
private int precedence = Grammar.MIN_PRECEDENCE;
public int Precedence
{
get { return precedence; }
set { precedence = value; }
}
/** This rule tag's associativity. */
private int associativity = Grammar.NON_ASSOCIATIVE;
public int Associativity
{
get { return associativity; }
set { associativity = value; }
}
/** This rule tag's fixity. */
private int fixity = OperatorSymbol.INFIX;
public int Fixity
{
get { return fixity; }
}
/** This is always false. */
public bool IsOperator
{
get { return false; }
set { }
}
/** This operator symbol's associativity/fixity specifier. */
internal string Specifier
{
get
{
StringBuilder s = new StringBuilder();
if (associativity == Grammar.LEFT_ASSOCIATIVE)
s.Append("y");
else
if (fixity != OperatorSymbol.PREFIX)
s.Append("x");
s.Append("f");
if (associativity == Grammar.RIGHT_ASSOCIATIVE)
s.Append("y");
else
if (fixity != OperatorSymbol.POSTFIX)
s.Append("x");
return s.ToString();
}
}
/**
* Throws a NonFatalParseErrorException reporting the specified
* specifier as bad.
*/
private void Bad (string specifier) // throws NonFatalParseErrorException
{
throw new NonFatalParseErrorException
("Bad dynamic operator specifier ("+specifier+")");
}
/**
* Decodes and interprets the contents of a Prolog-style operator
* specifier string.
*/
private void Decode (string specifier) // throws NonFatalParseErrorException
{
if (specifier.Length == 2)
{
if (specifier.IndexOf('f') == 0)
{
fixity = OperatorSymbol.PREFIX;
if (specifier[1] == 'y')
{
associativity = Grammar.RIGHT_ASSOCIATIVE;
return;
}
if (specifier[1] == 'x')
{
associativity = Grammar.NON_ASSOCIATIVE;
return;
}
Bad(specifier);
}
if (specifier.IndexOf('f') == 1)
{
fixity = OperatorSymbol.POSTFIX;
if (specifier[0] == 'y')
{
associativity = Grammar.LEFT_ASSOCIATIVE;
return;
}
if (specifier[0] == 'x')
{
associativity = Grammar.NON_ASSOCIATIVE;
return;
}
}
Bad(specifier);
}
if (specifier.Length == 3 && specifier.IndexOf('f') == 1)
{
fixity = OperatorSymbol.INFIX;
if (specifier[0] == 'y')
{
if (specifier[2] != 'x')
Bad(specifier);
associativity = Grammar.LEFT_ASSOCIATIVE;
return;
}
if (specifier[0] == 'x')
{
if (specifier[2] == 'y')
associativity = Grammar.RIGHT_ASSOCIATIVE;
else
if (specifier[2] == 'x')
associativity = Grammar.NON_ASSOCIATIVE;
else
Bad(specifier);
return;
}
}
Bad(specifier);
}
/**
* Returns true iff the specified object is a rule tag with
* identical properties.
*/
public override bool Equals (object other)
{
if (this == other)
return true;
if (!(other is RuleTag))
return false;
RuleTag that = (RuleTag)other;
return this.precedence == that.precedence
&& this.associativity == that.associativity
&& this.fixity == that.fixity;
}
/**
* Returns a hash code for this operator symbol.
*/
public override int GetHashCode ()
{
return precedence ^ associativity ^ fixity;
}
/**
* Returns a string description for this operator sysmbol.
*/
public override string ToString ()
{
return "<"
+ Grammar.PrologPrecedence(precedence)
+ ","
+ Specifier
+ ">"
;
}
}
}