001    package ifs.util;
002    
003    import java.io.*;
004    import java.util.*;
005    
006    /** A class for reading prolog files.
007     *
008     * @author <a href="mailto:muller@ktiml.mff.cuni.cz">Tomáš Müller</a>
009     * @version 1.0
010     */
011    public class PrologFile implements Iterator {
012        private java.io.BufferedReader iBufferedReader = null;
013        private Term iNextTerm = null;
014        
015        public PrologFile(String file) throws java.io.IOException {
016            iBufferedReader = new BufferedReader(new FileReader(file));
017            iNextTerm = (iBufferedReader.ready()?readTerm(new SpecialReader(iBufferedReader)):null);
018            if (iNextTerm==null) iBufferedReader.close(); else iBufferedReader.readLine();
019        }
020        
021        /** Reads a prolog file. It returns a set of terms */
022        public static Vector readTermsFromStream(java.io.InputStream is, String term) throws java.io.IOException {
023            BufferedReader br = new BufferedReader(new InputStreamReader(is));
024            Vector ret = new Vector();
025            //int x=0;
026            while (br.ready()) {
027                Term t = readTerm(new SpecialReader(br));
028                //System.out.println(t);
029                //x++;
030                //if (x>10) break;
031                if (t!=null && t.getText()!=null && t.getText().startsWith(term)) {
032                    ret.addElement(t);
033                }
034                br.readLine();
035            }
036            br.close();
037            return ret;
038        }
039        
040        /** Writes a set of terms. */
041        public static void writeTerms(PrintWriter pw, Vector terms) throws java.io.IOException {
042            for (Enumeration e=terms.elements();e.hasMoreElements();) {
043                Term t = (Term)e.nextElement();
044                writeTerm(pw,t);
045            }
046        }
047        
048        /** reads a term */
049        private static Term readTerm( SpecialReader is) throws IOException {
050            StringBuffer text=new StringBuffer();
051            Vector content = null;
052            int i;
053            if ((i = is.read())>=0) {
054                while ((char)i=='%' || (char)i==':') {
055                    do {
056                        i=is.read();
057                    } while (i>=0 && !( i==0x0d || i==0x0a ));
058                    i=is.read();
059                    if (i>=0 && (i==0x0d || i==0x0a )) i=is.read();
060                }
061                if (i>=0) is.flush((char)i);
062            }
063            char prev = (char)i;
064            if (i>=0) while ((i = is.read())>=0) {
065                char ch = (char)i;
066                if (ch=='\n' || ch=='\r')
067                    if (prev=='.') break; else continue;
068                if (ch=='(' || ch=='[') {
069                    content = new Vector();
070                    content.addElement(readTerm(is));
071                } else if (content==null && (ch==',' || ch==')' || ch==']')) {
072                    is.flush(ch);
073                    break;
074                } else if (ch==',') content.addElement(readTerm(is));
075                else if (ch==')' || ch==']') break;
076                else text.append(ch);
077                prev = ch;
078            } else return null;
079            Term ret =  new Term(text.toString().trim(),content);
080            return ret;
081        }
082        
083        /** writes a term */
084        private static void writeTerm( PrintWriter pw, Term t) {
085            pw.println(t.toString()+".");
086        }
087        
088        
089        public boolean hasNext() {
090            return iNextTerm!=null;
091        }
092        
093        public Object next() {
094            Term ret = iNextTerm;
095            try {
096                iNextTerm = (iBufferedReader.ready()?readTerm(new SpecialReader(iBufferedReader)):null);
097            } catch (java.io.IOException x) {
098                iNextTerm = null;
099            }
100            try {
101                if (iNextTerm==null) iBufferedReader.close(); else iBufferedReader.readLine();
102            } catch (java.io.IOException x) {}
103            return ret;
104        }
105        
106        public void remove() {
107        }
108        
109        /** Flushable reader -- extension of java.io.Reader */
110        private static class SpecialReader {
111            /** reader */
112            private Reader iReader = null;
113            /** flushed characters */
114            private StringBuffer iFlushedChars = new StringBuffer();
115            
116            /** constructor */
117            public SpecialReader(Reader r) {
118                iReader = r;
119            }
120            
121            /** reads a byte */
122            public int read() throws java.io.IOException {
123                if (iFlushedChars.length()==0) return iReader.read();
124                char ret=iFlushedChars.charAt(0);
125                iFlushedChars.deleteCharAt(0);
126                return ret;
127            }
128            
129            /** flush (return to stream) a character */
130            public void flush(char ch) {
131                iFlushedChars.insert(0,ch);
132            }
133        }
134        
135        /** Term -- it can contain a text and a content (set of terms) */
136        public static class Term {
137            /** text */
138            private String iText = null;
139            /** content */
140            private Vector iContent = null;
141            
142            public boolean equals(Object o) {
143                if (o==null || !(o instanceof Term)) return false;
144                Term t = (Term)o;
145                if (iText==null && t.iText!=null) return false;
146                if (iText!=null && t.iText==null) return false;
147                if (iText!=null && !iText.equals(t.iText)) return false;
148                if (iContent==null && t.iContent!=null) return false;
149                if (iContent!=null && t.iContent==null) return false;
150                if (iContent!=null && !iContent.equals(t.iContent)) return false;
151                return true;
152            }
153            
154            /** constructor */
155            public Term(String text) {
156                iText = text;
157                iContent = null;
158            }
159            
160            /** constructor */
161            public Term(Vector content) {
162                iText = null;
163                iContent = content;
164            }
165            
166            /** constructor */
167            public Term(String text, Vector content) {
168                iText = text;
169                iContent = content;
170            }
171            
172            /** constructor */
173            public Term(String text, Term[] content) {
174                iText = text;
175                if (content==null) {
176                    iContent = null;
177                } else {
178                    iContent = new Vector();
179                    for (int i=0;i<content.length;i++)
180                        iContent.addElement(content[i]);
181                }
182            }
183            
184            /** constructor */
185            public Term(Term[] content) {
186                this(null,content);
187            }
188            
189            /** return text */
190            public String getText() {
191                return iText;
192            }
193            
194            /** return content */
195            public Vector getContent() {
196                return iContent;
197            }
198            
199            /** content size */
200            public int size() {
201                return (iContent==null?-1:iContent.size());
202            }
203            
204            /** return text as int */
205            public int toInt() {
206                return Integer.parseInt(iText);
207            }
208            
209            /** return text as long */
210            public long toLong() {
211                return Long.parseLong(iText);
212            }
213            
214            /** return text as fouble */
215            public double toDouble() {
216                return Double.parseDouble(iText);
217            }
218            
219            /** return text as boolean */
220            public boolean toBoolean() {
221                return (toInt()!=0);
222            }
223            
224            /** return content as boolean array */
225            public boolean[] toBooleanArray() {
226                if (iContent.size()==1 && iContent.elementAt(0).toString().length()==0) return new boolean[] {};
227                boolean[] ret = new boolean[iContent.size()];
228                for (int i=0;i<ret.length;i++) {
229                    ret[i]=elementAt(i).toBoolean();
230                }
231                return ret;
232            }
233            
234            /** return content as string array */
235            public String[] toStringArray() {
236                if (iContent.size()==1 && iContent.elementAt(0).toString().length()==0) return new String[] {};
237                String[] ret = new String[iContent.size()];
238                for (int i=0;i<ret.length;i++) {
239                    Term t = elementAt(i);
240                    ret[i]=(t.getText().length()>0?t.toString():t.elementAt(0).toString());
241                }
242                return ret;
243            }
244            
245            /** return content as int array */
246            public int[] toIntArray() {
247                //System.err.println("ToIntArray: "+this);
248                if (iContent.size()==1 && iContent.elementAt(0).toString().length()==0) return new int[] {};
249                int[] ret = new int[iContent.size()];
250                for (int i=0;i<ret.length;i++) {
251                    Term t = elementAt(i);
252                    ret[i]=(t.getText().length()>0?Integer.parseInt(t.getText()):t.elementAt(0).toInt());
253                    //System.err.println("  "+i+" .. "+ret[i]);
254                }
255                return ret;
256            }
257            
258            /** idx-th element of content */
259            public Term elementAt(int idx) {
260                try {
261                    return (Term)iContent.elementAt(idx);
262                } catch (Exception e) {
263                    return null;
264                }
265            }
266            
267            /** element of content named name*/
268            public Term element(String name) {
269                try {
270                    for (Enumeration i=iContent.elements();i.hasMoreElements();) {
271                        Term t = (Term)i.nextElement();
272                        if (t.getText()!=null && t.getText().equals(name)) return t;
273                    }
274                    return null;
275                } catch (Exception e) {
276                    return null;
277                }
278            }
279            
280            /** index of element of content named name*/
281            public int indexOf(String name) {
282                try {
283                    int idx=0;
284                    for (Enumeration i=iContent.elements();i.hasMoreElements();) {
285                        Term t = (Term)i.nextElement();
286                        if (t.getText()!=null && t.getText().equals(name)) return idx;
287                        idx++;
288                    }
289                    return -1;
290                } catch (Exception e) {
291                    return -1;
292                }
293            }
294            
295            /** string representation of term */
296            public String toString() {
297                boolean isArray = (iText==null || iText.length()==0);
298                StringBuffer sb = new StringBuffer(isArray?"":iText);
299                if (iContent!=null) {
300                    sb.append(isArray?"[":"(");
301                    for (Enumeration e=iContent.elements();e.hasMoreElements();) {
302                        sb.append(e.nextElement().toString());
303                        sb.append(e.hasMoreElements()?",":"");
304                    }
305                    sb.append(isArray?"]":")");
306                }
307                return sb.toString();
308            }
309            
310            public Object clone() {
311                return new Term(iText==null?null:new String(iText),iContent==null?iContent:(Vector)iContent.clone());
312            }
313        }
314    }