Match a sequence of patterns.
class sequence pattern[readonly value element type]
extends base pattern[element type]
immutable list[pattern[element type]] patterns list
private mutable var boolean validated
sequence pattern(readonly list[pattern[element type]] patterns list)
this • patterns list = patterns listfrozen copy()
implement void validate()
if validated
return
for (the pattern : patterns list)
(the pattern !> validatable) • validate()
implement implicit boolean call(readonly list[element type] the list)
match : match prefix(the list)
return match is_not null && match == the listsize
Check whether the given list can be a start of the sequence that matches this pattern.
implement boolean is viable prefix(readonly list[element type] the list)
if the listis empty
return true
var nonnegative index : 0
while index < patterns listsize - 1
match : patterns list[index] • match prefix(the listskip(prefix))
if match is null
return false
prefix += match
if prefix == the listsize
return true
index += 1
assert index == patterns listsize - 1
return patterns list[index] • is viable prefix(the listskip(prefix))
private nonnegative or null match subsequence(readonly list[element type] the list, var nonnegative index, var nonnegative prefix)
while index < patterns listsize
match : patterns list[index] • match prefix(the listskip(prefix))
if match is null
return missinginstance
prefix += match
index += 1
return prefix
Returns the maximum number of the elements of a given list that matches the pattern, or null if there is no prefix match. This is a greedy match: it mtaches the longest prefix.
implement nonnegative or null match prefix(readonly list[element type] the list)
return match subsequence(the list, 0, 0)
Gets the first non-empty match for this pattern.
implement range or null find first(readonly list[element type] the list, var nonnegative start index)
while start index <= the listsize
first match : patterns list[0] • find first(the list, start index)
if first match is null
return missinginstance
rest match : match subsequence(the list, 1, first matchend)
if rest match is_not null
return base range • new(first matchbegin, rest match)
start index = first matchbegin + 1
return missinginstance