KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > lsmp > djep > xjep > XOperator


1 /* @author rich
2  * Created on 03-Aug-2003
3  *
4  * This code is covered by a Creative Commons
5  * Attribution, Non Commercial, Share Alike license
6  * <a HREF="http://creativecommons.org/licenses/by-nc-sa/1.0">License</a>
7  */

8 package org.lsmp.djep.xjep;
9
10 import org.nfunk.jep.function.PostfixMathCommandI;
11 import org.nfunk.jep.*;
12
13 /**
14  * An Operator with additional information about its commutativity etc.
15  * <p>
16  * Operators have a number of properties:
17  * <ul>
18  * <li>A symbol or name of the operator "+".
19  * <li>The number of arguments NO_ARGS 0, UNARY 1 (eg UMINUS -x),
20  * BINARY 2 (eq x+y), and NARY either 3 ( a>b ? a : b) or
21  * unspecified like a list [x,y,z,w].
22  * <li>The binging of the operator, LEFT 1+2+3 -> (1+2)+3 or RIGHT 1=2=3 -> 1=(2=3).
23  * <li>Whether the operator is ASSOCIATIVE or COMMUTATIVE.
24  * <li>The precedence of the operators + has a higher precedence than *.
25  * <li>For unary opperators they can either be PREFIX like -x or SUFIX like x%.
26  * <li>Comparative operators can be REFLEXIVE, SYMMETRIC, TRANSITIVE or EQUIVILENCE which has all three properties.
27  * <li>A reference to a PostfixtMathCommandI object which is used to evaluate an equation containing the operator.
28  * </ul>
29  * various is... and get... methods are provided to query the properties of the opperator.
30  *
31  * @author Rich Morris
32  * Created on 19-Oct-2003
33  */

34 public class XOperator extends Operator {
35     /** No arguments to operator */
36     public static final int NO_ARGS=0;
37     /** Unary operators, such as -x !x ~x */
38     public static final int UNARY=1;
39     /** Binary operators, such as x+y, x>y */
40     public static final int BINARY=2;
41     /** Trinary ops such as ?: and or higher like [x,y,z,w] */
42     public static final int NARY=3;
43     /** Left binding like +: 1+2+3 -> (1+2)+3 */
44     public static final int LEFT=4;
45     /** Right binding like =: 1=2=3 -> 1=(2=3) */
46     public static final int RIGHT=8;
47     /** Associative operators x*(y*z) == (x*y)*z . */
48     public static final int ASSOCIATIVE=16;
49     /** Commutative operators x*y = y*x. */
50     public static final int COMMUTATIVE=32;
51     /** Reflecive relations x=x for all x. */
52     public static final int REFLEXIVE=64;
53     /** Symmetric relation x=y implies y=x. */
54     public static final int SYMMETRIC=128;
55     /** Transative relations x=y and y=z implies x=z */
56     public static final int TRANSITIVE=256;
57     /** Equivilence relations = reflexive, transative and symetric. */
58     public static final int EQUIVILENCE=TRANSITIVE+REFLEXIVE+SYMMETRIC;
59     /** prefix operators -x **/
60     public static final int PREFIX=512;
61     /** postfix operators x%, if neiter prefix and postif then infix, if both trifix like x?y:z **/
62     public static final int SUFIX=1024;
63     /** self inverse operators like -(-x) !(!x) **/
64     public static final int SELF_INVERSE=2048;
65     /** composite operators, like a-b which is a+(-b) **/
66     public static final int COMPOSITE=4096;
67     /** For non commutative operators printing can be determined by the left or right binding.
68      * For example (a-b)-c is printed as a-b-c.
69      * But a/b/c could be ambiguous so (a/b)/c is printed with brackets.
70      */

71     public static final int USE_BINDING_FOR_PRINT=8192;
72     /** flags for type of operator */
73     private int flags;
74
75     /** construct a new operator.
76      *
77      * @param name printable name of operator
78      * @param pfmc postfix math command for opperator
79      * @param flags set of flags defining the porperties of the operator.
80      */

81     public XOperator(String JavaDoc name,PostfixMathCommandI pfmc,int flags)
82     {
83         super(name,pfmc);
84         this.flags = flags;
85     }
86     /**
87      * Allows a given precedent to be set.
88      * @param name
89      * @param pfmc
90      * @param flags
91      * @param precedence
92      */

93     public XOperator(String JavaDoc name,PostfixMathCommandI pfmc,int flags,int precedence)
94     {
95         this(name,pfmc,flags);
96         this.precedence=precedence;
97     }
98     /** construct a new operator, with a different name and symbol
99      *
100      * @param name name of operator, must be unique, used when describing operator
101      * @param symbol printable name of operator, used for printing equations
102      * @param pfmc postfix math command for opperator
103      * @param flags set of flags defining the porperties of the operator.
104      */

105     public XOperator(String JavaDoc name,String JavaDoc symbol,PostfixMathCommandI pfmc,int flags)
106     {
107         super(name,symbol,pfmc);
108         this.flags = flags;
109     }
110     /**
111      * Allows a given precedent to be set.
112      * @param name
113      * @param pfmc
114      * @param flags
115      * @param precedence
116      */

117     public XOperator(String JavaDoc name,String JavaDoc symbol,PostfixMathCommandI pfmc,int flags,int precedence)
118     {
119         super(name,symbol,pfmc);
120         this.precedence=precedence;
121         this.flags=flags;
122     }
123
124     public XOperator(Operator op,int flags,int precedence)
125     {
126         this(op.getName(),op.getSymbol(),op.getPFMC(),flags,precedence);
127     }
128
129     public XOperator(Operator op,int flags)
130     {
131         this(op.getName(),op.getSymbol(),op.getPFMC(),flags);
132     }
133     /** Creates a new XOperators with same flags and precedance as argument. */
134 // public XOperator(XOperator op,PostfixMathCommandI pfmc)
135
// {
136
// this(op.getName(),op.getSymbol(),op.getPFMC(),op.flags,op.precedence);
137
// }
138

139     /** precedence of operator, 0 is most tightly bound, so prec("*") < prec("+"). */
140     private int precedence = -1;
141     public final int getPrecedence() {return precedence;}
142     protected final void setPrecedence(int i) {precedence = i;}
143
144     /** Operators this is distributative over **/
145     private Operator distribOver[] = new Operator[0];
146
147     protected final void setDistributiveOver(Operator op)
148     {
149         int len = distribOver.length;
150         Operator temp[] = new Operator[len+1];
151         for(int i=0;i<len;++i) temp[i] = distribOver[i];
152         temp[len]=op;
153         distribOver=temp;
154     }
155     public boolean isDistributiveOver(Operator op)
156     {
157         for(int i=0;i<distribOver.length;++i)
158             if(op == distribOver[i])
159                 return true;
160         return false;
161     }
162     
163     /** For composite operators like a-b which is really a+(-b) there is a root operator and an inverse operator **/
164     private Operator rootOperator=null;
165     private Operator inverseOperator=null;
166     private Operator binaryInverseOperator=null;
167     protected void setRootOp(Operator root) {rootOperator=root;}
168     protected void setInverseOp(Operator inv){inverseOperator = inv;}
169     protected void setBinaryInverseOp(Operator inv){binaryInverseOperator = inv;}
170     public Operator getRootOp() { return rootOperator; }
171     public Operator getInverseOp() { return inverseOperator; }
172     public Operator getBinaryInverseOp() { return binaryInverseOperator; }
173
174     /**
175      * When parsing how is x+y+z interpreted.
176      * Can be Operator.LEFT x+y+z -> (x+y)+z or
177      * Operator.RIGHT x=y=z -> x=(y=z).
178      */

179     public final int getBinding() { return (flags & (LEFT | RIGHT)); }
180     public final boolean isAssociative() {return ((flags & ASSOCIATIVE) == ASSOCIATIVE);}
181     public final boolean isCommutative() { return ((flags & COMMUTATIVE) == COMMUTATIVE);}
182     public final boolean isBinary() { return ((flags & 3) == BINARY); }
183     public final boolean isUnary() { return ((flags & 3) == UNARY); }
184     public final boolean isNary() { return ((flags & 3) == NARY); }
185     public final int numArgs() { return (flags & 3); }
186     public final boolean isTransitive() { return ((flags & TRANSITIVE) == TRANSITIVE); }
187     public final boolean isSymmetric() { return ((flags & SYMMETRIC) == SYMMETRIC); }
188     public final boolean isReflexive() { return ((flags & REFLEXIVE) == REFLEXIVE); }
189     public final boolean isEquivilence() {return ((flags & EQUIVILENCE) == EQUIVILENCE); }
190     public final boolean isPrefix() {return ((flags & PREFIX) == PREFIX); }
191     public final boolean isSufix() {return ((flags & SUFIX) == SUFIX); }
192     public final boolean isComposite() {return ((flags & COMPOSITE) == COMPOSITE); }
193     public final boolean isSelfInverse() {return ((flags & SELF_INVERSE) == SELF_INVERSE); }
194     public final boolean useBindingForPrint() {return ((flags & USE_BINDING_FOR_PRINT) == USE_BINDING_FOR_PRINT); }
195
196     /** returns a verbose representation of the operator and all its properties. **/
197     
198     public String JavaDoc toFullString()
199     {
200         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
201         sb.append("Operator: \""+getSymbol()+"\"");
202         if(!getName().equals(getSymbol())) sb.append(" "+getName());
203         switch(numArgs()){
204         case 0: sb.append(" no arguments,"); break;
205         case 1: sb.append(" unary,"); break;
206         case 2: sb.append(" binary,"); break;
207         case 3: sb.append(" variable number of arguments,"); break;
208         }
209         if(isPrefix() && isSufix()) sb.append(" trifix,");
210         else if(isPrefix()) sb.append(" prefix,");
211         else if(isSufix()) sb.append(" sufix,");
212         else sb.append(" infix,");
213         if(getBinding()==LEFT) sb.append(" left binding,");
214         else if(getBinding()==RIGHT) sb.append(" right binding,");
215         if(isAssociative()) sb.append(" associative,");
216         if(isCommutative()) sb.append(" commutative,");
217         sb.append(" precedence "+getPrecedence()+",");
218         if(isEquivilence())
219             sb.append(" equivilence relation,");
220         else
221         {
222             if(isReflexive()) sb.append(" reflexive,");
223             if(isSymmetric()) sb.append(" symmetric,");
224             if(isTransitive()) sb.append(" transitive,");
225         }
226         sb.setCharAt(sb.length()-1,'.');
227         return sb.toString();
228     }
229 }
230
Popular Tags