@@ -56,9 +56,9 @@ import {
56
56
import { Expression } from './expressions/expression' ;
57
57
58
58
import {
59
- Q_MM ,
60
- Q_01 ,
61
- Q_1M ,
59
+ Q_ZERO_OR_MULTIPLE ,
60
+ Q_ZERO_OR_ONE ,
61
+ Q_ONE_OR_MULTIPLE ,
62
62
xPathTokenRules ,
63
63
TOK_DIV ,
64
64
TOK_MOD ,
@@ -135,7 +135,7 @@ export class XPath {
135
135
136
136
// The productions of the grammar. Columns of the table:
137
137
//
138
- // - target nonterminal ,
138
+ // - target non-terminal ,
139
139
// - pattern,
140
140
// - precedence,
141
141
// - semantic value factory
@@ -148,14 +148,14 @@ export class XPath {
148
148
// and thus evaluates XPath expressions.
149
149
//
150
150
// The precedence is used to decide between reducing and shifting by
151
- // comparing the precendence of the rule that is candidate for
151
+ // comparing the precedence of the rule that is candidate for
152
152
// reducing with the precedence of the look ahead token. Precedence of
153
153
// -1 means that the precedence of the tokens in the pattern is used
154
154
// instead. TODO: It shouldn't be necessary to explicitly assign
155
155
// precedences to rules.
156
156
157
157
// DGF As it stands, these precedences are purely empirical; we're
158
- // not sure they can be made to be consistent at all.
158
+ // not sure if they can be made to be consistent at all.
159
159
xPathGrammarRules = [
160
160
[ XPathLocationPath , [ XPathRelativeLocationPath ] , 18 , this . passExpr ] ,
161
161
[ XPathLocationPath , [ XPathAbsoluteLocationPath ] , 18 , this . passExpr ] ,
@@ -194,7 +194,7 @@ export class XPath {
194
194
[ XPathFunctionCall , [ TOK_QNAME , TOK_PARENO , TOK_PARENC ] , - 1 , this . makeFunctionCallExpr1 ] ,
195
195
[
196
196
XPathFunctionCall ,
197
- [ TOK_QNAME , TOK_PARENO , XPathExpr , XPathArgumentRemainder , Q_MM , TOK_PARENC ] ,
197
+ [ TOK_QNAME , TOK_PARENO , XPathExpr , XPathArgumentRemainder , Q_ZERO_OR_MULTIPLE , TOK_PARENC ] ,
198
198
- 1 ,
199
199
this . makeFunctionCallExpr2
200
200
] ,
@@ -208,7 +208,7 @@ export class XPath {
208
208
[ XPathPathExpr , [ XPathFilterExpr , TOK_SLASH , XPathRelativeLocationPath ] , 19 , this . makePathExpr1 ] ,
209
209
[ XPathPathExpr , [ XPathFilterExpr , TOK_DSLASH , XPathRelativeLocationPath ] , 19 , this . makePathExpr2 ] ,
210
210
211
- [ XPathFilterExpr , [ XPathPrimaryExpr , XPathPredicate , Q_MM ] , 31 , this . makeFilterExpr ] ,
211
+ [ XPathFilterExpr , [ XPathPrimaryExpr , XPathPredicate , Q_ZERO_OR_MULTIPLE ] , 31 , this . makeFilterExpr ] ,
212
212
213
213
[ XPathExpr , [ XPathPrimaryExpr ] , 16 , this . passExpr ] ,
214
214
[ XPathExpr , [ XPathUnionExpr ] , 16 , this . passExpr ] ,
@@ -356,7 +356,7 @@ export class XPath {
356
356
return new NodeTestNC ( ncname . value ) ;
357
357
}
358
358
359
- makeNodeTestExpr3 ( qname : any ) {
359
+ makeNodeTestExpr3 ( qname : TokenExpr ) {
360
360
return new NodeTestName ( qname . value ) ;
361
361
}
362
362
@@ -385,12 +385,12 @@ export class XPath {
385
385
return new NodeTestPI ( target . value ) ;
386
386
}
387
387
388
- makePredicateExpr ( pareno : any , expr : any ) {
389
- return new PredicateExpr ( expr ) ;
388
+ makePredicateExpr ( pareno : any , expression : any ) {
389
+ return new PredicateExpr ( expression ) ;
390
390
}
391
391
392
- makePrimaryExpr ( pareno : any , expr : any ) {
393
- return expr ;
392
+ makePrimaryExpr ( pareno : any , expression : any ) {
393
+ return expression ;
394
394
}
395
395
396
396
makeFunctionCallExpr1 ( name : any ) {
@@ -406,11 +406,11 @@ export class XPath {
406
406
return ret ;
407
407
}
408
408
409
- makeArgumentExpr ( comma : any , expr : any ) {
410
- return expr ;
409
+ makeArgumentExpr ( comma : any , expression : any ) {
410
+ return expression ;
411
411
}
412
412
413
- makeUnionExpr ( expr1 : any , pipe : any , expr2 : any ) {
413
+ makeUnionExpr ( expr1 : Expression , pipe : TokenExpr , expr2 : Expression ) {
414
414
return new UnionExpr ( expr1 , expr2 ) ;
415
415
}
416
416
@@ -567,56 +567,56 @@ export class XPath {
567
567
}
568
568
}
569
569
570
- xPathMatchStack ( stack : any , pattern : any ) {
570
+ xPathMatchStack ( stack : any [ ] , pattern : any [ ] ) {
571
571
// NOTE(mesch): The stack matches for variable cardinality are
572
572
// greedy but don't do backtracking. This would be an issue only
573
573
// with rules of the form A* A, i.e. with an element with variable
574
574
// cardinality followed by the same element. Since that doesn't
575
575
// occur in the grammar at hand, all matches on the stack are
576
576
// unambiguous.
577
577
578
- const S = stack . length ;
579
- const P = pattern . length ;
578
+ const stackLength = stack . length ;
579
+ const patternLength = pattern . length ;
580
580
let p ;
581
581
let s ;
582
582
const match : any = [ ] ;
583
- match . matchlength = 0 ;
583
+ match . matchLength = 0 ;
584
584
let ds = 0 ;
585
- for ( p = P - 1 , s = S - 1 ; p >= 0 && s >= 0 ; -- p , s -= ds ) {
585
+ for ( p = patternLength - 1 , s = stackLength - 1 ; p >= 0 && s >= 0 ; -- p , s -= ds ) {
586
586
ds = 0 ;
587
587
const qmatch : any = [ ] ;
588
- if ( pattern [ p ] == Q_MM ) {
588
+ if ( pattern [ p ] == Q_ZERO_OR_MULTIPLE ) {
589
589
p -= 1 ;
590
590
match . push ( qmatch ) ;
591
591
while ( s - ds >= 0 && stack [ s - ds ] . tag == pattern [ p ] ) {
592
592
qmatch . push ( stack [ s - ds ] ) ;
593
593
ds += 1 ;
594
- match . matchlength += 1 ;
594
+ match . matchLength += 1 ;
595
595
}
596
- } else if ( pattern [ p ] == Q_01 ) {
596
+ } else if ( pattern [ p ] == Q_ZERO_OR_ONE ) {
597
597
p -= 1 ;
598
598
match . push ( qmatch ) ;
599
599
while ( s - ds >= 0 && ds < 2 && stack [ s - ds ] . tag == pattern [ p ] ) {
600
600
qmatch . push ( stack [ s - ds ] ) ;
601
601
ds += 1 ;
602
- match . matchlength += 1 ;
602
+ match . matchLength += 1 ;
603
603
}
604
- } else if ( pattern [ p ] == Q_1M ) {
604
+ } else if ( pattern [ p ] == Q_ONE_OR_MULTIPLE ) {
605
605
p -= 1 ;
606
606
match . push ( qmatch ) ;
607
607
if ( stack [ s ] . tag == pattern [ p ] ) {
608
608
while ( s - ds >= 0 && stack [ s - ds ] . tag == pattern [ p ] ) {
609
609
qmatch . push ( stack [ s - ds ] ) ;
610
610
ds += 1 ;
611
- match . matchlength += 1 ;
611
+ match . matchLength += 1 ;
612
612
}
613
613
} else {
614
614
return [ ] ;
615
615
}
616
616
} else if ( stack [ s ] . tag == pattern [ p ] ) {
617
617
match . push ( stack [ s ] ) ;
618
618
ds += 1 ;
619
- match . matchlength += 1 ;
619
+ match . matchLength += 1 ;
620
620
} else {
621
621
return [ ] ;
622
622
}
@@ -764,10 +764,10 @@ export class XPath {
764
764
const pattern : any = rule [ 1 ] ;
765
765
766
766
for ( let j = pattern . length - 1 ; j >= 0 ; -- j ) {
767
- if ( pattern [ j ] == Q_1M ) {
767
+ if ( pattern [ j ] == Q_ONE_OR_MULTIPLE ) {
768
768
push_ ( this . xPathRules , pattern [ j - 1 ] . key , rule ) ;
769
769
break ;
770
- } else if ( pattern [ j ] == Q_MM || pattern [ j ] == Q_01 ) {
770
+ } else if ( pattern [ j ] == Q_ZERO_OR_MULTIPLE || pattern [ j ] == Q_ZERO_OR_ONE ) {
771
771
push_ ( this . xPathRules , pattern [ j - 1 ] . key , rule ) ;
772
772
-- j ;
773
773
} else {
@@ -924,8 +924,8 @@ export class XPath {
924
924
* grammatical rules to them, "reducing" them to higher-level
925
925
* tokens. Ultimately, any valid XPath should reduce to exactly one
926
926
* "Expr" token.
927
-
928
- * Reduce too early or too late and you'll have two tokens that can't reduce
927
+ *
928
+ * Reduce too early or too late, and you'll have two tokens that can't reduce
929
929
* to single Expr. For example, you may hastily reduce a qname that
930
930
* should name a function, incorrectly treating it as a tag name.
931
931
* Or you may reduce too late, accidentally reducing the last part of the
@@ -940,11 +940,15 @@ export class XPath {
940
940
*
941
941
* Some tokens have left associativity, in which case we shift when they
942
942
* have LOWER precedence than the candidate.
943
+ * @param stack The actual grammar rule stack.
944
+ * @param ahead The grammar rule ahead.
945
+ * @return `true` if a grammar rule candidate was applied. `false` otherwise.
946
+ * @private
943
947
*/
944
948
private xPathReduce (
945
949
stack : GrammarRuleCandidate [ ] ,
946
950
ahead : GrammarRuleCandidate
947
- ) {
951
+ ) : boolean {
948
952
let candidate : GrammarRuleCandidate = null ;
949
953
950
954
if ( stack . length > 0 ) {
@@ -956,9 +960,8 @@ export class XPath {
956
960
}
957
961
}
958
962
959
- let ret ;
960
963
if ( candidate && ( ! ahead || candidate . prec > ahead . prec || ( ahead . tag . left && candidate . prec >= ahead . prec ) ) ) {
961
- for ( let i = 0 ; i < candidate . match . matchlength ; ++ i ) {
964
+ for ( let i = 0 ; i < candidate . match . matchLength ; ++ i ) {
962
965
stack . pop ( ) ;
963
966
}
964
967
@@ -968,12 +971,12 @@ export class XPath {
968
971
} `
969
972
) ;
970
973
971
- const matchExpression = mapExpr ( candidate . match , ( m ) => m . expr ) ;
974
+ const matchExpression = mapExpr ( candidate . match , ( m : GrammarRuleCandidate ) => m . expr ) ;
972
975
this . xPathLog ( `going to apply ${ candidate . rule [ 3 ] } ` ) ;
973
976
candidate . expr = candidate . rule [ 3 ] . apply ( this , matchExpression ) ;
974
977
975
978
stack . push ( candidate ) ;
976
- ret = true ;
979
+ return true ;
977
980
} else {
978
981
if ( ahead ) {
979
982
this . xPathLog (
@@ -983,9 +986,9 @@ export class XPath {
983
986
) ;
984
987
stack . push ( ahead ) ;
985
988
}
986
- ret = false ;
989
+
990
+ return false ;
987
991
}
988
- return ret ;
989
992
}
990
993
991
994
/**
0 commit comments