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