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