@@ -854,6 +854,7 @@ extension Source {
854
854
/// NumberRef -> ('+' | '-')? <Decimal Number>
855
855
///
856
856
private mutating func lexNumberedReference(
857
+ allowWholePatternRef: Bool = false
857
858
) throws -> AST . Atom . Reference ? {
858
859
let kind = try recordLoc { src -> AST . Atom . Reference . Kind ? in
859
860
// Note this logic should match canLexNumberedReference.
@@ -869,6 +870,9 @@ extension Source {
869
870
return nil
870
871
}
871
872
guard let kind = kind else { return nil }
873
+ guard allowWholePatternRef || kind. value != . recurseWholePattern else {
874
+ throw ParseError . cannotReferToWholePattern
875
+ }
872
876
return . init( kind. value, innerLoc: kind. location)
873
877
}
874
878
@@ -882,10 +886,10 @@ extension Source {
882
886
883
887
/// Eat a named reference up to a given closing delimiter.
884
888
private mutating func expectNamedReference(
885
- endingWith end: String
889
+ endingWith end: String , eatEnding : Bool = true
886
890
) throws -> AST . Atom . Reference {
887
891
// TODO: Group name validation, see comment in lexGroupStart.
888
- let str = try expectQuoted ( endingWith: end)
892
+ let str = try expectQuoted ( endingWith: end, eatEnding : eatEnding )
889
893
return . init( . named( str. value) , innerLoc: str. location)
890
894
}
891
895
@@ -894,13 +898,18 @@ extension Source {
894
898
/// NameOrNumberRef -> NumberRef | <String>
895
899
///
896
900
private mutating func expectNamedOrNumberedReference(
897
- endingWith ending: String
901
+ endingWith ending: String , eatEnding: Bool = true ,
902
+ allowWholePatternRef: Bool = false
898
903
) throws -> AST . Atom . Reference {
899
- if let numbered = try lexNumberedReference ( ) {
900
- try expect ( sequence: ending)
904
+ if let numbered = try lexNumberedReference (
905
+ allowWholePatternRef: allowWholePatternRef
906
+ ) {
907
+ if eatEnding {
908
+ try expect ( sequence: ending)
909
+ }
901
910
return numbered
902
911
}
903
- return try expectNamedReference ( endingWith: ending)
912
+ return try expectNamedReference ( endingWith: ending, eatEnding : eatEnding )
904
913
}
905
914
906
915
private static func getClosingDelimiter(
@@ -943,8 +952,8 @@ extension Source {
943
952
// Oniguruma-style subpatterns.
944
953
if let openChar = src. tryEat ( anyOf: " < " , " ' " ) {
945
954
let closing = String ( Source . getClosingDelimiter ( for: openChar) )
946
- return . subpattern(
947
- try src . expectNamedOrNumberedReference ( endingWith: closing) )
955
+ return . subpattern( try src . expectNamedOrNumberedReference (
956
+ endingWith: closing, allowWholePatternRef : true ) )
948
957
}
949
958
950
959
// PCRE allows \g followed by a bare numeric reference.
@@ -1029,7 +1038,7 @@ extension Source {
1029
1038
}
1030
1039
1031
1040
// Numbered subpattern reference.
1032
- if let ref = try src. lexNumberedReference ( ) {
1041
+ if let ref = try src. lexNumberedReference ( allowWholePatternRef : true ) {
1033
1042
try src. expect ( " ) " )
1034
1043
return . subpattern( ref)
1035
1044
}
0 commit comments