File tree Expand file tree Collapse file tree 4 files changed +27
-8
lines changed Expand file tree Collapse file tree 4 files changed +27
-8
lines changed Original file line number Diff line number Diff line change @@ -92,11 +92,20 @@ extension AST {
92
92
93
93
public struct Alternation : Hashable , _ASTNode {
94
94
public let children : [ AST ]
95
- public let location : SourceLocation
95
+ public let pipes : [ SourceLocation ]
96
+
97
+ public init ( _ mems: [ AST ] , pipes: [ SourceLocation ] ) {
98
+ // An alternation must have at least two branches (though the branches
99
+ // may be empty AST nodes), and n - 1 pipes.
100
+ precondition ( mems. count >= 2 )
101
+ precondition ( pipes. count == mems. count - 1 )
96
102
97
- public init ( _ mems: [ AST ] , _ location: SourceLocation ) {
98
103
self . children = mems
99
- self . location = location
104
+ self . pipes = pipes
105
+ }
106
+
107
+ public var location : SourceLocation {
108
+ . init( children. first!. location. start ..< children. last!. location. end)
100
109
}
101
110
}
102
111
Original file line number Diff line number Diff line change @@ -89,17 +89,20 @@ extension Parser {
89
89
90
90
if source. isEmpty { return . empty( . init( loc ( _start) ) ) }
91
91
92
- var result = Array < AST > ( singleElement: try parseConcatenation ( ) )
93
- while source. tryEat ( " | " ) {
94
- // TODO: track pipe locations too...
92
+ var result = [ try parseConcatenation ( ) ]
93
+ var pipes : [ SourceLocation ] = [ ]
94
+ while true {
95
+ let pipeStart = source. currentPosition
96
+ guard source. tryEat ( " | " ) else { break }
97
+ pipes. append ( loc ( pipeStart) )
95
98
result. append ( try parseConcatenation ( ) )
96
99
}
97
100
98
101
if result. count == 1 {
99
102
return result [ 0 ]
100
103
}
101
104
102
- return . alternation( . init( result, loc ( _start ) ) )
105
+ return . alternation( . init( result, pipes : pipes ) )
103
106
}
104
107
105
108
/// Parse a term, potentially separated from others by `|`
Original file line number Diff line number Diff line change 17
17
import _MatchingEngine
18
18
19
19
func alt( _ asts: [ AST ] ) -> AST {
20
- . alternation( . init( asts, . fake) )
20
+ return . alternation(
21
+ . init( asts, pipes: Array ( repeating: . fake, count: asts. count - 1 ) )
22
+ )
21
23
}
22
24
func alt( _ asts: AST ... ) -> AST {
23
25
alt ( asts)
Original file line number Diff line number Diff line change @@ -928,6 +928,11 @@ extension RegexTests {
928
928
rangeTest ( alt, entireRange)
929
929
rangeTest ( " ( \( alt) ) " , insetRange ( by: 1 ) , at: \. children![ 0 ] . location)
930
930
}
931
+
932
+ rangeTest ( " | " , entireRange, at: { $0. as ( Alt . self) !. pipes [ 0 ] } )
933
+ rangeTest ( " a| " , range ( 1 ..< 2 ) , at: { $0. as ( Alt . self) !. pipes [ 0 ] } )
934
+ rangeTest ( " a|b " , range ( 1 ..< 2 ) , at: { $0. as ( Alt . self) !. pipes [ 0 ] } )
935
+ rangeTest ( " ||| " , range ( 1 ..< 2 ) , at: { $0. as ( Alt . self) !. pipes [ 1 ] } )
931
936
}
932
937
933
938
func testParseErrors( ) {
You can’t perform that action at this time.
0 commit comments