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 == '/') {
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
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
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
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
205 }
206 }
207 else {
208 ungetChar(c);
209
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 }