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("\"") && s.endsWith("\"") : 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 public WirthParserTokenManager token_source;
203 SimpleCharStream jj_input_stream;
204 public Token token, jj_nt;
205 private int jj_ntk;
206 private int jj_gen;
207 final private int[] jj_la1 = new int[4];
208 static private int[] jj_la1_0;
209 static {
210 jj_la1_0();
211 }
212 private static void jj_la1_0() {
213 jj_la1_0 = new int[] {0x4,0x2000,0x2a6,0x2a6,};
214 }
215
216 public WirthParser(java.io.InputStream stream) {
217 this(stream, null);
218 }
219 public WirthParser(java.io.InputStream stream, String encoding) {
220 try { jj_input_stream = new SimpleCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
221 token_source = new WirthParserTokenManager(jj_input_stream);
222 token = new Token();
223 jj_ntk = -1;
224 jj_gen = 0;
225 for (int i = 0; i < 4; i++) jj_la1[i] = -1;
226 }
227
228 public void ReInit(java.io.InputStream stream) {
229 ReInit(stream, null);
230 }
231 public void ReInit(java.io.InputStream stream, String encoding) {
232 try { jj_input_stream.ReInit(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
233 token_source.ReInit(jj_input_stream);
234 token = new Token();
235 jj_ntk = -1;
236 jj_gen = 0;
237 for (int i = 0; i < 4; i++) jj_la1[i] = -1;
238 }
239
240 public WirthParser(java.io.Reader stream) {
241 jj_input_stream = new SimpleCharStream(stream, 1, 1);
242 token_source = new WirthParserTokenManager(jj_input_stream);
243 token = new Token();
244 jj_ntk = -1;
245 jj_gen = 0;
246 for (int i = 0; i < 4; i++) jj_la1[i] = -1;
247 }
248
249 public void ReInit(java.io.Reader stream) {
250 jj_input_stream.ReInit(stream, 1, 1);
251 token_source.ReInit(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 public WirthParser(WirthParserTokenManager tm) {
259 token_source = tm;
260 token = new Token();
261 jj_ntk = -1;
262 jj_gen = 0;
263 for (int i = 0; i < 4; i++) jj_la1[i] = -1;
264 }
265
266 public void ReInit(WirthParserTokenManager tm) {
267 token_source = tm;
268 token = new Token();
269 jj_ntk = -1;
270 jj_gen = 0;
271 for (int i = 0; i < 4; i++) jj_la1[i] = -1;
272 }
273
274 final private Token jj_consume_token(int kind) throws ParseException {
275 Token oldToken;
276 if ((oldToken = token).next != null) token = token.next;
277 else token = token.next = token_source.getNextToken();
278 jj_ntk = -1;
279 if (token.kind == kind) {
280 jj_gen++;
281 return token;
282 }
283 token = oldToken;
284 jj_kind = kind;
285 throw generateParseException();
286 }
287
288 final public Token getNextToken() {
289 if (token.next != null) token = token.next;
290 else token = token.next = token_source.getNextToken();
291 jj_ntk = -1;
292 jj_gen++;
293 return token;
294 }
295
296 final public Token getToken(int index) {
297 Token t = token;
298 for (int i = 0; i < index; i++) {
299 if (t.next != null) t = t.next;
300 else t = t.next = token_source.getNextToken();
301 }
302 return t;
303 }
304
305 final private int jj_ntk() {
306 if ((jj_nt=token.next) == null)
307 return (jj_ntk = (token.next=token_source.getNextToken()).kind);
308 else
309 return (jj_ntk = jj_nt.kind);
310 }
311
312 private java.util.Vector jj_expentries = new java.util.Vector();
313 private int[] jj_expentry;
314 private int jj_kind = -1;
315
316 public ParseException generateParseException() {
317 jj_expentries.removeAllElements();
318 boolean[] la1tokens = new boolean[20];
319 for (int i = 0; i < 20; i++) {
320 la1tokens[i] = false;
321 }
322 if (jj_kind >= 0) {
323 la1tokens[jj_kind] = true;
324 jj_kind = -1;
325 }
326 for (int i = 0; i < 4; i++) {
327 if (jj_la1[i] == jj_gen) {
328 for (int j = 0; j < 32; j++) {
329 if ((jj_la1_0[i] & (1<<j)) != 0) {
330 la1tokens[j] = true;
331 }
332 }
333 }
334 }
335 for (int i = 0; i < 20; i++) {
336 if (la1tokens[i]) {
337 jj_expentry = new int[1];
338 jj_expentry[0] = i;
339 jj_expentries.addElement(jj_expentry);
340 }
341 }
342 int[][] exptokseq = new int[jj_expentries.size()][];
343 for (int i = 0; i < jj_expentries.size(); i++) {
344 exptokseq[i] = (int[])jj_expentries.elementAt(i);
345 }
346 return new ParseException(token, exptokseq, tokenImage);
347 }
348
349 final public void enable_tracing() {
350 }
351
352 final public void disable_tracing() {
353 }
354
355 }