1 61 62 63 package org.jaxen.saxpath.base; 64 65 import java.util.LinkedList ; 66 67 import org.jaxen.saxpath.Axis; 68 import org.jaxen.saxpath.Operator; 69 import org.jaxen.saxpath.SAXPathException; 70 import org.jaxen.saxpath.XPathHandler; 71 import org.jaxen.saxpath.XPathSyntaxException; 72 import org.jaxen.saxpath.helpers.DefaultXPathHandler; 73 74 79 public class XPathReader implements org.jaxen.saxpath.XPathReader 80 { 81 private LinkedList tokens; 82 private XPathLexer lexer; 83 84 private XPathHandler handler; 85 86 private static XPathHandler defaultHandler = new DefaultXPathHandler(); 87 88 92 public XPathReader() 93 { 94 setXPathHandler( defaultHandler ); 95 } 96 97 public void setXPathHandler(XPathHandler handler) 98 { 99 this.handler = handler; 100 } 101 102 public XPathHandler getXPathHandler() 103 { 104 return this.handler; 105 } 106 107 public void parse(String xpath) throws SAXPathException 108 { 109 setUpParse( xpath ); 110 111 getXPathHandler().startXPath(); 112 113 expr(); 114 115 getXPathHandler().endXPath(); 116 117 if ( LA(1) != TokenTypes.EOF ) 118 { 119 throwUnexpected(); 120 } 121 122 lexer = null; 123 tokens = null; 124 } 125 126 void setUpParse(String xpath) 127 { 128 this.tokens = new LinkedList (); 129 this.lexer = new XPathLexer( xpath ); 130 } 131 132 private void pathExpr() throws SAXPathException 133 { 134 getXPathHandler().startPathExpr(); 135 136 switch ( LA(1) ) 137 { 138 case TokenTypes.INTEGER: 139 case TokenTypes.DOUBLE: 140 case TokenTypes.LITERAL: 141 { 142 filterExpr(); 143 144 if ( LA(1) == TokenTypes.SLASH || LA(1) == TokenTypes.DOUBLE_SLASH ) 145 { 146 XPathSyntaxException ex = this.createSyntaxException("Node-set expected"); 147 throw ex; 148 } 149 150 break; 151 } 152 case TokenTypes.LEFT_PAREN: 153 case TokenTypes.DOLLAR: 154 { 155 filterExpr(); 156 157 if ( LA(1) == TokenTypes.SLASH || LA(1) == TokenTypes.DOUBLE_SLASH) 158 { 159 locationPath( false ); 160 } 161 break; 162 } 163 case TokenTypes.IDENTIFIER: 164 { 165 166 if ( ( LA(2) == TokenTypes.LEFT_PAREN 167 && 168 ! isNodeTypeName( LT(1) ) ) 169 || 170 ( LA(2) == TokenTypes.COLON 171 && 172 LA(4) == TokenTypes.LEFT_PAREN) ) 173 { 174 filterExpr(); 175 176 if ( LA(1) == TokenTypes.SLASH || LA(1) == TokenTypes.DOUBLE_SLASH) 177 { 178 locationPath( false ); 179 } 180 } 181 else 182 { 183 locationPath( false ); 184 } 185 break; 186 } 187 case TokenTypes.DOT: 188 case TokenTypes.DOT_DOT: 189 case TokenTypes.STAR: 190 case TokenTypes.AT: 191 { 192 locationPath( false ); 193 break; 194 } 195 case TokenTypes.SLASH: 196 case TokenTypes.DOUBLE_SLASH: 197 { 198 locationPath( true ); 199 break; 200 } 201 default: 202 { 203 throwUnexpected(); 204 } 205 } 206 207 getXPathHandler().endPathExpr(); 208 } 209 210 private void numberDouble() throws SAXPathException 211 { 212 Token token = match( TokenTypes.DOUBLE ); 213 214 getXPathHandler().number( Double.parseDouble( token.getTokenText() ) ); 215 } 216 217 private void numberInteger() throws SAXPathException 218 { 219 Token token = match( TokenTypes.INTEGER ); 220 221 String text = token.getTokenText(); 222 try { 223 getXPathHandler().number( Integer.parseInt( text ) ); 224 } 225 catch (NumberFormatException ex) { 226 getXPathHandler().number( Double.parseDouble( text ) ); 227 } 228 229 } 230 231 private void literal() throws SAXPathException 232 { 233 Token token = match( TokenTypes.LITERAL ); 234 235 getXPathHandler().literal( token.getTokenText() ); 236 } 237 238 private void functionCall() throws SAXPathException 239 { 240 String prefix = null; 241 String functionName = null; 242 243 if ( LA(2) == TokenTypes.COLON ) 244 { 245 prefix = match( TokenTypes.IDENTIFIER ).getTokenText(); 246 match( TokenTypes.COLON ); 247 } 248 else 249 { 250 prefix = ""; 251 } 252 253 functionName = match( TokenTypes.IDENTIFIER ).getTokenText(); 254 255 getXPathHandler().startFunction( prefix, 256 functionName ); 257 258 match ( TokenTypes.LEFT_PAREN ); 259 260 arguments(); 261 262 match ( TokenTypes.RIGHT_PAREN ); 263 264 getXPathHandler().endFunction(); 265 } 266 267 private void arguments() throws SAXPathException 268 { 269 while ( LA(1) != TokenTypes.RIGHT_PAREN ) 270 { 271 expr(); 272 273 if ( LA(1) == TokenTypes.COMMA ) 274 { 275 match( TokenTypes.COMMA ); 276 } 277 else 278 { 279 break; 280 } 281 } 282 } 283 284 private void filterExpr() throws SAXPathException 285 { 286 287 getXPathHandler().startFilterExpr(); 288 289 switch ( LA(1) ) 290 { 291 case TokenTypes.INTEGER: 292 { 293 numberInteger(); 294 break; 295 } 296 case TokenTypes.DOUBLE: 297 { 298 numberDouble(); 299 break; 300 } 301 case TokenTypes.LITERAL: 302 { 303 literal(); 304 break; 305 } 306 case TokenTypes.LEFT_PAREN: 307 { 308 match( TokenTypes.LEFT_PAREN ); 309 expr(); 310 match( TokenTypes.RIGHT_PAREN ); 311 break; 312 } 313 case TokenTypes.IDENTIFIER: 314 { 315 functionCall(); 316 break; 317 } 318 case TokenTypes.DOLLAR: 319 { 320 variableReference(); 321 break; 322 } 323 } 324 325 predicates(); 326 327 getXPathHandler().endFilterExpr(); 328 } 329 330 private void variableReference() throws SAXPathException 331 { 332 match( TokenTypes.DOLLAR ); 333 334 String prefix = null; 335 String variableName = null; 336 337 if ( LA(2) == TokenTypes.COLON ) 338 { 339 prefix = match( TokenTypes.IDENTIFIER ).getTokenText(); 340 match( TokenTypes.COLON ); 341 } 342 else 343 { 344 prefix = ""; 345 } 346 347 variableName = match( TokenTypes.IDENTIFIER ).getTokenText(); 348 349 getXPathHandler().variableReference( prefix, 350 variableName ); 351 } 352 353 void locationPath(boolean isAbsolute) throws SAXPathException 354 { 355 switch ( LA(1) ) 356 { 357 case TokenTypes.SLASH: 358 case TokenTypes.DOUBLE_SLASH: 359 { 360 if ( isAbsolute ) 361 { 362 absoluteLocationPath(); 363 } 364 else 365 { 366 relativeLocationPath(); 367 } 368 break; 369 } 370 case TokenTypes.AT: 371 case TokenTypes.IDENTIFIER: 372 case TokenTypes.DOT: 373 case TokenTypes.DOT_DOT: 374 case TokenTypes.STAR: 375 { 376 relativeLocationPath(); 377 break; 378 } 379 default: 380 { 381 throwUnexpected(); 382 break; 383 } 384 } 385 } 386 387 private void absoluteLocationPath() throws SAXPathException 388 { 389 getXPathHandler().startAbsoluteLocationPath(); 390 391 switch ( LA(1) ) 392 { 393 case TokenTypes.SLASH: 394 { 395 match( TokenTypes.SLASH ); 396 397 switch ( LA(1) ) 398 { 399 400 case TokenTypes.DOT: 401 case TokenTypes.DOT_DOT: 402 case TokenTypes.AT: 403 case TokenTypes.IDENTIFIER: 404 case TokenTypes.STAR: 405 { 406 steps(); 407 break; 408 } 409 } 410 break; 411 } 412 case TokenTypes.DOUBLE_SLASH: 413 { 414 getXPathHandler().startAllNodeStep( Axis.DESCENDANT_OR_SELF ); 415 getXPathHandler().endAllNodeStep(); 416 417 match( TokenTypes.DOUBLE_SLASH ); 418 switch ( LA(1) ) 419 { 420 case TokenTypes.DOT: 421 case TokenTypes.DOT_DOT: 422 case TokenTypes.AT: 423 case TokenTypes.IDENTIFIER: 424 case TokenTypes.STAR: 425 { 426 steps(); 427 break; 428 } 429 default: 430 XPathSyntaxException ex = this.createSyntaxException("Location path cannot end with //"); 431 throw ex; 432 } 433 break; 434 } 435 } 436 437 getXPathHandler().endAbsoluteLocationPath(); 438 } 439 440 private void relativeLocationPath() throws SAXPathException 441 { 442 getXPathHandler().startRelativeLocationPath(); 443 444 switch ( LA(1) ) 445 { 446 case TokenTypes.SLASH: 447 { 448 match( TokenTypes.SLASH ); 449 break; 450 } 451 case TokenTypes.DOUBLE_SLASH: 452 { 453 getXPathHandler().startAllNodeStep( Axis.DESCENDANT_OR_SELF ); 454 getXPathHandler().endAllNodeStep(); 455 456 match( TokenTypes.DOUBLE_SLASH ); 457 458 break; 459 } 460 } 461 462 steps(); 463 464 getXPathHandler().endRelativeLocationPath(); 465 } 466 467 private void steps() throws SAXPathException 468 { 469 switch ( LA(1) ) 470 { 471 472 case TokenTypes.DOT: 473 case TokenTypes.DOT_DOT: 474 case TokenTypes.AT: 475 case TokenTypes.IDENTIFIER: 476 case TokenTypes.STAR: 477 { 478 step(); 479 break; 480 } 481 case TokenTypes.EOF: 482 { 483 return; 484 } 485 default: 486 { 487 throw createSyntaxException( "Expected one of '.', '..', '@', '*', <QName>" ); 488 } 489 } 490 491 do 492 { 493 if ( ( LA(1) == TokenTypes.SLASH) 494 || 495 ( LA(1) == TokenTypes.DOUBLE_SLASH ) ) 496 { 497 switch ( LA(1) ) 498 { 499 case TokenTypes.SLASH: 500 { 501 match( TokenTypes.SLASH ); 502 break; 503 } 504 case TokenTypes.DOUBLE_SLASH: 505 { 506 getXPathHandler().startAllNodeStep( Axis.DESCENDANT_OR_SELF ); 507 getXPathHandler().endAllNodeStep(); 508 509 match( TokenTypes.DOUBLE_SLASH ); 510 break; 511 } 512 } 513 } 514 else 515 { 516 return; 517 } 518 519 switch ( LA(1) ) 520 { 521 case TokenTypes.DOT: 522 case TokenTypes.DOT_DOT: 523 case TokenTypes.AT: 524 case TokenTypes.IDENTIFIER: 525 case TokenTypes.STAR: 526 { 527 step(); 528 break; 529 } 530 default: 531 { 532 throw createSyntaxException( "Expected one of '.', '..', '@', '*', <QName>" ); 533 } 534 } 535 536 } while ( true ); 537 } 538 539 void step() throws SAXPathException 540 { 541 int axis = 0; 542 543 switch ( LA(1) ) 544 { 545 case TokenTypes.DOT: 546 case TokenTypes.DOT_DOT: 547 { 548 abbrStep(); 549 return; 550 } 551 case TokenTypes.AT: 552 { 553 axis = axisSpecifier(); 554 break; 555 } 556 case TokenTypes.IDENTIFIER: 557 { 558 if ( LA(2) == TokenTypes.DOUBLE_COLON ) 559 { 560 axis = axisSpecifier(); 561 } 562 else 563 { 564 axis = Axis.CHILD; 565 } 566 break; 567 } 568 case TokenTypes.STAR: 569 { 570 axis = Axis.CHILD; 571 break; 572 } 573 } 574 575 nodeTest( axis ); 576 } 577 578 private int axisSpecifier() throws SAXPathException 579 { 580 int axis = 0; 581 582 switch ( LA(1) ) 583 { 584 case TokenTypes.AT: 585 { 586 match( TokenTypes.AT ); 587 axis = Axis.ATTRIBUTE; 588 break; 589 } 590 case TokenTypes.IDENTIFIER: 591 { 592 Token token = LT( 1 ); 593 594 axis = Axis.lookup( token.getTokenText() ); 595 596 if ( axis == Axis.INVALID_AXIS ) 597 { 598 throwInvalidAxis( token.getTokenText() ); 599 } 600 601 match( TokenTypes.IDENTIFIER ); 602 match( TokenTypes.DOUBLE_COLON ); 603 604 break; 605 } 606 } 607 608 return axis; 609 } 610 611 private void nodeTest(int axis) throws SAXPathException 612 { 613 switch ( LA(1) ) 614 { 615 case TokenTypes.IDENTIFIER: 616 { 617 switch ( LA(2) ) 618 { 619 case TokenTypes.LEFT_PAREN: 620 { 621 nodeTypeTest( axis ); 622 break; 623 } 624 default: 625 { 626 nameTest( axis ); 627 break; 628 } 629 } 630 break; 631 } 632 case TokenTypes.STAR: 633 { 634 nameTest( axis ); 635 break; 636 } 637 default: 638 throw createSyntaxException("Expected <QName> or *"); 639 } 640 } 641 642 private void nodeTypeTest(int axis) throws SAXPathException 643 { 644 Token nodeTypeToken = match( TokenTypes.IDENTIFIER ); 645 String nodeType = nodeTypeToken.getTokenText(); 646 647 match( TokenTypes.LEFT_PAREN ); 648 649 if ( "processing-instruction".equals( nodeType ) ) 650 { 651 String piName = ""; 652 653 if ( LA(1) == TokenTypes.LITERAL ) 654 { 655 piName = match( TokenTypes.LITERAL ).getTokenText(); 656 } 657 658 match( TokenTypes.RIGHT_PAREN ); 659 660 getXPathHandler().startProcessingInstructionNodeStep( axis, 661 piName ); 662 663 predicates(); 664 665 getXPathHandler().endProcessingInstructionNodeStep(); 666 } 667 else if ( "node".equals( nodeType ) ) 668 { 669 match( TokenTypes.RIGHT_PAREN ); 670 671 getXPathHandler().startAllNodeStep( axis ); 672 673 predicates(); 674 675 getXPathHandler().endAllNodeStep(); 676 } 677 else if ( "text".equals( nodeType ) ) 678 { 679 match( TokenTypes.RIGHT_PAREN ); 680 681 getXPathHandler().startTextNodeStep( axis ); 682 683 predicates(); 684 685 getXPathHandler().endTextNodeStep(); 686 } 687 else if ( "comment".equals( nodeType ) ) 688 { 689 match( TokenTypes.RIGHT_PAREN ); 690 691 getXPathHandler().startCommentNodeStep( axis ); 692 693 predicates(); 694 695 getXPathHandler().endCommentNodeStep(); 696 } 697 else 698 { 699 throw createSyntaxException( "Expected node-type" ); 700 } 701 } 702 703 private void nameTest(int axis) throws SAXPathException 704 { 705 String prefix = null; 706 String localName = null; 707 708 switch ( LA(2) ) 709 { 710 case TokenTypes.COLON: 711 { 712 switch ( LA(1) ) 713 { 714 case TokenTypes.IDENTIFIER: 715 { 716 prefix = match( TokenTypes.IDENTIFIER ).getTokenText(); 717 match( TokenTypes.COLON ); 718 break; 719 } 720 } 721 break; 722 } 723 } 724 725 switch ( LA(1) ) 726 { 727 case TokenTypes.IDENTIFIER: 728 { 729 localName = match( TokenTypes.IDENTIFIER ).getTokenText(); 730 break; 731 } 732 case TokenTypes.STAR: 733 { 734 match( TokenTypes.STAR ); 735 localName = "*"; 736 break; 737 } 738 } 739 740 if ( prefix == null ) 741 { 742 prefix = ""; 743 } 744 745 getXPathHandler().startNameStep( axis, 746 prefix, 747 localName ); 748 749 predicates(); 750 751 getXPathHandler().endNameStep(); 752 } 753 754 private void abbrStep() throws SAXPathException 755 { 756 switch ( LA(1) ) 757 { 758 case TokenTypes.DOT: 759 { 760 match( TokenTypes.DOT ); 761 getXPathHandler().startAllNodeStep( Axis.SELF ); 762 predicates(); 763 getXPathHandler().endAllNodeStep(); 764 break; 765 } 766 case TokenTypes.DOT_DOT: 767 { 768 match( TokenTypes.DOT_DOT ); 769 getXPathHandler().startAllNodeStep( Axis.PARENT ); 770 predicates(); 771 getXPathHandler().endAllNodeStep(); 772 break; 773 } 774 } 775 } 776 777 private void predicates() throws SAXPathException 778 { 779 while (true ) 780 { 781 if ( LA(1) == TokenTypes.LEFT_BRACKET ) 782 { 783 predicate(); 784 } 785 else 786 { 787 break; 788 } 789 } 790 } 791 792 void predicate() throws SAXPathException 793 { 794 getXPathHandler().startPredicate(); 795 796 match( TokenTypes.LEFT_BRACKET ); 797 798 predicateExpr(); 799 800 match( TokenTypes.RIGHT_BRACKET ); 801 802 getXPathHandler().endPredicate(); 803 } 804 805 private void predicateExpr() throws SAXPathException 806 { 807 expr(); 808 } 809 810 private void expr() throws SAXPathException 811 { 812 orExpr(); 813 } 814 815 private void orExpr() throws SAXPathException 816 { 817 getXPathHandler().startOrExpr(); 818 819 andExpr(); 820 821 boolean create = false; 822 823 switch ( LA(1) ) 824 { 825 case TokenTypes.OR: 826 { 827 create = true; 828 match( TokenTypes.OR ); 829 orExpr(); 830 break; 831 } 832 } 833 834 getXPathHandler().endOrExpr( create ); 835 } 836 837 private void andExpr() throws SAXPathException 838 { 839 getXPathHandler().startAndExpr(); 840 841 equalityExpr(); 842 843 boolean create = false; 844 845 switch ( LA(1) ) 846 { 847 case TokenTypes.AND: 848 { 849 create = true; 850 match( TokenTypes.AND ); 851 andExpr(); 852 break; 853 } 854 } 855 856 getXPathHandler().endAndExpr( create ); 857 } 858 859 private void equalityExpr() throws SAXPathException 860 { 861 relationalExpr(); 862 863 int la = LA(1); 864 while (la == TokenTypes.EQUALS || la == TokenTypes.NOT_EQUALS) 865 { 866 switch ( la ) 867 { 868 case TokenTypes.EQUALS: 869 { 870 match( TokenTypes.EQUALS ); 871 getXPathHandler().startEqualityExpr(); 872 relationalExpr(); 873 getXPathHandler().endEqualityExpr( Operator.EQUALS ); 874 break; 875 } 876 case TokenTypes.NOT_EQUALS: 877 { 878 match( TokenTypes.NOT_EQUALS ); 879 getXPathHandler().startEqualityExpr(); 880 relationalExpr(); 881 getXPathHandler().endEqualityExpr( Operator.NOT_EQUALS ); 882 break; 883 } 884 } 885 la = LA(1); 886 } 887 } 888 889 private void relationalExpr() throws SAXPathException 890 { 891 892 additiveExpr(); 893 894 int la = LA(1); 895 while (la == TokenTypes.LESS_THAN_SIGN 900 || la == TokenTypes.GREATER_THAN_SIGN 901 || la == TokenTypes.LESS_THAN_OR_EQUALS_SIGN 902 || la == TokenTypes.GREATER_THAN_OR_EQUALS_SIGN ) { 903 switch ( la ) 904 { 905 case TokenTypes.LESS_THAN_SIGN: 906 { 907 match( TokenTypes.LESS_THAN_SIGN ); 908 getXPathHandler().startRelationalExpr(); 909 additiveExpr(); 910 getXPathHandler().endRelationalExpr( Operator.LESS_THAN ); 911 break; 912 } 913 case TokenTypes.GREATER_THAN_SIGN: 914 { 915 match( TokenTypes.GREATER_THAN_SIGN ); 916 getXPathHandler().startRelationalExpr(); 917 additiveExpr(); 918 getXPathHandler().endRelationalExpr( Operator.GREATER_THAN ); 919 break; 920 } 921 case TokenTypes.GREATER_THAN_OR_EQUALS_SIGN: 922 { 923 match( TokenTypes.GREATER_THAN_OR_EQUALS_SIGN ); 924 getXPathHandler().startRelationalExpr(); 925 additiveExpr(); 926 getXPathHandler().endRelationalExpr( Operator.GREATER_THAN_EQUALS ); 927 break; 928 } 929 case TokenTypes.LESS_THAN_OR_EQUALS_SIGN: 930 { 931 match( TokenTypes.LESS_THAN_OR_EQUALS_SIGN ); 932 getXPathHandler().startRelationalExpr(); 933 additiveExpr(); 934 getXPathHandler().endRelationalExpr( Operator.LESS_THAN_EQUALS ); 935 break; 936 } 937 } 938 la = LA(1); 939 } 940 } 941 942 943 private void additiveExpr() throws SAXPathException 944 { 945 multiplicativeExpr(); 946 947 int la = LA(1); 948 while (la == TokenTypes.PLUS || la == TokenTypes.MINUS) 949 { 950 switch ( la ) 951 { 952 case TokenTypes.PLUS: 953 { 954 match( TokenTypes.PLUS ); 955 getXPathHandler().startAdditiveExpr(); 956 multiplicativeExpr(); 957 getXPathHandler().endAdditiveExpr( Operator.ADD ); 958 break; 959 } 960 case TokenTypes.MINUS: 961 { 962 match( TokenTypes.MINUS ); 963 getXPathHandler().startAdditiveExpr(); 964 multiplicativeExpr(); 965 getXPathHandler().endAdditiveExpr( Operator.SUBTRACT ); 966 break; 967 } 968 } 969 la = LA(1); 970 } 971 } 972 973 private void multiplicativeExpr() throws SAXPathException 974 { 975 unaryExpr(); 976 977 int la = LA(1); 978 while (la == TokenTypes.STAR || la == TokenTypes.DIV || la == TokenTypes.MOD) 979 { 980 switch ( la ) 981 { 982 case TokenTypes.STAR: 983 { 984 match( TokenTypes.STAR ); 985 getXPathHandler().startMultiplicativeExpr(); 986 unaryExpr(); 987 getXPathHandler().endMultiplicativeExpr( Operator.MULTIPLY ); 988 break; 989 } 990 case TokenTypes.DIV: 991 { 992 match( TokenTypes.DIV ); 993 getXPathHandler().startMultiplicativeExpr(); 994 unaryExpr(); 995 getXPathHandler().endMultiplicativeExpr( Operator.DIV ); 996 break; 997 } 998 case TokenTypes.MOD: 999 { 1000 match( TokenTypes.MOD ); 1001 getXPathHandler().startMultiplicativeExpr(); 1002 unaryExpr(); 1003 getXPathHandler().endMultiplicativeExpr( Operator.MOD ); 1004 break; 1005 } 1006 } 1007 la = LA(1); 1008 } 1009 1010 } 1011 1012 private void unaryExpr() throws SAXPathException 1013 { 1014 switch ( LA(1) ) 1015 { 1016 case TokenTypes.MINUS: 1017 { 1018 getXPathHandler().startUnaryExpr(); 1019 match( TokenTypes.MINUS ); 1020 unaryExpr(); 1021 getXPathHandler().endUnaryExpr( Operator.NEGATIVE ); 1022 break; 1023 } 1024 default: 1025 { 1026 unionExpr(); 1027 break; 1028 } 1029 } 1030 1031 1032 } 1033 1034 private void unionExpr() throws SAXPathException 1035 { 1036 getXPathHandler().startUnionExpr(); 1037 1038 pathExpr(); 1039 1040 boolean create = false; 1041 1042 switch ( LA(1) ) 1043 { 1044 case TokenTypes.PIPE: 1045 { 1046 match( TokenTypes.PIPE ); 1047 create = true; 1048 expr(); 1049 break; 1050 } 1051 } 1052 1053 getXPathHandler().endUnionExpr( create ); 1054 } 1055 1056 private Token match(int tokenType) throws XPathSyntaxException 1057 { 1058 LT(1); 1059 1060 Token token = (Token) tokens.get( 0 ); 1061 1062 if ( token.getTokenType() == tokenType ) 1063 { 1064 tokens.removeFirst(); 1065 return token; 1066 } 1067 1068 throw createSyntaxException( "Expected: " + TokenTypes.getTokenText( tokenType ) ); 1069 } 1070 1071 private int LA(int position) 1072 { 1073 return LT(position).getTokenType(); 1074 } 1075 1076 private Token LT(int position) 1077 { 1078 if ( tokens.size() <= ( position - 1 ) ) 1079 { 1080 for ( int i = 0 ; i < position ; ++i ) 1081 { 1082 tokens.add( lexer.nextToken() ); 1083 } 1084 } 1085 1086 return (Token) tokens.get( position - 1 ); 1087 } 1088 1089 private boolean isNodeTypeName(Token name) 1090 { 1091 String text = name.getTokenText(); 1092 1093 if ( "node".equals( text ) 1094 || 1095 "comment".equals( text ) 1096 || 1097 "text".equals( text ) 1098 || 1099 "processing-instruction".equals( text ) ) 1100 { 1101 return true; 1102 } 1103 1104 return false; 1105 } 1106 1107 private XPathSyntaxException createSyntaxException(String message) 1108 { 1109 String xpath = this.lexer.getXPath(); 1110 int position = LT(1).getTokenBegin(); 1111 1112 return new XPathSyntaxException( xpath, 1113 position, 1114 message ); 1115 } 1116 1117 private void throwInvalidAxis(String invalidAxis) throws SAXPathException 1118 { 1119 String xpath = this.lexer.getXPath(); 1120 int position = LT(1).getTokenBegin(); 1121 1122 String message = "Expected valid axis name instead of [" + invalidAxis + "]"; 1123 1124 throw new XPathSyntaxException( xpath, 1125 position, 1126 message ); 1127 } 1128 1129 private void throwUnexpected() throws SAXPathException 1130 { 1131 throw createSyntaxException( "Unexpected '" + LT(1).getTokenText() + "'" ); 1132 } 1133} 1134 | Popular Tags |