001/* 002 * Copyright 2006 - 2013 003 * Stefan Balev <stefan.balev@graphstream-project.org> 004 * Julien Baudry <julien.baudry@graphstream-project.org> 005 * Antoine Dutot <antoine.dutot@graphstream-project.org> 006 * Yoann Pigné <yoann.pigne@graphstream-project.org> 007 * Guilhelm Savin <guilhelm.savin@graphstream-project.org> 008 * 009 * This file is part of GraphStream <http://graphstream-project.org>. 010 * 011 * GraphStream is a library whose purpose is to handle static or dynamic 012 * graph, create them from scratch, file or any source and display them. 013 * 014 * This program is free software distributed under the terms of two licenses, the 015 * CeCILL-C license that fits European law, and the GNU Lesser General Public 016 * License. You can use, modify and/ or redistribute the software under the terms 017 * of the CeCILL-C license as circulated by CEA, CNRS and INRIA at the following 018 * URL <http://www.cecill.info> or under the terms of the GNU LGPL as published by 019 * the Free Software Foundation, either version 3 of the License, or (at your 020 * option) any later version. 021 * 022 * This program is distributed in the hope that it will be useful, but WITHOUT ANY 023 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 024 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 025 * 026 * You should have received a copy of the GNU Lesser General Public License 027 * along with this program. If not, see <http://www.gnu.org/licenses/>. 028 * 029 * The fact that you are presently reading this means that you have had 030 * knowledge of the CeCILL-C and LGPL licenses and that you accept their terms. 031 */ 032package org.graphstream.stream.file.tlp; 033 034import java.io.InputStream; 035import java.io.IOException; 036import java.io.Reader; 037 038import java.util.HashMap; 039import java.util.LinkedList; 040import java.util.Stack; 041 042import org.graphstream.stream.SourceBase.ElementType; 043import org.graphstream.stream.file.FileSourceTLP; 044import org.graphstream.graph.implementations.AbstractElement.AttributeChangeEvent; 045 046import org.graphstream.util.parser.ParseException; 047import org.graphstream.util.parser.Parser; 048import org.graphstream.util.parser.SimpleCharStream; 049import org.graphstream.util.parser.Token; 050import org.graphstream.util.parser.TokenMgrError; 051 052/** 053 * This class defines a TLP parser. 054 */ 055@SuppressWarnings("unused") 056public class TLPParser implements Parser, TLPParserConstants { 057 058 protected static enum PropertyType { 059 BOOL, COLOR, DOUBLE, LAYOUT, INT, SIZE, STRING 060 } 061 062 protected static class Cluster { 063 int index; 064 String name; 065 066 LinkedList<String> nodes; 067 LinkedList<String> edges; 068 069 Cluster(int index, String name) { 070 this.index = index; 071 this.name = name; 072 this.nodes = new LinkedList<String>(); 073 this.edges = new LinkedList<String>(); 074 } 075 } 076 077 /** 078 * The DOT source associated with this parser. 079 */ 080 private FileSourceTLP tlp; 081 082 /** 083 * Id of the parser used in events. 084 */ 085 private String sourceId; 086 087 private Cluster root; 088 private HashMap<Integer, Cluster> clusters; 089 private Stack<Cluster> stack; 090 091 /** 092 * Create a new parser associated with a TLP source from an input stream. 093 */ 094 public TLPParser(FileSourceTLP tlp, InputStream stream) { 095 this(stream); 096 init(tlp); 097 } 098 099 /** 100 * Create a new parser associated with a DOT source from a reader. 101 */ 102 public TLPParser(FileSourceTLP tlp, Reader stream) { 103 this(stream); 104 init(tlp); 105 } 106 107 /** 108 * Closes the parser, closing the opened stream. 109 */ 110 public void close() throws IOException { 111 jj_input_stream.close(); 112 clusters.clear(); 113 } 114 115 private void init(FileSourceTLP tlp) { 116 this.tlp = tlp; 117 this.sourceId = String.format("<DOT stream %x>", System.nanoTime()); 118 119 this.clusters = new HashMap<Integer, Cluster>(); 120 this.stack = new Stack<Cluster>(); 121 122 this.root = new Cluster(0, "<root>"); 123 this.clusters.put(0, this.root); 124 this.stack.push(this.root); 125 } 126 127 private void addNode(String id) throws ParseException { 128 if (stack.size() > 1 129 && (!root.nodes.contains(id) || !stack.get(stack.size() - 2).nodes 130 .contains(id))) 131 throw new ParseException("parent cluster do not contain the node"); 132 133 if (stack.size() == 1) 134 tlp.sendNodeAdded(sourceId, id); 135 136 stack.peek().nodes.add(id); 137 } 138 139 private void addEdge(String id, String source, String target) 140 throws ParseException { 141 if (stack.size() > 1 142 && (!root.edges.contains(id) || !stack.get(stack.size() - 2).edges 143 .contains(id))) 144 throw new ParseException("parent cluster " 145 + stack.get(stack.size() - 2).name 146 + " do not contain the edge"); 147 148 if (stack.size() == 1) 149 tlp.sendEdgeAdded(sourceId, id, source, target, false); 150 151 stack.peek().edges.add(id); 152 } 153 154 private void includeEdge(String id) throws ParseException { 155 if (stack.size() > 1 156 && (!root.edges.contains(id) || !stack.get(stack.size() - 2).edges 157 .contains(id))) 158 throw new ParseException("parent cluster " 159 + stack.get(stack.size() - 2).name 160 + " do not contain the edge"); 161 162 stack.peek().edges.add(id); 163 } 164 165 private void graphAttribute(String key, Object value) { 166 tlp.sendAttributeChangedEvent(sourceId, sourceId, ElementType.GRAPH, 167 key, AttributeChangeEvent.ADD, null, value); 168 } 169 170 private void pushCluster(int i, String name) { 171 Cluster c = new Cluster(i, name); 172 clusters.put(i, c); 173 stack.push(c); 174 } 175 176 private void popCluster() { 177 if (stack.size() > 1) 178 stack.pop(); 179 } 180 181 private void newProperty(Integer cluster, String name, PropertyType type, 182 String nodeDefault, String edgeDefault, 183 HashMap<String, String> nodes, HashMap<String, String> edges) { 184 Object nodeDefaultValue = convert(type, nodeDefault); 185 Object edgeDefaultValue = convert(type, edgeDefault); 186 Cluster c = clusters.get(cluster); 187 188 for (String id : c.nodes) { 189 Object value = nodeDefaultValue; 190 191 if (nodes.containsKey(id)) 192 value = convert(type, nodes.get(id)); 193 194 tlp.sendAttributeChangedEvent(sourceId, id, ElementType.NODE, name, 195 AttributeChangeEvent.ADD, null, value); 196 } 197 198 for (String id : c.edges) { 199 Object value = edgeDefaultValue; 200 201 if (edges.containsKey(id)) 202 value = convert(type, edges.get(id)); 203 204 tlp.sendAttributeChangedEvent(sourceId, id, ElementType.EDGE, name, 205 AttributeChangeEvent.ADD, null, value); 206 } 207 } 208 209 private Object convert(PropertyType type, String value) { 210 switch (type) { 211 case BOOL: 212 return Boolean.valueOf(value); 213 case INT: 214 return Integer.valueOf(value); 215 case DOUBLE: 216 return Double.valueOf(value); 217 case LAYOUT: 218 case COLOR: 219 case SIZE: 220 case STRING: 221 return value; 222 } 223 224 return value; 225 } 226 227 final public void all() throws ParseException { 228 tlp(); 229 label_1: while (true) { 230 switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { 231 case OBRACKET: 232 ; 233 break; 234 default: 235 jj_la1[0] = jj_gen; 236 break label_1; 237 } 238 statement(); 239 } 240 jj_consume_token(CBRACKET); 241 jj_consume_token(0); 242 } 243 244 final public boolean next() throws ParseException { 245 boolean hasMore = false; 246 switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { 247 case OBRACKET: 248 statement(); 249 hasMore = true; 250 break; 251 case 0: 252 jj_consume_token(0); 253 break; 254 default: 255 jj_la1[1] = jj_gen; 256 jj_consume_token(-1); 257 throw new ParseException(); 258 } 259 260 return hasMore; 261 } 262 263 final public void open() throws ParseException { 264 tlp(); 265 } 266 267 final private void tlp() throws ParseException { 268 jj_consume_token(OBRACKET); 269 jj_consume_token(TLP); 270 jj_consume_token(STRING); 271 label_2: while (true) { 272 if (jj_2_1(2)) { 273 ; 274 } else { 275 break label_2; 276 } 277 headers(); 278 } 279 } 280 281 final private void headers() throws ParseException { 282 String s; 283 jj_consume_token(OBRACKET); 284 switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { 285 case DATE: 286 jj_consume_token(DATE); 287 s = string(); 288 graphAttribute("date", s); 289 break; 290 case AUTHOR: 291 jj_consume_token(AUTHOR); 292 s = string(); 293 graphAttribute("author", s); 294 break; 295 case COMMENTS: 296 jj_consume_token(COMMENTS); 297 s = string(); 298 graphAttribute("comments", s); 299 break; 300 default: 301 jj_la1[2] = jj_gen; 302 jj_consume_token(-1); 303 throw new ParseException(); 304 } 305 jj_consume_token(CBRACKET); 306 } 307 308 final private void statement() throws ParseException { 309 if (jj_2_2(2)) { 310 nodes(); 311 } else if (jj_2_3(2)) { 312 edge(); 313 } else if (jj_2_4(2)) { 314 cluster(); 315 } else if (jj_2_5(2)) { 316 property(); 317 } else { 318 jj_consume_token(-1); 319 throw new ParseException(); 320 } 321 } 322 323 final private void nodes() throws ParseException { 324 Token i; 325 jj_consume_token(OBRACKET); 326 jj_consume_token(NODES); 327 label_3: while (true) { 328 switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { 329 case INTEGER: 330 ; 331 break; 332 default: 333 jj_la1[3] = jj_gen; 334 break label_3; 335 } 336 i = jj_consume_token(INTEGER); 337 addNode(i.image); 338 } 339 jj_consume_token(CBRACKET); 340 } 341 342 final private void edge() throws ParseException { 343 Token i, s, t; 344 jj_consume_token(OBRACKET); 345 jj_consume_token(EDGE); 346 i = jj_consume_token(INTEGER); 347 s = jj_consume_token(INTEGER); 348 t = jj_consume_token(INTEGER); 349 jj_consume_token(CBRACKET); 350 addEdge(i.image, s.image, t.image); 351 } 352 353 final private void edges() throws ParseException { 354 Token i; 355 jj_consume_token(OBRACKET); 356 jj_consume_token(EDGES); 357 label_4: while (true) { 358 switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { 359 case INTEGER: 360 ; 361 break; 362 default: 363 jj_la1[4] = jj_gen; 364 break label_4; 365 } 366 i = jj_consume_token(INTEGER); 367 includeEdge(i.image); 368 } 369 jj_consume_token(CBRACKET); 370 } 371 372 final private void cluster() throws ParseException { 373 Token index; 374 String name; 375 jj_consume_token(OBRACKET); 376 jj_consume_token(CLUSTER); 377 index = jj_consume_token(INTEGER); 378 name = string(); 379 pushCluster(Integer.valueOf(index.image), name); 380 nodes(); 381 edges(); 382 label_5: while (true) { 383 switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { 384 case OBRACKET: 385 ; 386 break; 387 default: 388 jj_la1[5] = jj_gen; 389 break label_5; 390 } 391 cluster(); 392 } 393 jj_consume_token(CBRACKET); 394 popCluster(); 395 } 396 397 final private void property() throws ParseException { 398 PropertyType type; 399 Integer cluster; 400 String name; 401 String nodeDefault, edgeDefault; 402 String value; 403 Token t; 404 405 HashMap<String, String> nodes = new HashMap<String, String>(); 406 HashMap<String, String> edges = new HashMap<String, String>(); 407 jj_consume_token(OBRACKET); 408 jj_consume_token(PROPERTY); 409 cluster = integer(); 410 type = type(); 411 name = string(); 412 jj_consume_token(OBRACKET); 413 jj_consume_token(DEF); 414 nodeDefault = string(); 415 edgeDefault = string(); 416 jj_consume_token(CBRACKET); 417 label_6: while (true) { 418 switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { 419 case OBRACKET: 420 ; 421 break; 422 default: 423 jj_la1[6] = jj_gen; 424 break label_6; 425 } 426 jj_consume_token(OBRACKET); 427 switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { 428 case NODE: 429 jj_consume_token(NODE); 430 t = jj_consume_token(INTEGER); 431 value = string(); 432 nodes.put(t.image, value); 433 break; 434 case EDGE: 435 jj_consume_token(EDGE); 436 t = jj_consume_token(INTEGER); 437 value = string(); 438 edges.put(t.image, value); 439 break; 440 default: 441 jj_la1[7] = jj_gen; 442 jj_consume_token(-1); 443 throw new ParseException(); 444 } 445 jj_consume_token(CBRACKET); 446 } 447 jj_consume_token(CBRACKET); 448 newProperty(cluster, name, type, nodeDefault, edgeDefault, nodes, edges); 449 } 450 451 final private PropertyType type() throws ParseException { 452 Token t; 453 t = jj_consume_token(PTYPE); 454 455 return PropertyType.valueOf(t.image.toUpperCase()); 456 } 457 458 final private String string() throws ParseException { 459 Token t; 460 t = jj_consume_token(STRING); 461 462 return t.image.substring(1, t.image.length() - 1); 463 } 464 465 final private Integer integer() throws ParseException { 466 Token t; 467 t = jj_consume_token(INTEGER); 468 469 return Integer.valueOf(t.image); 470 } 471 472 private boolean jj_2_1(int xla) { 473 jj_la = xla; 474 jj_lastpos = jj_scanpos = token; 475 try { 476 return !jj_3_1(); 477 } catch (LookaheadSuccess ls) { 478 return true; 479 } finally { 480 jj_save(0, xla); 481 } 482 } 483 484 private boolean jj_2_2(int xla) { 485 jj_la = xla; 486 jj_lastpos = jj_scanpos = token; 487 try { 488 return !jj_3_2(); 489 } catch (LookaheadSuccess ls) { 490 return true; 491 } finally { 492 jj_save(1, xla); 493 } 494 } 495 496 private boolean jj_2_3(int xla) { 497 jj_la = xla; 498 jj_lastpos = jj_scanpos = token; 499 try { 500 return !jj_3_3(); 501 } catch (LookaheadSuccess ls) { 502 return true; 503 } finally { 504 jj_save(2, xla); 505 } 506 } 507 508 private boolean jj_2_4(int xla) { 509 jj_la = xla; 510 jj_lastpos = jj_scanpos = token; 511 try { 512 return !jj_3_4(); 513 } catch (LookaheadSuccess ls) { 514 return true; 515 } finally { 516 jj_save(3, xla); 517 } 518 } 519 520 private boolean jj_2_5(int xla) { 521 jj_la = xla; 522 jj_lastpos = jj_scanpos = token; 523 try { 524 return !jj_3_5(); 525 } catch (LookaheadSuccess ls) { 526 return true; 527 } finally { 528 jj_save(4, xla); 529 } 530 } 531 532 private boolean jj_3_1() { 533 if (jj_3R_7()) 534 return true; 535 return false; 536 } 537 538 private boolean jj_3_5() { 539 if (jj_3R_11()) 540 return true; 541 return false; 542 } 543 544 private boolean jj_3R_9() { 545 if (jj_scan_token(OBRACKET)) 546 return true; 547 if (jj_scan_token(EDGE)) 548 return true; 549 return false; 550 } 551 552 private boolean jj_3_4() { 553 if (jj_3R_10()) 554 return true; 555 return false; 556 } 557 558 private boolean jj_3_3() { 559 if (jj_3R_9()) 560 return true; 561 return false; 562 } 563 564 private boolean jj_3R_14() { 565 if (jj_scan_token(COMMENTS)) 566 return true; 567 return false; 568 } 569 570 private boolean jj_3R_13() { 571 if (jj_scan_token(AUTHOR)) 572 return true; 573 return false; 574 } 575 576 private boolean jj_3_2() { 577 if (jj_3R_8()) 578 return true; 579 return false; 580 } 581 582 private boolean jj_3R_12() { 583 if (jj_scan_token(DATE)) 584 return true; 585 return false; 586 } 587 588 private boolean jj_3R_11() { 589 if (jj_scan_token(OBRACKET)) 590 return true; 591 if (jj_scan_token(PROPERTY)) 592 return true; 593 return false; 594 } 595 596 private boolean jj_3R_10() { 597 if (jj_scan_token(OBRACKET)) 598 return true; 599 if (jj_scan_token(CLUSTER)) 600 return true; 601 return false; 602 } 603 604 private boolean jj_3R_7() { 605 if (jj_scan_token(OBRACKET)) 606 return true; 607 Token xsp; 608 xsp = jj_scanpos; 609 if (jj_3R_12()) { 610 jj_scanpos = xsp; 611 if (jj_3R_13()) { 612 jj_scanpos = xsp; 613 if (jj_3R_14()) 614 return true; 615 } 616 } 617 return false; 618 } 619 620 private boolean jj_3R_8() { 621 if (jj_scan_token(OBRACKET)) 622 return true; 623 if (jj_scan_token(NODES)) 624 return true; 625 return false; 626 } 627 628 /** Generated Token Manager. */ 629 public TLPParserTokenManager token_source; 630 SimpleCharStream jj_input_stream; 631 /** Current token. */ 632 public Token token; 633 /** Next token. */ 634 public Token jj_nt; 635 private int jj_ntk; 636 private Token jj_scanpos, jj_lastpos; 637 private int jj_la; 638 private int jj_gen; 639 final private int[] jj_la1 = new int[8]; 640 static private int[] jj_la1_0; 641 static { 642 jj_la1_init_0(); 643 } 644 645 private static void jj_la1_init_0() { 646 jj_la1_0 = new int[] { 0x400, 0x401, 0x380000, 0x1000000, 0x1000000, 647 0x400, 0x400, 0x14000, }; 648 } 649 650 final private JJCalls[] jj_2_rtns = new JJCalls[5]; 651 private boolean jj_rescan = false; 652 private int jj_gc = 0; 653 654 /** Constructor with InputStream. */ 655 public TLPParser(java.io.InputStream stream) { 656 this(stream, null); 657 } 658 659 /** Constructor with InputStream and supplied encoding */ 660 public TLPParser(java.io.InputStream stream, String encoding) { 661 try { 662 jj_input_stream = new SimpleCharStream(stream, encoding, 1, 1); 663 } catch (java.io.UnsupportedEncodingException e) { 664 throw new RuntimeException(e); 665 } 666 token_source = new TLPParserTokenManager(jj_input_stream); 667 token = new Token(); 668 jj_ntk = -1; 669 jj_gen = 0; 670 for (int i = 0; i < 8; i++) 671 jj_la1[i] = -1; 672 for (int i = 0; i < jj_2_rtns.length; i++) 673 jj_2_rtns[i] = new JJCalls(); 674 } 675 676 /** Reinitialise. */ 677 public void ReInit(java.io.InputStream stream) { 678 ReInit(stream, null); 679 } 680 681 /** Reinitialise. */ 682 public void ReInit(java.io.InputStream stream, String encoding) { 683 try { 684 jj_input_stream.ReInit(stream, encoding, 1, 1); 685 } catch (java.io.UnsupportedEncodingException e) { 686 throw new RuntimeException(e); 687 } 688 token_source.ReInit(jj_input_stream); 689 token = new Token(); 690 jj_ntk = -1; 691 jj_gen = 0; 692 for (int i = 0; i < 8; i++) 693 jj_la1[i] = -1; 694 for (int i = 0; i < jj_2_rtns.length; i++) 695 jj_2_rtns[i] = new JJCalls(); 696 } 697 698 /** Constructor. */ 699 public TLPParser(java.io.Reader stream) { 700 jj_input_stream = new SimpleCharStream(stream, 1, 1); 701 token_source = new TLPParserTokenManager(jj_input_stream); 702 token = new Token(); 703 jj_ntk = -1; 704 jj_gen = 0; 705 for (int i = 0; i < 8; i++) 706 jj_la1[i] = -1; 707 for (int i = 0; i < jj_2_rtns.length; i++) 708 jj_2_rtns[i] = new JJCalls(); 709 } 710 711 /** Reinitialise. */ 712 public void ReInit(java.io.Reader stream) { 713 jj_input_stream.ReInit(stream, 1, 1); 714 token_source.ReInit(jj_input_stream); 715 token = new Token(); 716 jj_ntk = -1; 717 jj_gen = 0; 718 for (int i = 0; i < 8; i++) 719 jj_la1[i] = -1; 720 for (int i = 0; i < jj_2_rtns.length; i++) 721 jj_2_rtns[i] = new JJCalls(); 722 } 723 724 /** Constructor with generated Token Manager. */ 725 public TLPParser(TLPParserTokenManager tm) { 726 token_source = tm; 727 token = new Token(); 728 jj_ntk = -1; 729 jj_gen = 0; 730 for (int i = 0; i < 8; i++) 731 jj_la1[i] = -1; 732 for (int i = 0; i < jj_2_rtns.length; i++) 733 jj_2_rtns[i] = new JJCalls(); 734 } 735 736 /** Reinitialise. */ 737 public void ReInit(TLPParserTokenManager tm) { 738 token_source = tm; 739 token = new Token(); 740 jj_ntk = -1; 741 jj_gen = 0; 742 for (int i = 0; i < 8; i++) 743 jj_la1[i] = -1; 744 for (int i = 0; i < jj_2_rtns.length; i++) 745 jj_2_rtns[i] = new JJCalls(); 746 } 747 748 private Token jj_consume_token(int kind) throws ParseException { 749 Token oldToken; 750 if ((oldToken = token).next != null) 751 token = token.next; 752 else 753 token = token.next = token_source.getNextToken(); 754 jj_ntk = -1; 755 if (token.kind == kind) { 756 jj_gen++; 757 if (++jj_gc > 100) { 758 jj_gc = 0; 759 for (int i = 0; i < jj_2_rtns.length; i++) { 760 JJCalls c = jj_2_rtns[i]; 761 while (c != null) { 762 if (c.gen < jj_gen) 763 c.first = null; 764 c = c.next; 765 } 766 } 767 } 768 return token; 769 } 770 token = oldToken; 771 jj_kind = kind; 772 throw generateParseException(); 773 } 774 775 static private final class LookaheadSuccess extends java.lang.Error { 776 private static final long serialVersionUID = -7986896058452164869L; 777 } 778 779 final private LookaheadSuccess jj_ls = new LookaheadSuccess(); 780 781 private boolean jj_scan_token(int kind) { 782 if (jj_scanpos == jj_lastpos) { 783 jj_la--; 784 if (jj_scanpos.next == null) { 785 jj_lastpos = jj_scanpos = jj_scanpos.next = token_source 786 .getNextToken(); 787 } else { 788 jj_lastpos = jj_scanpos = jj_scanpos.next; 789 } 790 } else { 791 jj_scanpos = jj_scanpos.next; 792 } 793 if (jj_rescan) { 794 int i = 0; 795 Token tok = token; 796 while (tok != null && tok != jj_scanpos) { 797 i++; 798 tok = tok.next; 799 } 800 if (tok != null) 801 jj_add_error_token(kind, i); 802 } 803 if (jj_scanpos.kind != kind) 804 return true; 805 if (jj_la == 0 && jj_scanpos == jj_lastpos) 806 throw jj_ls; 807 return false; 808 } 809 810 /** Get the next Token. */ 811 final public Token getNextToken() { 812 if (token.next != null) 813 token = token.next; 814 else 815 token = token.next = token_source.getNextToken(); 816 jj_ntk = -1; 817 jj_gen++; 818 return token; 819 } 820 821 /** Get the specific Token. */ 822 final public Token getToken(int index) { 823 Token t = token; 824 for (int i = 0; i < index; i++) { 825 if (t.next != null) 826 t = t.next; 827 else 828 t = t.next = token_source.getNextToken(); 829 } 830 return t; 831 } 832 833 private int jj_ntk() { 834 if ((jj_nt = token.next) == null) 835 return (jj_ntk = (token.next = token_source.getNextToken()).kind); 836 else 837 return (jj_ntk = jj_nt.kind); 838 } 839 840 private java.util.List<int[]> jj_expentries = new java.util.ArrayList<int[]>(); 841 private int[] jj_expentry; 842 private int jj_kind = -1; 843 private int[] jj_lasttokens = new int[100]; 844 private int jj_endpos; 845 846 private void jj_add_error_token(int kind, int pos) { 847 if (pos >= 100) 848 return; 849 if (pos == jj_endpos + 1) { 850 jj_lasttokens[jj_endpos++] = kind; 851 } else if (jj_endpos != 0) { 852 jj_expentry = new int[jj_endpos]; 853 for (int i = 0; i < jj_endpos; i++) { 854 jj_expentry[i] = jj_lasttokens[i]; 855 } 856 jj_entries_loop: for (java.util.Iterator<?> it = jj_expentries 857 .iterator(); it.hasNext();) { 858 int[] oldentry = (int[]) (it.next()); 859 if (oldentry.length == jj_expentry.length) { 860 for (int i = 0; i < jj_expentry.length; i++) { 861 if (oldentry[i] != jj_expentry[i]) { 862 continue jj_entries_loop; 863 } 864 } 865 jj_expentries.add(jj_expentry); 866 break jj_entries_loop; 867 } 868 } 869 if (pos != 0) 870 jj_lasttokens[(jj_endpos = pos) - 1] = kind; 871 } 872 } 873 874 /** Generate ParseException. */ 875 public ParseException generateParseException() { 876 jj_expentries.clear(); 877 boolean[] la1tokens = new boolean[28]; 878 if (jj_kind >= 0) { 879 la1tokens[jj_kind] = true; 880 jj_kind = -1; 881 } 882 for (int i = 0; i < 8; i++) { 883 if (jj_la1[i] == jj_gen) { 884 for (int j = 0; j < 32; j++) { 885 if ((jj_la1_0[i] & (1 << j)) != 0) { 886 la1tokens[j] = true; 887 } 888 } 889 } 890 } 891 for (int i = 0; i < 28; i++) { 892 if (la1tokens[i]) { 893 jj_expentry = new int[1]; 894 jj_expentry[0] = i; 895 jj_expentries.add(jj_expentry); 896 } 897 } 898 jj_endpos = 0; 899 jj_rescan_token(); 900 jj_add_error_token(0, 0); 901 int[][] exptokseq = new int[jj_expentries.size()][]; 902 for (int i = 0; i < jj_expentries.size(); i++) { 903 exptokseq[i] = jj_expentries.get(i); 904 } 905 return new ParseException(token, exptokseq, tokenImage); 906 } 907 908 /** Enable tracing. */ 909 final public void enable_tracing() { 910 } 911 912 /** Disable tracing. */ 913 final public void disable_tracing() { 914 } 915 916 private void jj_rescan_token() { 917 jj_rescan = true; 918 for (int i = 0; i < 5; i++) { 919 try { 920 JJCalls p = jj_2_rtns[i]; 921 do { 922 if (p.gen > jj_gen) { 923 jj_la = p.arg; 924 jj_lastpos = jj_scanpos = p.first; 925 switch (i) { 926 case 0: 927 jj_3_1(); 928 break; 929 case 1: 930 jj_3_2(); 931 break; 932 case 2: 933 jj_3_3(); 934 break; 935 case 3: 936 jj_3_4(); 937 break; 938 case 4: 939 jj_3_5(); 940 break; 941 } 942 } 943 p = p.next; 944 } while (p != null); 945 } catch (LookaheadSuccess ls) { 946 } 947 } 948 jj_rescan = false; 949 } 950 951 private void jj_save(int index, int xla) { 952 JJCalls p = jj_2_rtns[index]; 953 while (p.gen > jj_gen) { 954 if (p.next == null) { 955 p = p.next = new JJCalls(); 956 break; 957 } 958 p = p.next; 959 } 960 p.gen = jj_gen + xla - jj_la; 961 p.first = token; 962 p.arg = xla; 963 } 964 965 static final class JJCalls { 966 int gen; 967 Token first; 968 int arg; 969 JJCalls next; 970 } 971 972}