View Javadoc

1   package fr.ove.openmath.jome.ctrl.mml;
2   
3   import java.io.*;
4   import java.util.*;
5   
6   import fr.ove.openmath.jome.ctrl.mml.*;
7   
8   /***
9   * A parser for MathML objects.
10  *
11  * @author © 2000 DIRAT Laurent
12  * @version 1.0 25/05/2000
13  */
14  public abstract class BasicXMLParser {
15      private int charRead = -1;
16      private StringBuffer buffer = new StringBuffer();
17      
18      /***
19      * Parse the object coming through the source stream.
20      * @param source the source stream.
21      */
22      public void parse(InputStream source) throws IOException {
23          Tag tag;
24          char c;
25          StringTokenizer tokenizer;
26          
27          while(source.available() != 0) {
28              parseSeparator(source);
29              c = getChar(source);
30              if (c == '<') {
31                  tag = new Tag();
32                  parseSeparator(source);
33                  c = getChar(source);
34                  if (c == '/') { // Closing tag
35                      tag.setIsStart(false);
36                      clearBuffer();
37                      parseSeparator(source);
38                      parseName(source);
39                      tag.setName(buffer.toString());
40                      parseClosing(source);
41                      readTag(tag);
42                  }
43                  else if (isTag(c) || isDigit(c)) {
44                      clearBuffer();
45                      buffer.append(c);
46                      parseName(source);
47                      tag.setName(buffer.toString());
48                      parseSeparator(source);
49                      c = getChar(source);
50                      if (isTag(c) || isDigit(c)) {
51                          while ((c != '>') && (c != '/')) {
52                              Attribute att = new Attribute();
53                              clearBuffer();
54                              buffer.append(c);
55                              parseName(source);
56                              att.setName(buffer.toString());
57                              parseEqual(source);
58                              parseQuote(source);
59                              clearBuffer();
60                              parseName(source);
61                              att.setValue(buffer.toString());
62                              tag.addAttribute(att);
63                              parseQuote(source);
64                              parseSeparator(source);
65                              c = getChar(source);
66                          }
67                          
68                          if (c == '>')
69                              tag.setIsEmpty(false);
70                              
71                          ungetChar(c);
72                          parseClosing(source);    
73                          readTag(tag);
74                      }
75                      else if ((c == '>') || (c == '/')) {
76                          if (c == '>')
77                              tag.setIsEmpty(false);
78                              
79                          ungetChar(c);
80                          parseClosing(source);
81                          readTag(tag);
82                      }
83                      else
84                          System.out.println("Dommage !!!!");
85                  }
86                  else
87                      System.out.println("Dommage !!!!");
88              }
89              else if (isTag(c) || isDigit(c)) {
90                  clearBuffer();
91                  buffer.append(c);
92                  c = getChar(source);
93                  while (c != '<') {
94                      buffer.append(c);
95                      c = getChar(source);
96                  }
97                  ungetChar(c);
98  
99                  readValue(buffer.toString());
100             }
101             else
102                 System.out.println("Dommage !!!!");
103         }
104     }
105     
106     /***
107     * Called by the parser when an tag has been parsed.
108     * @param tag the parsed tag.
109     */
110     public abstract void readTag(Tag tag);
111     
112     /***
113     * Called by the parser when the value of an element has been parsed.
114     * @param vale the parsed value.
115     */
116     public abstract void readValue(String value);
117     
118     
119     /*
120     * Private methods. Internal use.
121     */
122     
123     
124     private void clearBuffer() {
125         buffer = new StringBuffer();
126     }
127     private boolean isTag(char c) {
128         boolean isTag = (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
129         return isTag;
130     }
131 
132     private boolean isDigit(char c) {
133         return (c >= '0') && (c <= '9');
134     }
135 
136     private boolean isHexDigit(char c) {
137         return (c >= '0') && (c <= '9') || (c >= 'A' && c <= 'F')
138                 || (c >= 'a' && c <= 'f');
139     }
140 
141     private final static boolean isSeparator(char c) {
142         return (c == ' ') || (c == '\t') || (c == '\n') || (c == '\r');
143     }
144 
145     private void parseName(InputStream source) throws IOException {
146         char c;
147         
148         c = getChar(source);
149         while (isTag(c) || isDigit(c)) {
150             buffer.append(c);
151             c = getChar(source);
152         }
153         ungetChar(c);
154     }
155 
156     private void parseSeparator(InputStream source) throws IOException {
157         char c;
158 
159         while (true) {
160             c = getChar(source);
161             if ((c != ' ') && (c != '\r') && (c != '\t') && (c != '\n')) {
162                 ungetChar(c);
163                 break;
164             }
165         }
166     }
167 
168     private void parseEqual(InputStream source) throws IOException {
169         char c;
170 
171         parseSeparator(source);
172         c = getChar(source);
173         if (c != '=') {
174             ungetChar(c);
175             // Erreur
176         }
177         parseSeparator(source);
178     }
179 
180     private void parseQuote(InputStream source) throws IOException {
181         char c;
182 
183         c = getChar(source);
184         if (c != '"' && c != '\'') {
185             ungetChar(c);
186             // Erreur
187         }
188     }
189 
190     private void parseClosing(InputStream source) throws IOException {
191         char c;
192 
193         parseSeparator(source);
194         if ((c = getChar(source)) == '>') {
195             return;
196         }
197         else if (c == '/') {
198             parseSeparator(source);
199             if ((c = getChar(source)) == '>') {
200                 return;
201             }
202             else {
203                 ungetChar(c);
204                 // erreur
205             }
206         }
207         else {
208             ungetChar(c);
209             // erreur
210         }
211     }
212 
213     private char getChar(InputStream source) throws IOException {
214         int i;
215 
216         if (charRead == -1) {
217             if ((i = source.read()) < 0) {
218                 throw new IOException("EOF");
219             }
220         }
221         else {
222             i = charRead;
223             charRead = -1;
224         }
225 
226         return (char) i;
227     }
228 
229     private void ungetChar(char c) throws IOException {
230         if (charRead == -1)
231             charRead = (int) c;
232         else
233             throw new IOException("can't unget twice...");
234     }
235 }