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}