001/* Generated By:JavaCC: Do not edit this line. WirthParser.java */
002package net.hydromatic.clapham.parser.wirth;
003
004import java.util.*;
005import 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 */
016public 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/*
032Example:
033
034Wirth's BNF:
035
036SYNTAX     = { PRODUCTION } .
037PRODUCTION = IDENTIFIER "=" EXPRESSION "." .
038EXPRESSION = TERM { "|" TERM } .
039TERM       = FACTOR { FACTOR } .
040FACTOR     = IDENTIFIER
041           | LITERAL
042           | "[" EXPRESSION "]"
043           | "(" EXPRESSION ")"
044           | "{" EXPRESSION "}" .
045IDENTIFIER = letter { letter } .
046LITERAL    = """" 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}