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 }