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}