Annotation of OpenXM/src/OpenMath/OM2OXM.java, Revision 1.2
1.1 tam 1: /**
1.2 ! tam 2: * $OpenXM$
1.1 tam 3: *
4: * $B$3$N%/%i%9$G$O0J2<$N(B BNF $B$GI=$5$l$k9=J82r@O$r<BAu$7$F$$$k(B
5: * expr -> stag [expr | immediate]* etag
6: * immediate -> INTEGER
7: * | SYMBOL
8: * stag -> '<' SYMBOL '>'
9: * etag -> '<' '/' SYMBOL '>'
10: * $B=*C<5-9f(B: INTEGER, SYMBOL, '<', '/', '>'
11: * $BHs=*C<5-9f(B: expr, stag, etag, immediate
12: * $B3+;O5-9f(B: expr
13: *
14: * $B0J2<$N4X?t$r;HMQ(B:
15: * public void send(OutputStream os); - buffer $B$K$"$k(B OX message $B$rAw?.$9$k(B.
16: * public int parse(); - $B9=J82r@O$r3+;O$9$k(B.
17: * private int parse_expr(); - parser $B$N(B expr $BItJ,(B
18: * private Attribute parse_stag(); - parser $B$N(B stag $BItJ,(B
19: * private void parse_etag(Attribute tag,int argnum); - parser $B$N(B etag $BItJ,(B
20: * private int parse_immediate(); - parser $B$N(B immediate $BItJ,(B
21: * private void parse_error(String mesg); - parser $B$N(B error $B$rI=<($7$F=*N;$9$k(B
22: * public static void main(String[] args); - main $B4X?t(B.
23: *
24: * $B0J2<$NJQ?t$r;HMQ(B:
25: * Attribute Attribute; - $B;z6g2r@O4o$r8F$S=P$7(B, $B$=$NB0@-CM$rJ]B8$7$F$*$/(B
26: * int token; - $B8=:_FI$_9~$s$G$$$k(B token $B$rJ]B8$7$F$*$/$N$K;HMQ(B.
27: * CellStack stack; - $B%;%^%s%F%#%C%/%9$N%A%'%C%/$K;H$&FbIt%9%?%C%/(B.
28: * ByteArrayOutputStream buffer; - oxasir $B$KAw?.$9$k$^$($K%G!<%?$rN/$a$F$*$/(B
29: */
30:
31: import java.io.*;
32: import java.net.*;
33: import java.util.Vector;
34: import JP.ac.kobe_u.math.tam.OpenXM.*;
35:
36: final class OM2OXM implements Runnable{
37: private PushbackInputStream is;
38: private String attribute;
39: private int token = TT_NULL;
40: private boolean lexPushbackFlag = false;
41: private OpenXM asir; // for debug
42:
43: // Token Type for lexical analyzer
44: final static int TT_NULL = 0;
45: final static int TT_String = -1;
46: final static int TT_StartTag = -2;
47: final static int TT_EndTag = -3;
48: final static int TT_SingleTag = -4;
49:
50: public void run(){ // for debug
51: //$B%5!<%PB&$+$iAw?.$5$l$?J8;zNs$r<u?.$7$^$9!#(B
52: try{
53: while(true){
54: CMO tmp;
55:
56: Thread.yield();
57:
58: switch(asir.receiveOXtag()){
59: case OpenXM.OX_COMMAND:
60: asir.receiveSM();
61: break;
62:
63: case OpenXM.OX_DATA:
64: tmp = asir.receiveCMO();
1.2 ! tam 65: System.out.println("=> "+ CMO2OM(tmp));
1.1 tam 66: break;
67: }
68:
69: }
70: }catch(IOException e){}
71: }
72:
73: public static String CMO2OM(CMO cmo){
1.2 ! tam 74: return "<OMOBJ>"+ CMO2OM_sub(cmo) +"</OMOBJ>";
! 75: }
! 76:
! 77: private static String CMO2OM_sub(CMO cmo){
1.1 tam 78: String ret = "";
79:
80: switch(cmo.getDISCRIMINATOR()){
81: case CMO.CMO_NULL:
82: return "<OMI>0</OMI>";
83:
84: case CMO.CMO_INT32:
85: return "<OMI>"+ ((CMO_INT32)cmo).intValue() +"</OMI>";
86:
87: // case CMO.CMO_DATUM:
88:
89: case CMO.CMO_STRING:
90: return "<OMSTR>"+ ((CMO_STRING)cmo).getString() +"</OMSTR>";
91:
92: // case CMO.CMO_LIST:
93:
94: case CMO.CMO_MONOMIAL32:
95: ret += "<OMA><OMS name=\"Monom\" cd=\"poly\"/>";
1.2 ! tam 96: ret += CMO2OM_sub(((CMO_MONOMIAL32)cmo).getCoefficient());
1.1 tam 97: for(int i=0;i<((CMO_MONOMIAL32)cmo).getDegree().length;i++){
98: ret += "<OMI>"+ ((CMO_MONOMIAL32)cmo).getDegree()[i] +"</OMI>";
99: }
100: ret += "</OMA>";
101: return ret;
102:
103: case CMO.CMO_ZZ:
104: return "<OMI>"+ ((CMO_ZZ)cmo).BigIntValue() +"</OMI>";
105:
106: case CMO.CMO_QQ:
107: return "<OMA><OMS name=\"over\" cd=\"basic\"/>"+
1.2 ! tam 108: CMO2OM_sub(((CMO_QQ)cmo).getBunshi())+
! 109: CMO2OM_sub(((CMO_QQ)cmo).getBunbo())+
! 110: "</OMA>";
1.1 tam 111:
112: case CMO.CMO_ZERO:
113: return "<OMI> 0 </OMI>";
114:
115: // case CMO.CMO_DMS:
116:
117: case CMO.CMO_DMS_GENERIC:
118: ret += "<OMA><OMS name=\"PolyRing\" cd=\"poly\"/>";
119: ret += "<OMI>2</OMI>";
120: return ret;
121:
122: case CMO.CMO_DISTRIBUTED_POLYNOMIAL:
123: ret += "<OMA><OMS name=\"DMP\" cd=\"poly\"/>";
1.2 ! tam 124: ret += CMO2OM_sub(((CMO_DISTRIBUTED_POLYNOMIAL)cmo).getRing());
1.1 tam 125: ret += "<OMA><OMS name=\"SDMP\" cd=\"poly\"/>";
1.2 ! tam 126: for(int i=0;i<((CMO_DISTRIBUTED_POLYNOMIAL)cmo).getMonomials().length;
! 127: i++){
! 128: ret += CMO2OM_sub(((CMO_DISTRIBUTED_POLYNOMIAL)cmo).getMonomials()[i]);
1.1 tam 129: }
130: ret += "</OMA></OMA>";
131: return ret;
132:
133: case CMO.CMO_INDETERMINATE:
134: return "<OMV name=\""+ ((CMO_INDETERMINATE)cmo).getString() +"\"/>";
135:
136: /*
137: case CMO.CMO_TREE:
138: return "<OMA><OMS name=\""+ "\"/>"+
139: "</OMA>";
140: */
141:
142: default:
143: return "<OMSTR>"+ cmo.toCMOexpression() +"</OMSTR>";
144: }
145: }
146:
147: private boolean isSpace(int ch){ // use from lex
148: return (ch==' ' || ch=='\t' || ch=='\n' || ch=='\r');
149: }
150:
151: private int skipSpace() throws IOException{ // use from lex
152: int ch;
153:
154: do{
155: ch = is.read();
156: }while(isSpace(ch));
157: is.unread(ch);
158:
159: return ch;
160: }
161:
162: private void pushbackLex(){
163: if(lexPushbackFlag){
164: System.err.println("lex pushback error!");
165: }
166: lexPushbackFlag = true;
167: }
168:
169: private int readNextToken() throws IOException{ // lexical analyzer
170: String buf = "";
171: int ch;
172:
173: if(lexPushbackFlag){
174: lexPushbackFlag = false;
175: return token;
176: }
177:
178: token = TT_NULL;
179: attribute = "";
180: skipSpace();
181: ch = is.read();
182:
183: if(ch == '<'){ // for tag
184: ch = skipSpace();
185: if(ch == '/'){
186: is.read();
187: token = TT_EndTag;
188: skipSpace();
189: }else{
190: token = TT_StartTag;
191: }
192: while((ch = is.read()) != '>' && ch != '/' && ch != -1){
193: if(isSpace(ch)){
194: if((ch = skipSpace()) != '>' && ch != '/'){
195: buf += " ";
196: }
197: continue;
198: }
199:
200: buf += Character.toUpperCase((char)ch);
201:
202: if(ch == '"'){
203: do{
204: ch = is.read();
205: buf += (char)ch;
206: }while(ch != '"' && ch != -1);
207: }
208: }
209: if(ch == '>'){ // for StartTag and EndTag
210: attribute = buf;
211: return token;
212: }else if(ch == '/'){
213: skipSpace();
214: if((ch = is.read()) == '>'){ // for SingleTag
215: attribute = buf;
216: return token = TT_SingleTag;
217: }
218: }
219: return token = TT_NULL;
220: }else if(ch != -1){
221: is.unread(ch);
222: while((ch = is.read()) != '<' && ch != -1){
223: System.out.println("debug: "+ch);
224: if(isSpace(ch)){
225: String spaces = String.valueOf(ch);
226:
227: while(isSpace(ch = is.read())){
228: spaces += (char)ch;
229: }
230: if(ch != '<' && ch != -1){
231: buf += spaces;
232: }
233: is.unread(ch);
234: }else{
235: buf += (char)ch;
236: }
237: }
238: is.unread(ch);
239:
240: attribute = buf;
241: return token = TT_String;
242: }
243:
244: return token = TT_NULL;
245: }
246:
247: private boolean exceptTokenTypeInParse(int type) throws IOException{
248: // use from parse
249: if(readNextToken() != type){
250: parse_error("We expect type :'"+ type
251: +"', but we got type :'"+ token +"'("+ attribute +").");
252: }
253: //System.out.println(":"+token+":"+attribute+":"+type);
254: return true;
255: }
256:
257: public CMO parse(InputStream stream) throws IOException{
258: // start -> '<OMOBJ>' object '</OMOBJ>'
259: CMO ret;
260:
261: is = new PushbackInputStream(stream);
262:
263: exceptTokenTypeInParse(TT_StartTag);
264: if(!attribute.equals("OMOBJ")){
265: parse_error("We expect '<OMOBJ>'.");
266: }
267:
268: ret = parse_object();
269:
270: exceptTokenTypeInParse(TT_EndTag);
271: if(!attribute.equals("OMOBJ")){
272: parse_error("We expect '</OMOBJ>'.");
273: }
274:
275: return ret;
276: }
277:
278: private CMO parse_object() throws IOException{
279: // object -> variable
280: // | '<OMI>' S? integer S? '</OMI>'
281: // | '<OMA>' S? symbol S? objects S? '</OMA>'
282: CMO ret;
283:
284: if(readNextToken() != TT_StartTag && token != TT_SingleTag){
285: parse_error("We expect '<OMI> or '<OMA>' or '<OMV>'.");
286: }
287:
288: if(attribute.startsWith("OMV")){
289: pushbackLex();
290: ret = parse_variable();
291: }else if(attribute.equals("OMI")){
292: pushbackLex();
293: ret = parse_OMI();
294: }else if(attribute.equals("OMA")){
295: String name,cdname;
296: int argnum = 0;
297:
298: name = parse_symbol();
299:
300: if(name.equals("DMP")){
301: ret = parse_symb_DMP();
302: }else{
303: ret = new CMO_TREE(name,"Basic",parse_objects());
304: }
305:
306: exceptTokenTypeInParse(TT_EndTag);
307: if(!attribute.equals("OMA")){
308: parse_error("We expect '</OMA>'.");
309: }
310: }else{
311: parse_error("???");
312: ret = null;
313: }
314:
315: return ret;
316: }
317:
318: private CMO_ZZ parse_OMI() throws IOException{
319: CMO_ZZ ret;
320:
321: exceptTokenTypeInParse(TT_StartTag);
322: if(!attribute.equals("OMI")){
323: parse_error("We expect '<OMI>'.");
324: }
325:
326: ret = (CMO_ZZ)parse_integer();
327:
328: exceptTokenTypeInParse(TT_EndTag);
329: if(!attribute.equals("OMI")){
330: parse_error("We expect '</OMI>'.");
331: }
332:
333: return ret;
334: }
335:
336: private CMO parse_symb_DMP() throws IOException{
337: parse_object();
338: return new CMO_DISTRIBUTED_POLYNOMIAL(new CMO_DMS_GENERIC(),
339: parse_symb_SDMP());
340: }
341:
342: private CMO_MONOMIAL32[] parse_symb_SDMP() throws IOException{
343: Vector mono = new Vector();
344: CMO_MONOMIAL32[] ret;
345:
346: exceptTokenTypeInParse(TT_StartTag);
347: if(!attribute.equals("OMA")){
348: parse_error("We expect '<OMA>'.");
349: }
350:
351: if(!parse_symbol().equals("SDMP")){
352: parse_error("We expect '<SDMP>'");
353: }
354:
355: while(readNextToken() != TT_EndTag){
356: pushbackLex();
357: mono.addElement(parse_symb_Monom());
358: }
359:
360: if(!attribute.equals("OMA")){
361: parse_error("We expect '</OMA>'.");
362: }
363:
364: ret = new CMO_MONOMIAL32[mono.size()];
365: mono.copyInto((Object[])ret);
366:
367: return ret;
368: }
369:
370: private CMO_MONOMIAL32 parse_symb_Monom() throws IOException{
371: Vector degree = new Vector();
372: int[] array;
373:
374: exceptTokenTypeInParse(TT_StartTag);
375: if(!attribute.equals("OMA")){
376: parse_error("We expect '<OMA>'.");
377: }
378:
379: if(!parse_symbol().equals("Monom")){
380: parse_error("We expect '<Monom>'");
381: }
382:
383: while(readNextToken() != TT_EndTag){
384: pushbackLex();
385: degree.addElement(parse_OMI());
386: }
387:
388: if(!attribute.equals("OMA")){
389: parse_error("We expect '<OMA>'.");
390: }
391:
392: array = new int[degree.size()-1];
393: for(int i=0;i<array.length;i++){
394: array[i] = ((CMO_ZZ)degree.elementAt(i+1)).intValue();
395: }
396:
397: return new CMO_MONOMIAL32(array,(CMO_ZZ)degree.elementAt(0));
398: }
399:
400: private CMO parse_objects() throws IOException{
401: // $B2r@O$5$l$?(B object $B$r(B LIST $B$GJV$9(B
402: Vector objects = new Vector();
403: CMO[] array;
404:
405: while(readNextToken() != TT_EndTag){
406: pushbackLex();
407: objects.addElement(parse_object());
408: }
409: pushbackLex();
410:
411: objects.trimToSize();
412: array = new CMO[objects.size()];
413: objects.copyInto((Object[])array);
414:
415: System.out.println("debug :"+ new CMO_LIST(array));
416: return new CMO_LIST(array);
417: }
418:
419: private String parse_symbol() throws IOException{
420: // symbname $B$rJV$9(B
421: String ret = "";
422: StreamTokenizer para;
423:
424: exceptTokenTypeInParse(TT_SingleTag);
425:
426: para = new StreamTokenizer(new StringReader(attribute));
427: para.resetSyntax();
428: para.wordChars('A','Z');
429: para.wordChars('a','z');
430: para.wordChars('0','9');
431: para.wordChars('\u00A0','\u00FF');
432: para.whitespaceChars('\u0000','\u0020');
433: para.quoteChar('"');
434: para.eolIsSignificant(false);
435: para.lowerCaseMode(true);
436: para.slashStarComments(false);
437: para.slashSlashComments(false);
438: para.ordinaryChar('=');
439:
440: if(para.nextToken() != StreamTokenizer.TT_WORD
441: || !para.sval.equalsIgnoreCase("OMS")){
442: parse_error("We expect '<OMS>', but '"+ para.sval +"'.");
443: }
444:
445: if(para.nextToken() != StreamTokenizer.TT_WORD){
446: parse_error("We expect 'name' or 'cd'.");
447: }
448: if(para.sval.equals("name")){
449: if(para.nextToken() != '='){
450: parse_error("We expect '='.");
451: }
452: if(para.nextToken() != '"'){
453: parse_error("We expect '\"'.");
454: }
455: ret = parse_symbname(para.sval);
456:
457: if(para.nextToken() != StreamTokenizer.TT_WORD
458: || !para.sval.equals("cd")){
459: parse_error("We expect 'cd'.");
460: }
461: if(para.nextToken() != '='){
462: parse_error("We expect '='.");
463: }
464: if(para.nextToken() != '"'){
465: parse_error("We expect '\"'.");
466: }
467: parse_cdname(para.sval);
468:
469: }else if(para.sval.equals("cd")){
470: if(para.nextToken() != '='){
471: parse_error("We expect '='.");
472: }
473: if(para.nextToken() != '"'){
474: parse_error("We expect '\"'.");
475: }
476: parse_cdname(para.sval);
477:
478: if(para.nextToken() != StreamTokenizer.TT_WORD
479: || !para.sval.equals("name")){
480: parse_error("We expect 'cd'.");
481: }
482: if(para.nextToken() != '='){
483: parse_error("We expect '='.");
484: }
485: if(para.nextToken() != '"'){
486: parse_error("We expect '\"'.");
487: }
488: ret = parse_symbname(para.sval);
489:
490: }else{
491: parse_error("We expect 'name' or 'cd'.");
492: }
493:
494: if(para.nextToken() != StreamTokenizer.TT_EOF){
495: parse_error("We expect '/>'.");
496: }
497:
498: return ret;
499: }
500:
501: private CMO parse_integer() throws IOException{
502: //Attribute integer = new Attribute(value);
503: String str;
504: int i=0;
505:
506: exceptTokenTypeInParse(TT_String);
507: str = attribute;
508:
509: if(str.charAt(i)=='-'){
510: i++;
511: }
512: if(str.length()>=i+2 && str.charAt(i)=='x'){ // for HEX
513: String strhex = str.substring(0,i) + str.substring(i+1);
514: for(i++;i<str.length();i++){
515: if("0123456789ABCDEF".indexOf((int)str.charAt(i)) == -1){
516: parse_error("We expect integer.");
517: }
518: }
519: // 10 $B?J?t$KJQ49(B
520: str = (new java.math.BigInteger(strhex,16)).toString();
521: }else if(str.length()>=i+1){ // for DEC
522: for(;i<str.length();i++){
523: if("0123456789".indexOf((int)str.charAt(i)) == -1){
524: parse_error("We expect integer.");
525: }
526: }
527: }else{
528: parse_error("We expect integer.");
529: }
530:
531: return new CMO_ZZ(str);
532: }
533:
534: private CMO parse_variable() throws IOException{
535: StreamTokenizer para;
536: CMO ret;
537:
538: exceptTokenTypeInParse(TT_SingleTag);
539:
540: para = new StreamTokenizer(new StringReader(attribute));
541: para.resetSyntax();
542: para.wordChars('A','Z');
543: para.wordChars('a','z');
544: para.wordChars('0','9');
545: para.wordChars('\u00A0','\u00FF');
546: para.whitespaceChars('\u0000','\u0020');
547: para.quoteChar('"');
548: para.eolIsSignificant(false);
549: para.lowerCaseMode(true);
550: para.slashStarComments(false);
551: para.slashSlashComments(false);
552: para.ordinaryChar('=');
553:
554: if(para.nextToken() != StreamTokenizer.TT_WORD
555: || !para.sval.equalsIgnoreCase("OMV")){
556: parse_error("We expect '<OMV>'.");
557: }
558:
559: if(para.nextToken() != StreamTokenizer.TT_WORD
560: || !para.sval.equals("name")){
561: parse_error("We expect 'name', but obtain '"+ para.sval +"'.");
562: }
563: if(para.nextToken() != '='){
564: parse_error("We expect '='.");
565: }
566: if(para.nextToken() != '"'){
567: parse_error("We expect '\"'.");
568: }
569: ret = new CMO_INDETERMINATE(parse_varname(para.sval));
570:
571: if(para.nextToken() != StreamTokenizer.TT_EOF){
572: parse_error("We expect '/>'.");
573: }
574:
575: return ret;
576: }
577:
578: private String parse_varname(String str){
579: String words = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
580: + "0123456789+='(),-./:?!#$%*;@[]^_`{|}";
581:
582: for(int i=0;i<str.length();i++){
583: if(words.indexOf((int)str.charAt(i))==-1){
584: parse_error("string \""+ str +"\" is not varname.");
585: }
586: }
587:
588: return str;
589: }
590:
591: private String parse_cdname(String str){
592: String alphabet = "abcdefghijklmnopqrstuvwxyz";
593: int i=0;
594:
595: if(alphabet.indexOf((int)str.charAt(i))==-1){
596: parse_error("cdname \""+ str +"\" must begin small alphabet.");
597: }
598: for(i++;i<str.length();i++){
599: if((alphabet + "0123456789_").indexOf((int)str.charAt(i))==-1){
600: parse_error("string \""+ str +"\" is not cdname.");
601: }
602: }
603:
604: return str;
605: }
606:
607: private String parse_symbname(String str) throws IOException{
608: String Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
609: int i=0;
610:
611: if(Alphabet.indexOf((int)str.charAt(i))==-1){
612: parse_error("symbname \""+ str +"\" must begin alphabet.");
613: }
614: for(i++;i<str.length();i++){
615: if((Alphabet + "0123456789_").indexOf((int)str.charAt(i))==-1){
616: parse_error("string \""+ str +"\" is not symbname.");
617: }
618: }
619:
620: return str;
621: }
622:
623: private void parse_error(String mesg){
624: System.err.println(mesg);
625: System.err.print("error occuered near :");
626: try{
627: for(int i=0;i<10;i++){
628: System.err.print((char)is.read());
629: }
630: System.err.println((char)is.read());
631: }catch(IOException e){}
632: System.exit(1);
633: }
634:
635: public static void main(String[] argv) throws IOException{
636: OM2OXM P = new OM2OXM();
637: OpenXM asir;
638: String host = "localhost";
639: int CtrlPort = 1200,StreamPort = 1300;
640:
641: for(int i=0;i<argv.length;i++){
642: if(argv[i].equals("-h")){
643: System.out.println("");
644: System.exit(0);
645: }else if(argv[i].equals("-host")){
646: host = argv[++i];
647: }else if(argv[i].equals("-data")){
648: StreamPort = Integer.valueOf(argv[++i]).intValue();
649: }else if(argv[i].equals("-control")){
650: CtrlPort = Integer.valueOf(argv[++i]).intValue();
651: }else{
652: System.err.println("unknown option :"+ argv[i]);
653: System.exit(1);
654: }
655: }
656:
657: try{
658: asir = new OpenXM(host,CtrlPort,StreamPort);
659: asir.sendSM(new SM(SM.SM_mathcap));
660: }catch(UnknownHostException e){
661: System.err.println("host unknown.");
662: System.err.println(e.getMessage());
663: return;
664: }catch(IOException e){
665: System.err.println("connection failed.");
666: System.err.println("IOException occuer !!");
667: System.err.println(e.getMessage());
668: return;
669: }
670:
671: P.asir = asir;
672: new Thread(P).start();
673: System.out.println("start");
674:
675: try{
676: //P.value = new Attribute(System.in);
677:
678: //$B%5!<%PB&$+$iAw?.$5$l$?J8;zNs$r<u?.$7$^$9!#(B
679: while(true){
680: CMO obj = P.parse(System.in);
681: asir.send(obj);
682: asir.sendSM(new SM(SM.SM_popCMO));
683: }
684:
685: //System.out.println("breaking...");
686:
687: }catch(IOException e){
688: e.printStackTrace();
689: }
690: }
691: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>