001 /* Generated By:JavaCC: Do not edit this line. WirthParser.java */
002 package net.hydromatic.clapham.parser.wirth;
003
004 import java.util.*;
005 import net.hydromatic.clapham.parser.*;
006
007 /**
008 * Parser for grammars in Wirth Syntax Notation.
009 *
010 * <p><a href="http://en.wikipedia.org/wiki/Wirth_syntax_notation">Wirth Syntax
011 * Notation</a> (WSN) is an alternative to Backus-Naur Form.
012 *
013 * @author Julian Hyde
014 * @version $Id: WirthParser.jj 3 2009-05-11 08:11:57Z jhyde $
015 */
016 public class WirthParser implements WirthParserConstants {
017 public static <E extends EbnfNode> void toString(
018 StringBuilder buf, String start, List<E> list, String end)
019 {
020 int i = 0;
021 buf.append(start);
022 for (E node : list) {
023 if (i++ > 0) {
024 buf.append(", ");
025 }
026 node.toString(buf);
027 }
028 buf.append(end);
029 }
030
031 /*
032 Example:
033
034 Wirth's BNF:
035
036 SYNTAX = { PRODUCTION } .
037 PRODUCTION = IDENTIFIER "=" EXPRESSION "." .
038 EXPRESSION = TERM { "|" TERM } .
039 TERM = FACTOR { FACTOR } .
040 FACTOR = IDENTIFIER
041 | LITERAL
042 | "[" EXPRESSION "]"
043 | "(" EXPRESSION ")"
044 | "{" EXPRESSION "}" .
045 IDENTIFIER = letter { letter } .
046 LITERAL = """" character { character } """" .
047 */
048
049 /*****************************************
050 * Syntactical Descriptions *
051 *****************************************/
052
053 // SYNTAX = { PRODUCTION } .
054 final public List<ProductionNode> Syntax() throws ParseException {
055 List<ProductionNode> list = new ArrayList<ProductionNode>();
056 ProductionNode p;
057 label_1:
058 while (true) {
059 switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
060 case IDENTIFIER:
061 ;
062 break;
063 default:
064 jj_la1[0] = jj_gen;
065 break label_1;
066 }
067 p = Production();
068 list.add(p);
069 }
070 {if (true) return list;}
071 throw new Error("Missing return statement in function");
072 }
073
074 // PRODUCTION = IDENTIFIER "=" EXPRESSION "." .
075 final public ProductionNode Production() throws ParseException {
076 IdentifierNode id;
077 EbnfNode expression;
078 id = Identifier();
079 jj_consume_token(EQ);
080 expression = Expression();
081 jj_consume_token(DOT);
082 {if (true) return new ProductionNode(id, expression);}
083 throw new Error("Missing return statement in function");
084 }
085
086 // EXPRESSION = TERM { "|" TERM } .
087 final public EbnfNode Expression() throws ParseException {
088 List<EbnfNode> list = new ArrayList<EbnfNode>();
089 EbnfNode n;
090 n = Term();
091 list.add(n);
092 label_2:
093 while (true) {
094 switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
095 case BAR:
096 ;
097 break;
098 default:
099 jj_la1[1] = jj_gen;
100 break label_2;
101 }
102 jj_consume_token(BAR);
103 n = Term();
104 list.add(n);
105 }
106 if (list.size() == 1) {
107 {if (true) return list.get(0);}
108 } else {
109 {if (true) return new AlternateNode(list);}
110 }
111 throw new Error("Missing return statement in function");
112 }
113
114 // TERM = FACTOR { FACTOR } .
115 final public EbnfNode Term() throws ParseException {
116 List<EbnfNode> list = new ArrayList<EbnfNode>();
117 EbnfNode n;
118 n = Factor();
119 list.add(n);
120 label_3:
121 while (true) {
122 switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
123 case LITERAL:
124 case IDENTIFIER:
125 case LPAREN:
126 case LBRACE:
127 case LBRACKET:
128 ;
129 break;
130 default:
131 jj_la1[2] = jj_gen;
132 break label_3;
133 }
134 n = Factor();
135 list.add(n);
136 }
137 if (list.size() == 1) {
138 {if (true) return list.get(0);}
139 } else {
140 {if (true) return new SequenceNode(list);}
141 }
142 throw new Error("Missing return statement in function");
143 }
144
145 // FACTOR = IDENTIFIER
146 // | LITERAL
147 // | "[" EXPRESSION "]"
148 // | "(" EXPRESSION ")"
149 // | "{" EXPRESSION "}" .
150 final public EbnfNode Factor() throws ParseException {
151 EbnfNode n;
152 switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
153 case IDENTIFIER:
154 n = Identifier();
155 break;
156 case LITERAL:
157 n = Literal();
158 break;
159 case LBRACKET:
160 jj_consume_token(LBRACKET);
161 n = Expression();
162 jj_consume_token(RBRACKET);
163 n = new OptionNode(n);
164 break;
165 case LPAREN:
166 jj_consume_token(LPAREN);
167 n = Expression();
168 jj_consume_token(RPAREN);
169 break;
170 case LBRACE:
171 jj_consume_token(LBRACE);
172 n = Expression();
173 jj_consume_token(RBRACE);
174 n = new RepeatNode(n);
175 break;
176 default:
177 jj_la1[3] = jj_gen;
178 jj_consume_token(-1);
179 throw new ParseException();
180 }
181 {if (true) return n;}
182 throw new Error("Missing return statement in function");
183 }
184
185 // IDENTIFIER = letter { letter } .
186 final public IdentifierNode Identifier() throws ParseException {
187 String s;
188 s = jj_consume_token(IDENTIFIER).image;
189 {if (true) return new IdentifierNode(s);}
190 throw new Error("Missing return statement in function");
191 }
192
193 // LITERAL = """" character { character } """" .
194 final public LiteralNode Literal() throws ParseException {
195 String s;
196 s = jj_consume_token(LITERAL).image;
197 assert s.startsWith("\u005c"") && s.endsWith("\u005c"") : s;
198 {if (true) return new LiteralNode(s.substring(1, s.length() - 1));}
199 throw new Error("Missing return statement in function");
200 }
201
202 /** Generated Token Manager. */
203 public WirthParserTokenManager token_source;
204 SimpleCharStream jj_input_stream;
205 /** Current token. */
206 public Token token;
207 /** Next token. */
208 public Token jj_nt;
209 private int jj_ntk;
210 private int jj_gen;
211 final private int[] jj_la1 = new int[4];
212 static private int[] jj_la1_0;
213 static {
214 jj_la1_init_0();
215 }
216 private static void jj_la1_init_0() {
217 jj_la1_0 = new int[] {0x4,0x2000,0x2a6,0x2a6,};
218 }
219
220 /** Constructor with InputStream. */
221 public WirthParser(java.io.InputStream stream) {
222 this(stream, null);
223 }
224 /** Constructor with InputStream and supplied encoding */
225 public WirthParser(java.io.InputStream stream, String encoding) {
226 try { jj_input_stream = new SimpleCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
227 token_source = new WirthParserTokenManager(jj_input_stream);
228 token = new Token();
229 jj_ntk = -1;
230 jj_gen = 0;
231 for (int i = 0; i < 4; i++) jj_la1[i] = -1;
232 }
233
234 /** Reinitialise. */
235 public void ReInit(java.io.InputStream stream) {
236 ReInit(stream, null);
237 }
238 /** Reinitialise. */
239 public void ReInit(java.io.InputStream stream, String encoding) {
240 try { jj_input_stream.ReInit(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
241 token_source.ReInit(jj_input_stream);
242 token = new Token();
243 jj_ntk = -1;
244 jj_gen = 0;
245 for (int i = 0; i < 4; i++) jj_la1[i] = -1;
246 }
247
248 /** Constructor. */
249 public WirthParser(java.io.Reader stream) {
250 jj_input_stream = new SimpleCharStream(stream, 1, 1);
251 token_source = new WirthParserTokenManager(jj_input_stream);
252 token = new Token();
253 jj_ntk = -1;
254 jj_gen = 0;
255 for (int i = 0; i < 4; i++) jj_la1[i] = -1;
256 }
257
258 /** Reinitialise. */
259 public void ReInit(java.io.Reader stream) {
260 jj_input_stream.ReInit(stream, 1, 1);
261 token_source.ReInit(jj_input_stream);
262 token = new Token();
263 jj_ntk = -1;
264 jj_gen = 0;
265 for (int i = 0; i < 4; i++) jj_la1[i] = -1;
266 }
267
268 /** Constructor with generated Token Manager. */
269 public WirthParser(WirthParserTokenManager tm) {
270 token_source = tm;
271 token = new Token();
272 jj_ntk = -1;
273 jj_gen = 0;
274 for (int i = 0; i < 4; i++) jj_la1[i] = -1;
275 }
276
277 /** Reinitialise. */
278 public void ReInit(WirthParserTokenManager tm) {
279 token_source = tm;
280 token = new Token();
281 jj_ntk = -1;
282 jj_gen = 0;
283 for (int i = 0; i < 4; i++) jj_la1[i] = -1;
284 }
285
286 private Token jj_consume_token(int kind) throws ParseException {
287 Token oldToken;
288 if ((oldToken = token).next != null) token = token.next;
289 else token = token.next = token_source.getNextToken();
290 jj_ntk = -1;
291 if (token.kind == kind) {
292 jj_gen++;
293 return token;
294 }
295 token = oldToken;
296 jj_kind = kind;
297 throw generateParseException();
298 }
299
300
301 /** Get the next Token. */
302 final public Token getNextToken() {
303 if (token.next != null) token = token.next;
304 else token = token.next = token_source.getNextToken();
305 jj_ntk = -1;
306 jj_gen++;
307 return token;
308 }
309
310 /** Get the specific Token. */
311 final public Token getToken(int index) {
312 Token t = token;
313 for (int i = 0; i < index; i++) {
314 if (t.next != null) t = t.next;
315 else t = t.next = token_source.getNextToken();
316 }
317 return t;
318 }
319
320 private int jj_ntk() {
321 if ((jj_nt=token.next) == null)
322 return (jj_ntk = (token.next=token_source.getNextToken()).kind);
323 else
324 return (jj_ntk = jj_nt.kind);
325 }
326
327 private java.util.List<int[]> jj_expentries = new java.util.ArrayList<int[]>();
328 private int[] jj_expentry;
329 private int jj_kind = -1;
330
331 /** Generate ParseException. */
332 public ParseException generateParseException() {
333 jj_expentries.clear();
334 boolean[] la1tokens = new boolean[20];
335 if (jj_kind >= 0) {
336 la1tokens[jj_kind] = true;
337 jj_kind = -1;
338 }
339 for (int i = 0; i < 4; i++) {
340 if (jj_la1[i] == jj_gen) {
341 for (int j = 0; j < 32; j++) {
342 if ((jj_la1_0[i] & (1<<j)) != 0) {
343 la1tokens[j] = true;
344 }
345 }
346 }
347 }
348 for (int i = 0; i < 20; i++) {
349 if (la1tokens[i]) {
350 jj_expentry = new int[1];
351 jj_expentry[0] = i;
352 jj_expentries.add(jj_expentry);
353 }
354 }
355 int[][] exptokseq = new int[jj_expentries.size()][];
356 for (int i = 0; i < jj_expentries.size(); i++) {
357 exptokseq[i] = jj_expentries.get(i);
358 }
359 return new ParseException(token, exptokseq, tokenImage);
360 }
361
362 /** Enable tracing. */
363 final public void enable_tracing() {
364 }
365
366 /** Disable tracing. */
367 final public void disable_tracing() {
368 }
369
370 }