32
32
* This class is in charge of lexical processing of the XPath
33
33
* expression into tokens.
34
34
*
35
- * @LastModified: Apr 2022
35
+ * @LastModified: June 2022
36
36
*/
37
37
class Lexer
38
38
{
@@ -155,6 +155,7 @@ void tokenize(String pat, List<String> targetStrings)
155
155
boolean isStartOfPat = true ;
156
156
boolean isAttrName = false ;
157
157
boolean isNum = false ;
158
+ boolean isAxis = false ;
158
159
159
160
// Nesting of '[' so we can know if the given element should be
160
161
// counted inside the m_patternMap.
@@ -254,8 +255,7 @@ void tokenize(String pat, List<String> targetStrings)
254
255
// check operator symbol
255
256
String s = pat .substring (startSubstring , i );
256
257
if (Token .contains (s )) {
257
- m_opCount ++;
258
- isLiteral = false ;
258
+ incrementCount ();
259
259
}
260
260
addToTokenQueue (s );
261
261
}
@@ -339,23 +339,45 @@ else if (Token.STAR == c)
339
339
{
340
340
nesting --;
341
341
}
342
- else if (( Token .LPAREN == c ) || ( Token . LBRACK == c ) )
342
+ else if (Token .LBRACK == c )
343
343
{
344
344
nesting ++;
345
- if (!isLiteral && (Token .LPAREN == c )) {
346
- m_grpCount ++;
347
- m_opCount ++;
348
- isLiteral = false ;
345
+ incrementCount ();
346
+ isAxis = false ;
347
+ }
348
+ else if ((Token .LPAREN == c ))
349
+ {
350
+ nesting ++;
351
+ if (isLiteral ) {
352
+ if (!isAxis ) {
353
+ incrementCount ();
354
+ }
355
+ } else {
356
+ m_grpCount ++;
357
+ incrementCount ();
349
358
}
359
+ isAxis = false ;
350
360
}
351
361
352
- if ((Token .GT == c || Token .LT == c || Token .EQ == c ) && Token .EQ != peekNext (pat , i )) {
353
- m_opCount ++;
354
- isLiteral = false ;
362
+ if ((Token .GT == c || Token .LT == c || Token .EQ == c || Token .EM == c )) {
363
+ if (Token .EQ != peekNext (pat , i )) {
364
+ incrementCount ();
365
+ }
355
366
}
356
- else if ((Token .LPAREN != c ) && (Token .RPAREN != c ) && (Token .RBRACK != c )) {
357
- m_opCount ++;
358
- isLiteral = false ;
367
+ else if (Token .SLASH == c ) {
368
+ isAxis = false ;
369
+ if (Token .SLASH != peekNext (pat , i )) {
370
+ incrementCount ();
371
+ }
372
+ }
373
+ // '(' and '[' already counted above; ':' is examined in case below
374
+ // ',' is part of a function
375
+ else if ((Token .LPAREN != c ) && (Token .LBRACK != c ) && (Token .RPAREN != c )
376
+ && (Token .RBRACK != c ) && (Token .COLON != c ) && (Token .COMMA != c )) {
377
+ if (Token .STAR != c || !isAxis ) {
378
+ incrementCount ();
379
+ }
380
+ isAxis = false ;
359
381
}
360
382
361
383
addToTokenQueue (pat .substring (i , i + 1 ));
@@ -376,6 +398,7 @@ else if ((Token.LPAREN != c) && (Token.RPAREN != c) && (Token.RBRACK != c)) {
376
398
startSubstring = -1 ;
377
399
posOfNSSep = -1 ;
378
400
m_opCount ++;
401
+ isAxis = true ;
379
402
addToTokenQueue (pat .substring (i - 1 , i + 1 ));
380
403
381
404
break ;
@@ -389,6 +412,9 @@ else if ((Token.LPAREN != c) && (Token.RPAREN != c) && (Token.RBRACK != c)) {
389
412
// fall through on purpose
390
413
default :
391
414
isLiteral = true ;
415
+ if (!isNum && Token .DOT == c && Token .DOT != peekNext (pat , i )) {
416
+ incrementCount ();
417
+ }
392
418
if (-1 == startSubstring )
393
419
{
394
420
startSubstring = i ;
@@ -443,6 +469,11 @@ else if (null != targetStrings)
443
469
m_processor .m_queueMark = 0 ;
444
470
}
445
471
472
+ private void incrementCount () {
473
+ m_opCount ++;
474
+ isLiteral = false ;
475
+ }
476
+
446
477
/**
447
478
* Peeks at the next character without advancing the index.
448
479
* @param s the input string
0 commit comments