1 package JSci.io; 2 3 import java.util.Set ; 4 import java.util.HashSet ; 5 import JSci.maths.*; 6 import JSci.maths.matrices.*; 7 import JSci.maths.vectors.*; 8 import JSci.maths.fields.*; 9 import org.w3c.dom.*; 10 import org.w3c.dom.mathml.*; 11 import org.xml.sax.SAXNotRecognizedException ; 12 import org.xml.sax.SAXNotSupportedException ; 13 import org.apache.xerces.parsers.DOMParser; 14 15 20 public final class MathMLParser extends DOMParser { 21 24 public MathMLParser() { 25 try { 26 setProperty("http://apache.org/xml/properties/dom/document-class-name", "JSci.mathml.MathMLDocumentImpl"); 27 } catch(SAXNotRecognizedException e) { 28 e.printStackTrace(); 29 } catch(SAXNotSupportedException e) { 30 e.printStackTrace(); 31 } 32 } 33 36 public Object [] translateToJSciObjects() { 37 return translateToJSciObjects(getDocument().getDocumentElement()); 38 } 39 public static Object [] translateToJSciObjects(Node root) { 40 Translator translator=new JSciObjectTranslator(); 41 return translator.translate(root); 42 } 43 46 public Object [] translateToJSciCode() { 47 return translateToJSciCode(getDocument().getDocumentElement()); 48 } 49 public static Object [] translateToJSciCode(Node root) { 50 Translator translator=new JSciCodeTranslator(); 51 return translator.translate(root); 52 } 53 56 static abstract class Translator extends Object { 57 public Translator() {} 58 public Object [] translate(Node root) { 59 return parseMATH(root); 60 } 61 64 private Object [] parseMATH(Node n) { 65 int len=0; 66 final NodeList nl=n.getChildNodes(); 67 final Object objList[]=new Object [nl.getLength()]; 68 Object obj; 69 for(int i=0;i<objList.length;i++) { 70 obj=processNode(nl.item(i)); 71 if(obj!=null) { 72 objList[len]=obj; 73 len++; 74 } 75 } 76 final Object parseList[]=new Object [len]; 77 System.arraycopy(objList,0,parseList,0,len); 78 return parseList; 79 } 80 83 protected Object processNode(Node n) { 84 final String nodeName=n.getNodeName(); 85 if(n instanceof MathMLApplyElement || nodeName.equals("reln")) 86 return parseAPPLY((MathMLContentContainer)n); 87 else if(n instanceof MathMLCnElement) 88 return parseCN((MathMLCnElement)n); 89 else if(n instanceof MathMLCiElement) 90 return parseCI((MathMLCiElement)n); 91 else if(n instanceof MathMLVectorElement) 92 return parseVECTOR((MathMLVectorElement)n); 93 else if(n instanceof MathMLMatrixElement) 94 return parseMATRIX((MathMLMatrixElement)n); 95 else if(n instanceof MathMLSetElement) 96 return parseSET((MathMLSetElement)n); 97 else if(n instanceof MathMLStringLitElement) 98 return parseMS((MathMLStringLitElement)n); 99 else if(nodeName.equals("mtext")) 100 return parseMTEXT((MathMLPresentationToken)n); 101 else 102 return null; 103 } 104 protected abstract Object parseAPPLY(MathMLContentContainer n); 105 protected abstract Object parseCN(MathMLCnElement n); 106 protected abstract Object parseCI(MathMLCiElement n); 107 protected abstract Object parseVECTOR(MathMLVectorElement n); 108 protected abstract Object parseMATRIX(MathMLMatrixElement n); 109 protected abstract Object parseSET(MathMLSetElement n); 110 protected abstract Object parseMS(MathMLStringLitElement n); 111 protected abstract Object parseMTEXT(MathMLPresentationToken n); 112 } 113 116 static class JSciObjectTranslator extends Translator { 117 private final int INTEGER=0; 118 private final int DOUBLE=1; 119 private final int COMPLEX=2; 120 private int setID=1; 121 122 public JSciObjectTranslator() {} 123 127 protected Object parseAPPLY(MathMLContentContainer n) { 128 final MathMLExpression expr=new MathMLExpression(); 129 final NodeList nl=n.getChildNodes(); 130 Object obj; 131 int i; 132 for(i=0;nl.item(i).getNodeType()==Node.TEXT_NODE;i++) 133 ; 134 expr.setOperation(nl.item(i).getNodeName()); 135 for(;i<nl.getLength();i++) { 136 obj=processNode(nl.item(i)); 137 if(obj!=null) 138 expr.addArgument(obj); 139 } 140 return expr; 141 } 142 146 protected Object parseCN(MathMLCnElement n) { 147 return parseNumber(n); 148 } 149 private Ring.Member parseNumber(MathMLCnElement n) { 150 if(!n.getBase().equals("10")) 152 return null; 153 final String attrType = n.getType(); 154 if(attrType.equals("real")) { 155 return new MathDouble(n.getFirstChild().getNodeValue()); 156 } else if(attrType.equals("integer")) { 157 return new MathInteger(n.getFirstChild().getNodeValue()); 158 } else if(attrType.equals("rational")) { 159 final Node num=n.getArgument(1); 160 final Node denom=n.getArgument(2); 161 return new MathDouble(num.getNodeValue()).divide(new MathDouble(denom.getNodeValue())); 162 } else if(attrType.equals("complex-cartesian")) { 163 final Node re=n.getArgument(1); 164 final Node im=n.getArgument(2); 165 return new Complex( 166 new Double (re.getNodeValue()).doubleValue(), 167 new Double (im.getNodeValue()).doubleValue() 168 ); 169 } else if(attrType.equals("complex-polar")) { 170 final Node mod=n.getArgument(1); 171 final Node arg=n.getArgument(2); 172 return Complex.polar( 173 new Double (mod.getNodeValue()).doubleValue(), 174 new Double (arg.getNodeValue()).doubleValue() 175 ); 176 } else if(attrType.equals("constant")) { 177 final String value=n.getFirstChild().getNodeValue(); 178 if(value.equals("π")) 179 return RealField.PI; 180 else if(value.equals("ⅇ") || value.equals("ⅇ")) 181 return RealField.E; 182 else if(value.equals("ⅈ") || value.equals("ⅈ")) 183 return ComplexField.I; 184 else if(value.equals("γ")) 185 return RealField.GAMMA; 186 else if(value.equals("&infty;") || value.equals("∞")) 187 return RealField.INFINITY; 188 else if(value.equals("&NaN;") || value.equals("&NotANumber;")) 189 return RealField.NaN; 190 else 191 return null; 192 } else 193 return null; 194 } 195 199 protected Object parseCI(MathMLCiElement n) { 200 return n.getFirstChild().getNodeValue(); 201 } 202 206 protected Object parseVECTOR(MathMLVectorElement n) { 207 int len=0,type=INTEGER; 208 final Ring.Member num[]=new Ring.Member[n.getNcomponents()]; 209 for(int i=0;i<num.length;i++) { 210 MathMLContentElement elem = n.getComponent(i+1); 211 if(elem instanceof MathMLCnElement) { 212 num[len]=parseNumber((MathMLCnElement)elem); 213 if(num[len]!=null) { 214 if(num[len] instanceof MathDouble && type<DOUBLE) 216 type=DOUBLE; 217 else if(num[len] instanceof Complex && type<COMPLEX) 218 type=COMPLEX; 219 len++; 220 } 221 } 222 } 223 if(type==INTEGER) { 225 final int array[]=new int[len]; 226 for(int i=0;i<array.length;i++) 227 array[i]=((MathInteger)num[i]).value(); 228 return new IntegerVector(array); 229 } else if(type==DOUBLE) { 230 final double array[]=new double[len]; 231 for(int i=0;i<array.length;i++) { 232 if(num[i] instanceof MathInteger) 233 array[i]=((MathInteger)num[i]).value(); 234 else 235 array[i]=((MathDouble)num[i]).value(); 236 } 237 return new DoubleVector(array); 238 } else { 239 final Complex array[]=new Complex[len]; 240 for(int i=0;i<array.length;i++) { 241 if(num[i] instanceof MathInteger) 242 array[i]=new Complex(((MathInteger)num[i]).value(),0.0); 243 else if(num[i] instanceof MathDouble) 244 array[i]=new Complex(((MathDouble)num[i]).value(),0.0); 245 else 246 array[i]=(Complex)num[i]; 247 } 248 return new ComplexVector(array); 249 } 250 } 251 255 protected Object parseMATRIX(MathMLMatrixElement n) { 256 int rows=0,cols=Integer.MAX_VALUE; 257 final Ring.Member num[][]=new Ring.Member[n.getNrows()][]; 258 for(int i=0;i<num.length;i++) { 259 num[rows]=parseMatrixRow(n.getRow(i+1)); 260 if(num[rows].length<cols) 261 cols=num[rows].length; 262 rows++; 263 } 264 int type=INTEGER; 266 for(int j,i=0;i<rows;i++) { 267 for(j=0;j<cols;j++) { 268 if(num[i][j] instanceof MathDouble && type<DOUBLE) 269 type=DOUBLE; 270 else if(num[i][j] instanceof Complex && type<COMPLEX) 271 type=COMPLEX; 272 } 273 } 274 if(type==INTEGER) { 276 final int array[][]=new int[rows][cols]; 277 for(int j,i=0;i<rows;i++) { 278 for(j=0;j<cols;j++) 279 array[i][j]=((MathInteger)num[i][j]).value(); 280 } 281 if(rows==cols) 282 return new IntegerSquareMatrix(array); 283 else 284 return new IntegerMatrix(array); 285 } else if(type==DOUBLE) { 286 final double array[][]=new double[rows][cols]; 287 for(int j,i=0;i<rows;i++) { 288 for(j=0;j<cols;j++) { 289 if(num[i][j] instanceof MathInteger) 290 array[i][j]=((MathInteger)num[i][j]).value(); 291 else 292 array[i][j]=((MathDouble)num[i][j]).value(); 293 } 294 } 295 if(rows==cols) 296 return new DoubleSquareMatrix(array); 297 else 298 return new DoubleMatrix(array); 299 } else { 300 final Complex array[][]=new Complex[rows][cols]; 301 for(int j,i=0;i<rows;i++) { 302 for(j=0;j<cols;j++) { 303 if(num[i][j] instanceof MathInteger) 304 array[i][j]=new Complex(((MathInteger)num[i][j]).value(),0.0); 305 else if(num[i][j] instanceof MathDouble) 306 array[i][j]=new Complex(((MathDouble)num[i][j]).value(),0.0); 307 else 308 array[i][j]=(Complex)num[i][j]; 309 } 310 } 311 if(rows==cols) 312 return new ComplexSquareMatrix(array); 313 else 314 return new ComplexMatrix(array); 315 } 316 } 317 320 private Ring.Member[] parseMatrixRow(MathMLMatrixrowElement n) { 321 int len=0; 322 final Ring.Member num[]=new Ring.Member[n.getNEntries()]; 323 for(int i=0;i<num.length;i++) { 324 MathMLContentElement elem = n.getEntry(i+1); 325 if(elem instanceof MathMLCnElement) { 326 num[len]=parseNumber((MathMLCnElement)elem); 327 if(num[len]!=null) 328 len++; 329 } 330 } 331 final Ring.Member row[]=new Ring.Member[len]; 332 System.arraycopy(num,0,row,0,len); 333 return row; 334 } 335 339 protected Object parseSET(MathMLSetElement n) { 340 final NodeList nl = n.getChildNodes(); 341 final Set elements = new HashSet (nl.getLength()); 342 for(int i=0;i<nl.getLength();i++) { 343 Node child = nl.item(i); 344 if(child instanceof MathMLCiElement) 345 elements.add(parseCI((MathMLCiElement)child)); 346 } 347 return new FiniteSet(elements); 349 } 350 354 protected Object parseMS(MathMLStringLitElement n) { 355 return n.getFirstChild().getNodeValue(); 356 } 357 361 protected Object parseMTEXT(MathMLPresentationToken n) { 362 return n.getFirstChild().getNodeValue(); 363 } 364 } 365 368 static class JSciCodeTranslator extends Translator { 369 public JSciCodeTranslator() {} 370 374 protected Object parseAPPLY(MathMLContentContainer n) { 375 final StringBuffer buf=new StringBuffer (); 376 final NodeList nl=n.getChildNodes(); 377 Object obj; 378 int i; 379 for(i=0;nl.item(i).getNodeType()==Node.TEXT_NODE;i++) 380 ; 381 String op=nl.item(i).getNodeName(); 382 if(op.equals("plus")) 383 op="add"; 384 else if(op.equals("minus")) 385 op="subtract"; 386 else if(op.equals("times")) 387 op="multiply"; 388 boolean isFirst=true; 389 for(;i<nl.getLength();i++) { 390 obj=processNode(nl.item(i)); 391 if(obj!=null) { 392 if(isFirst) { 393 buf.append(obj); 394 isFirst=false; 395 } else 396 buf.append('.').append(op).append('(').append(obj).append(')'); 397 } 398 } 399 return buf; 400 } 401 405 protected Object parseCN(MathMLCnElement n) { 406 if(!n.getBase().equals("10")) 408 return null; 409 final String attrType = n.getType(); 410 if(attrType.equals("real")) { 411 return "new MathDouble("+n.getFirstChild().getNodeValue()+')'; 412 } else if(attrType.equals("integer")) { 413 return "new MathInteger("+n.getFirstChild().getNodeValue()+')'; 414 } else if(attrType.equals("rational")) { 415 final Node num=n.getArgument(1); 416 final Node denom=n.getArgument(2); 417 return "new MathDouble("+num.getNodeValue()+'/'+denom.getNodeValue()+')'; 418 } else if(attrType.equals("complex-cartesian")) { 419 final Node re=n.getArgument(1); 420 final Node im=n.getArgument(2); 421 return "new Complex("+re.getNodeValue()+','+im.getNodeValue()+')'; 422 } else if(attrType.equals("complex-polar")) { 423 final Node mod=n.getArgument(1); 424 final Node arg=n.getArgument(2); 425 return "Complex.polar("+mod.getNodeValue()+','+arg.getNodeValue()+')'; 426 } else if(attrType.equals("constant")) { 427 final String value=n.getFirstChild().getNodeValue(); 428 if(value.equals("π")) 429 return "RealField.PI"; 430 else if(value.equals("ⅇ") || value.equals("ⅇ")) 431 return "RealField.E"; 432 else if(value.equals("ⅈ") || value.equals("ⅈ")) 433 return "ComplexField.I"; 434 else if(value.equals("γ")) 435 return "RealField.GAMMA"; 436 else if(value.equals("&infty;") || value.equals("∞")) 437 return "RealField.INFINITY"; 438 else if(value.equals("&NaN;") || value.equals("&NotANumber;")) 439 return "RealField.NaN"; 440 else 441 return null; 442 } else 443 return null; 444 } 445 449 protected Object parseCI(MathMLCiElement n) { 450 return n.getFirstChild().getNodeValue(); 451 } 452 456 protected Object parseVECTOR(MathMLVectorElement n) { 457 return null; 458 } 459 463 protected Object parseMATRIX(MathMLMatrixElement n) { 464 return null; 465 } 466 470 protected Object parseSET(MathMLSetElement n) { 471 return null; 472 } 473 477 protected Object parseMS(MathMLStringLitElement n) { 478 return n.getFirstChild().getNodeValue(); 479 } 480 484 protected Object parseMTEXT(MathMLPresentationToken n) { 485 return "/*\n"+n.getFirstChild().getNodeValue()+"\n*/"; 486 } 487 } 488 } 489 | Popular Tags |