Unicode Character Classes
Syntax
UnicodeCharacter  Any Unicode character
UnicodeAlphanumeric  Any Unicode alphabetic or decimal digit character (includes ASCII 0‑9, A‑Z, and a‑z)
LineTerminator  «LF» | «CR» | «u2028» | «u2029»
NonTerminator  UnicodeCharacter except LineTerminator
Semantics
lineTerminators : {Character} = {‘«LF»’, ‘«CR»’, ‘«u2028»’, ‘«u2029»’}
nonTerminators : {Character} = {‘«NUL»’ ... ‘«uFFFF»’} – lineTerminators
reWhitespaces : {Character} = {‘«FF»’, ‘«LF»’, ‘«CR»’, ‘«TAB»’, ‘«VT»’, ‘ ’}
reDigits : {Character} = {‘0’ ... ‘9’}
reWordCharacters : {Character} = {‘0’ ... ‘9’, ‘A’ ... ‘Z’, ‘a’ ... ‘z’, ‘_’}
Regular Expression Definitions
Semantics
type REInput = tuple {str: String; ignoreCase: Boolean; multiline: Boolean}
Field str is the input string. ignoreCase and multiline are the corresponding regular expression flags.
type REResult = oneof {success: REMatch; failure}
type REMatch = tuple {endIndex: Integer; captured: Capture[]}
A REMatch holds an intermediate state during the pattern-matching process. endIndex is the index of the next input character to be matched by the next component in a regular expression pattern. If we are at the end of the pattern, endIndex is one plus the index of the last matched input character. captured is a zero-based array of the strings captured so far by capturing parentheses.
type Capture = oneof {present: String; absent}
type Continuation = REMatch  REResult
A Continuation is a function that attempts to match the remaining portion of the pattern against the input string, starting at the intermediate state given by its REMatch argument. If a match is possible, it returns a success result that contains the final REMatch state; if no match is possible, it returns a failure result.
type Matcher = REInput  REMatch  Integer  Continuation  REResult
A Matcher is a function that attempts to match a middle portion of the pattern against the input string, starting at the intermediate state given by its REMatch argument. Since the remainder of the pattern heavily influences whether (and how) a middle portion will match, we must pass in a Continuation function that checks whether the rest of the pattern matched. If the continuation returns failure, the matcher function may call it repeatedly, trying various alternatives at pattern choice points.
The REInput parameter contains the input string and is merely passed down to subroutines. The Integer parameter contains the number of capturing left parentheses seen so far in the pattern and is used to assign static, consecutive numbers to capturing parentheses.
sequenceMatcher(matcher1: Matcher, parenCount1: Integer, matcher2: Matcher) : Matcher
  = function(t: REInput, x: REMatch, p: Integer, c: Continuation)
         let d: Continuation
                 = function(y: REMatch)
                        matcher2(t, y, p + parenCount1, c)
         in matcher1(t, x, p, d)
sequenceMatcher returns a Matcher that matches the concatenation of the patterns matched by matcher1 and matcher2. parenCount1 is the number of capturing left parentheses inside matcher2's pattern.
characterSetMatcher(acceptanceSet: {Character}) : Matcher
  = function(t: REInput, x: REMatch, p: Integer, c: Continuation)
         let i: Integer = x.endIndex;
             s: String = t.str
         in if i = length(s)
             then failure
             else if s[i]  acceptanceSet
             then c(endIndex (i + 1), captured x.captured)
             else failure
characterSetMatcher returns a Matcher that matches a single input string character. The match succeeds if the character is a member of the acceptanceSet set of characters (possibly ignoring case).
characterMatcher(ch: Character) : Matcher = characterSetMatcher({ch})
characterMatcher returns a Matcher that matches a single input string character. The match succeeds if the character is the same as ch (possibly ignoring case).
Regular Expression Patterns
Syntax
RegularExpressionPattern  Disjunction
Semantics
action Exec[RegularExpressionPattern] : REInput  Integer  REResult
Exec[RegularExpressionPattern  Disjunction](t: REInput, index: Integer)
  = Match[Disjunction](
         t,
         endIndex index, captured fillCapture(CountParens[Disjunction]),
         0,
         
         (function(x: REMatch)
             success x))
fillCapture(i: Integer) : Capture[]
  = if i = 0
     then []Capture
     else fillCapture(i – 1)  [absent]
Disjunctions
Syntax
Disjunction 
	Alternativenormal
|	Alternativenormal | Disjunction
Semantics
action Match[Disjunction] : Matcher
Match[Disjunction  Alternativenormal] = Match[Alternativenormal]
Match[Disjunction  Alternativenormal | Disjunction1]
            (t: REInput, x: REMatch, p: Integer, c: Continuation)
  = case Match[Alternativenormal](t, x, p, c) of
        success(y: REMatch): success y;
        failure: Match[Disjunction1](t, x, p + CountParens[Alternativenormal], c)
        end
action CountParens[Disjunction] : Integer
CountParens[Disjunction  Alternativenormal] = CountParens[Alternativenormal]
CountParens[Disjunction  Alternativenormal | Disjunction1]
  = CountParens[Alternativenormal] + CountParens[Disjunction1]
Quantifiers
Syntax
  {normal, nonDecimalDigit, nonOctalDigit}
Alternative 
	«empty»
|	Assertion Alternativenormal
|	OrdinaryAtom Alternativenormal
|	OneDigitEscape AlternativenonDecimalDigit
|	ShortOctalEscape AlternativenonOctalDigit
|	Atom Quantifier Alternativenormal
Quantifier 
	QuantifierPrefix
|	QuantifierPrefix ?
QuantifierPrefix 
	*
|	+
|	?
|	{ DecimalDigits }
|	{ DecimalDigits , }
|	{ DecimalDigits , DecimalDigits }
DecimalDigits 
	DecimalDigit
|	DecimalDigits DecimalDigit
DecimalDigit  0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
Semantics
type Limit = oneof {finite: Integer; infinite}
resetParens(x: REMatch, p: Integer, nParens: Integer) : REMatch
  = if nParens = 0
     then x
     else let y: REMatch = endIndex x.endIndex, captured x.captured[p  absent]
           in resetParens(y, p + 1, nParens – 1)
repeatMatcher(body: Matcher, min: Integer, max: Limit, lazy: Boolean, nBodyParens: Integer)
  : Matcher
  = function(t: REInput, x: REMatch, p: Integer, c: Continuation)
         if 
             (case max of
                finite(m: Integer): m = 0;
                infinite: false
                end)
         then c(x)
         else let d: Continuation
                       = function(y: REMatch)
                              if min = 0 and (max is infinite and y.endIndex = x.endIndex)
                              then failure
                              else let newMin: Integer
                                            = if min = 0
                                               then 0
                                               else min – 1;
                                        newMax: Limit
                                            = case max of
                                                  finite(m: Integer): finite (m – 1);
                                                  infinite: infinite
                                                  end
                                    in repeatMatcher(body, newMin, newMax, lazy, nBodyParens)(
                                            t,
                                            y,
                                            p,
                                            c);
                   xr: REMatch = resetParens(x, p, nBodyParens)
               in if min ≠ 0
                   then body(t, xr, p, d)
                   else if lazy
                   then case c(x) of
                             success(z: REMatch): success z;
                             failure: body(t, xr, p, d)
                             end
                   else case body(t, xr, p, d) of
                            success(z: REMatch): success z;
                            failure: c(x)
                            end
action Match[Alternative] : Matcher
Match[Alternative  «empty»](t: REInput, x: REMatch, p: Integer, c: Continuation) = c(x)
Match[Alternative  Assertion Alternativenormal1]
            (t: REInput, x: REMatch, p: Integer, c: Continuation)
  = if TestAssertion[Assertion](t, x)
     then Match[Alternativenormal1](t, x, p, c)
     else failure
Match[Alternative  OrdinaryAtom Alternativenormal1]
  = sequenceMatcher(
         Match[OrdinaryAtom],
         CountParens[OrdinaryAtom],
         Match[Alternativenormal1])
Match[Alternative  OneDigitEscape AlternativenonDecimalDigit1]
  = sequenceMatcher(Match[OneDigitEscape], 0, Match[AlternativenonDecimalDigit1])
Match[Alternative  ShortOctalEscape AlternativenonOctalDigit1]
  = sequenceMatcher(Match[ShortOctalEscape], 0, Match[AlternativenonOctalDigit1])
Match[Alternative  Atom Quantifier Alternativenormal1]
  = let min: Integer = Minimum[Quantifier];
         max: Limit = Maximum[Quantifier];
         lazy: Boolean = Lazy[Quantifier]
     in if 
             (case max of
                finite(m: Integer): m < min;
                infinite: false
                end)
         then 
         else let looper: Matcher
                       = repeatMatcher(Match[Atom], min, max, lazy, CountParens[Atom])
               in sequenceMatcher(looper, CountParens[Atom], Match[Alternativenormal1])
action CountParens[Alternative] : Integer
CountParens[Alternative  «empty»] = 0
CountParens[Alternative  Assertion Alternativenormal1]
  = CountParens[Alternativenormal1]
CountParens[Alternative  OrdinaryAtom Alternativenormal1]
  = CountParens[OrdinaryAtom] + CountParens[Alternativenormal1]
CountParens[Alternative  OneDigitEscape AlternativenonDecimalDigit1]
  = CountParens[AlternativenonDecimalDigit1]
CountParens[Alternative  ShortOctalEscape AlternativenonOctalDigit1]
  = CountParens[AlternativenonOctalDigit1]
CountParens[Alternative  Atom Quantifier Alternativenormal1]
  = CountParens[Atom] + CountParens[Alternativenormal1]
action Minimum[Quantifier] : Integer
Minimum[Quantifier  QuantifierPrefix] = Minimum[QuantifierPrefix]
Minimum[Quantifier  QuantifierPrefix ?] = Minimum[QuantifierPrefix]
action Maximum[Quantifier] : Limit
Maximum[Quantifier  QuantifierPrefix] = Maximum[QuantifierPrefix]
Maximum[Quantifier  QuantifierPrefix ?] = Maximum[QuantifierPrefix]
action Lazy[Quantifier] : Boolean
Lazy[Quantifier  QuantifierPrefix] = false
Lazy[Quantifier  QuantifierPrefix ?] = true
action Minimum[QuantifierPrefix] : Integer
Minimum[QuantifierPrefix  *] = 0
Minimum[QuantifierPrefix  +] = 1
Minimum[QuantifierPrefix  ?] = 0
Minimum[QuantifierPrefix  { DecimalDigits }] = IntegerValue[DecimalDigits]
Minimum[QuantifierPrefix  { DecimalDigits , }] = IntegerValue[DecimalDigits]
Minimum[QuantifierPrefix  { DecimalDigits1 , DecimalDigits2 }]
  = IntegerValue[DecimalDigits1]
action Maximum[QuantifierPrefix] : Limit
Maximum[QuantifierPrefix  *] = infinite
Maximum[QuantifierPrefix  +] = infinite
Maximum[QuantifierPrefix  ?] = finite 1
Maximum[QuantifierPrefix  { DecimalDigits }] = finite IntegerValue[DecimalDigits]
Maximum[QuantifierPrefix  { DecimalDigits , }] = infinite
Maximum[QuantifierPrefix  { DecimalDigits1 , DecimalDigits2 }]
  = finite IntegerValue[DecimalDigits2]
action IntegerValue[DecimalDigits] : Integer
IntegerValue[DecimalDigits  DecimalDigit] = DigitValue[DecimalDigit]
IntegerValue[DecimalDigits  DecimalDigits1 DecimalDigit]
  = 10*IntegerValue[DecimalDigits1] + DigitValue[DecimalDigit]
action DigitValue[DecimalDigit] : Integer = digitValue(DecimalDigit)
Assertions
Syntax
Assertion 
	^
|	$
|	\ b
|	\ B
Semantics
action TestAssertion[Assertion] : REInput  REMatch  Boolean
TestAssertion[Assertion  ^](t: REInput, x: REMatch) = x.endIndex = 0
TestAssertion[Assertion  $](t: REInput, x: REMatch) = x.endIndex = length(t.str)
TestAssertion[Assertion  \ b](t: REInput, x: REMatch)
  = atWordBoundary(x.endIndex, t.str)
TestAssertion[Assertion  \ B](t: REInput, x: REMatch)
  = not atWordBoundary(x.endIndex, t.str)
atWordBoundary(i: Integer, s: String) : Boolean
  = i = 0 or (i = length(s) or (s[i – 1]  reWordCharacters xor s[i]  reWordCharacters))
Atoms
Syntax
Atom 
	OrdinaryAtom
|	OneDigitEscape
|	ShortOctalEscape
OrdinaryAtom 
	CompoundAtom
|	PatternCharacter
PatternCharacternormal  NonTerminator except ^ | $ | \ | . | * | + | ? | ( | ) | [ | ] | { | } | |
PatternCharacternonDecimalDigit  PatternCharacternormal except DecimalDigit
PatternCharacternonOctalDigit  PatternCharacternormal except OctalDigit
CompoundAtom 
	( Disjunction )
|	( ? : Disjunction )
|	.
|	CharacterClass
|	CharacterEscape
|	TwoDigitEscape
|	CharacterClassEscape
Semantics
action Match[Atom] : Matcher
Match[Atom  OrdinaryAtom] = Match[OrdinaryAtom]
Match[Atom  OneDigitEscape] = Match[OneDigitEscape]
Match[Atom  ShortOctalEscape] = Match[ShortOctalEscape]
action CountParens[Atom] : Integer
CountParens[Atom  OrdinaryAtom] = CountParens[OrdinaryAtom]
CountParens[Atom  OneDigitEscape] = 0
CountParens[Atom  ShortOctalEscape] = 0
action Match[OrdinaryAtom] : Matcher
Match[OrdinaryAtom  CompoundAtom] = Match[CompoundAtom]
Match[OrdinaryAtom  PatternCharacter] = characterMatcher(PatternCharacter)
action CountParens[OrdinaryAtom] : Integer
CountParens[OrdinaryAtom  CompoundAtom] = CountParens[CompoundAtom]
CountParens[OrdinaryAtom  PatternCharacter] = 0
action Match[CompoundAtom] : Matcher
Match[CompoundAtom  ( Disjunction )]
            (t: REInput, x: REMatch, p: Integer, c: Continuation)
  = let d: Continuation
             = function(y: REMatch)
                    let updatedCaptured: Capture[]
                            = y.captured[p  present t.str[x.endIndex ... y.endIndex – 1]]
                    in c(endIndex y.endIndex, captured updatedCaptured)
     in Match[Disjunction](t, x, p + 1, d)
Match[CompoundAtom  ( ? : Disjunction )] = Match[Disjunction]
Match[CompoundAtom  .] = characterSetMatcher(nonTerminators)
Match[CompoundAtom  CharacterClass](t: REInput, x: REMatch, p: Integer, c: Continuation)
  = let a: {Character} = AcceptanceSet[CharacterClass](length(x.captured))
     in characterSetMatcher(a)(t, x, p, c)
Match[CompoundAtom  CharacterEscape] = characterMatcher(CharacterValue[CharacterEscape])
Match[CompoundAtom  TwoDigitEscape] = Match[TwoDigitEscape]
Match[CompoundAtom  CharacterClassEscape]
  = characterSetMatcher(AcceptanceSet[CharacterClassEscape])
action CountParens[CompoundAtom] : Integer
CountParens[CompoundAtom  ( Disjunction )] = CountParens[Disjunction] + 1
CountParens[CompoundAtom  ( ? : Disjunction )] = CountParens[Disjunction]
CountParens[CompoundAtom  .] = 0
CountParens[CompoundAtom  CharacterClass] = 0
CountParens[CompoundAtom  CharacterEscape] = 0
CountParens[CompoundAtom  TwoDigitEscape] = 0
CountParens[CompoundAtom  CharacterClassEscape] = 0
Escapes
Syntax
CharacterEscape 
	ControlEscape
|	\ c ControlLetter
|	ThreeDigitEscape
|	HexEscape
|	\ IdentityEscape
ControlLetter 
	A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
|	a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x | y | z
IdentityEscape  NonTerminator except UnicodeAlphanumeric
ControlEscape 
	\ f
|	\ n
|	\ r
|	\ t
|	\ v
Semantics
action CharacterValue[CharacterEscape] : Character
CharacterValue[CharacterEscape  ControlEscape] = CharacterValue[ControlEscape]
CharacterValue[CharacterEscape  \ c ControlLetter]
  = codeToCharacter(bitwiseAnd(characterToCode(ControlLetter), 31))
CharacterValue[CharacterEscape  ThreeDigitEscape] = CharacterValue[ThreeDigitEscape]
CharacterValue[CharacterEscape  HexEscape] = CharacterValue[HexEscape]
CharacterValue[CharacterEscape  \ IdentityEscape] = IdentityEscape
action CharacterValue[ControlEscape] : Character
CharacterValue[ControlEscape  \ f] = ‘«FF»’
CharacterValue[ControlEscape  \ n] = ‘«LF»’
CharacterValue[ControlEscape  \ r] = ‘«CR»’
CharacterValue[ControlEscape  \ t] = ‘«TAB»’
CharacterValue[ControlEscape  \ v] = ‘«VT»’
Numeric Escapes
Syntax
OneDigitEscape  \ DecimalDigit
ShortOctalEscape  \ ZeroToThree OctalDigit
TwoDigitEscape 
	\ ZeroToThree EightOrNine
|	\ FourToNine DecimalDigit
ThreeDigitEscape  \ ZeroToThree OctalDigit OctalDigit
ZeroToThree  0 | 1 | 2 | 3
FourToNine  4 | 5 | 6 | 7 | 8 | 9
OctalDigit  0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
EightOrNine  8 | 9
Semantics
backreferenceMatcher(n: Integer) : Matcher
  = function(t: REInput, x: REMatch, p: Integer, c: Continuation)
         case nthBackreference(x, n) of
            present(ref: String):
                  let i: Integer = x.endIndex;
                      s: String = t.str
                  in let j: Integer = i + length(ref)
                  in if j > length(s)
                      then failure
                      else if s[i ... j – 1] = ref
                      then c(endIndex j, captured x.captured)
                      else failure;
            absent: failure
            end
nthBackreference(x: REMatch, n: Integer) : Capture
  = if n > 0 and n ≤ length(x.captured)
     then x.captured[n – 1]
     else 
action Match[OneDigitEscape] : Matcher
Match[OneDigitEscape  \ DecimalDigit]
  = let n: Integer = DigitValue[DecimalDigit]
     in if n = 0
         then characterMatcher(‘«NUL»’)
         else backreferenceMatcher(n)
action CharacterValue[ShortOctalEscape] : Integer  Character
CharacterValue[ShortOctalEscape  \ ZeroToThree OctalDigit](nCapturingParens: Integer)
  = let n: Integer = 10*DigitValue[ZeroToThree] + DigitValue[OctalDigit]
     in if n ≥ 10 and n ≤ nCapturingParens
         then 
         else codeToCharacter(8*DigitValue[ZeroToThree] + DigitValue[OctalDigit])
action Match[ShortOctalEscape] : Matcher
Match[ShortOctalEscape  \ ZeroToThree OctalDigit]
            (t: REInput, x: REMatch, p: Integer, c: Continuation)
  = let n: Integer = 10*DigitValue[ZeroToThree] + DigitValue[OctalDigit]
     in if n ≥ 10 and n ≤ length(x.captured)
         then backreferenceMatcher(n)(t, x, p, c)
         else characterMatcher(
                   codeToCharacter(8*DigitValue[ZeroToThree] + DigitValue[OctalDigit]))(
                   t,
                   x,
                   p,
                   c)
action Match[TwoDigitEscape] : Matcher
Match[TwoDigitEscape  \ ZeroToThree EightOrNine]
  = backreferenceMatcher(10*DigitValue[ZeroToThree] + DigitValue[EightOrNine])
Match[TwoDigitEscape  \ FourToNine DecimalDigit]
  = backreferenceMatcher(10*DigitValue[FourToNine] + DigitValue[DecimalDigit])
action CharacterValue[ThreeDigitEscape] : Character
CharacterValue[ThreeDigitEscape  \ ZeroToThree OctalDigit1 OctalDigit2]
  = codeToCharacter(
         64*DigitValue[ZeroToThree] + 8*DigitValue[OctalDigit1] + DigitValue[OctalDigit2])
action DigitValue[ZeroToThree] : Integer = digitValue(ZeroToThree)
action DigitValue[FourToNine] : Integer = digitValue(FourToNine)
action DigitValue[OctalDigit] : Integer = digitValue(OctalDigit)
action DigitValue[EightOrNine] : Integer = digitValue(EightOrNine)
Syntax
HexEscape 
	\ x HexDigit HexDigit
|	\ u HexDigit HexDigit HexDigit HexDigit
HexDigit  0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | a | b | c | d | e | f
Semantics
action CharacterValue[HexEscape] : Character
CharacterValue[HexEscape  \ x HexDigit1 HexDigit2]
  = codeToCharacter(16*HexValue[HexDigit1] + HexValue[HexDigit2])
CharacterValue[HexEscape  \ u HexDigit1 HexDigit2 HexDigit3 HexDigit4]
  = codeToCharacter(
         4096*HexValue[HexDigit1] + 256*HexValue[HexDigit2] + 16*HexValue[HexDigit3] +
         HexValue[HexDigit4])
action DigitValue[HexDigit] : Integer = digitValue(HexDigit)
Character Class Escapes
Syntax
CharacterClassEscape 
	\ s
|	\ S
|	\ d
|	\ D
|	\ w
|	\ W
Semantics
action AcceptanceSet[CharacterClassEscape] : {Character}
AcceptanceSet[CharacterClassEscape  \ s] = reWhitespaces
AcceptanceSet[CharacterClassEscape  \ S] = {‘«NUL»’ ... ‘«uFFFF»’} – reWhitespaces
AcceptanceSet[CharacterClassEscape  \ d] = reDigits
AcceptanceSet[CharacterClassEscape  \ D] = {‘«NUL»’ ... ‘«uFFFF»’} – reDigits
AcceptanceSet[CharacterClassEscape  \ w] = reWordCharacters
AcceptanceSet[CharacterClassEscape  \ W] = {‘«NUL»’ ... ‘«uFFFF»’} – reWordCharacters
User-Specified Character Classes
Syntax
  {any, noCaret, noDash}
CharacterClass 
	[ ClassRangesnoCaret ]
|	[ ^ ClassRangesany ]
ClassRanges 
	«empty»
|	RangeList,normal
RangeList, 
	FinalRangeAtom,
|	OrdinaryRangeAtom, RangeListSuffixnormal
|	ZeroEscape RangeListSuffixnonDecimalDigit
|	ShortOctalEscape RangeListSuffixnonOctalDigit
RangeListSuffix 
	RangeListnoDash,
|	- RangeAtomany,normal
|	- OrdinaryRangeAtomany,normal RangeListany,normal
|	- ZeroEscape RangeListany,nonDecimalDigit
|	- ShortOctalEscape RangeListany,nonOctalDigit
Semantics
action AcceptanceSet[CharacterClass] : Integer  {Character}
AcceptanceSet[CharacterClass  [ ClassRangesnoCaret ]](nCapturingParens: Integer)
  = AcceptanceSet[ClassRangesnoCaret](nCapturingParens)
AcceptanceSet[CharacterClass  [ ^ ClassRangesany ]](nCapturingParens: Integer)
  = {‘«NUL»’ ... ‘«uFFFF»’} – AcceptanceSet[ClassRangesany](nCapturingParens)
action AcceptanceSet[ClassRanges] : Integer  {Character}
AcceptanceSet[ClassRanges  «empty»](nCapturingParens: Integer) = {}Character
AcceptanceSet[ClassRanges  RangeList,normal](nCapturingParens: Integer)
  = AcceptanceSet[RangeList,normal](nCapturingParens)
action AcceptanceSet[RangeList,] : Integer  {Character}
AcceptanceSet[RangeList,  FinalRangeAtom,](nCapturingParens: Integer)
  = AcceptanceSet[FinalRangeAtom,](nCapturingParens)
AcceptanceSet[RangeList,  OrdinaryRangeAtom, RangeListSuffixnormal]
            (nCapturingParens: Integer)
  = let a: {Character} = AcceptanceSet[OrdinaryRangeAtom,]
     in AcceptanceSet[RangeListSuffixnormal](nCapturingParens, a)
AcceptanceSet[RangeList,  ZeroEscape RangeListSuffixnonDecimalDigit]
            (nCapturingParens: Integer)
  = let a: {Character} = {CharacterValue[ZeroEscape]}
     in AcceptanceSet[RangeListSuffixnonDecimalDigit](nCapturingParens, a)
AcceptanceSet[RangeList,  ShortOctalEscape RangeListSuffixnonOctalDigit]
            (nCapturingParens: Integer)
  = let a: {Character} = {CharacterValue[ShortOctalEscape](nCapturingParens)}
     in AcceptanceSet[RangeListSuffixnonOctalDigit](nCapturingParens, a)
action AcceptanceSet[RangeListSuffix] : Integer  {Character}  {Character}
AcceptanceSet[RangeListSuffix  RangeListnoDash,]
            (nCapturingParens: Integer, low: {Character})
  = low  AcceptanceSet[RangeListnoDash,](nCapturingParens)
AcceptanceSet[RangeListSuffix  - RangeAtomany,normal]
            (nCapturingParens: Integer, low: {Character})
  = characterRange(low, AcceptanceSet[RangeAtomany,normal](nCapturingParens))
AcceptanceSet[RangeListSuffix  - OrdinaryRangeAtomany,normal RangeListany,normal]
            (nCapturingParens: Integer, low: {Character})
  = let range: {Character}
             = characterRange(low, AcceptanceSet[OrdinaryRangeAtomany,normal])
     in range  AcceptanceSet[RangeListany,normal](nCapturingParens)
AcceptanceSet[RangeListSuffix  - ZeroEscape RangeListany,nonDecimalDigit]
            (nCapturingParens: Integer, low: {Character})
  = let range: {Character} = characterRange(low, {CharacterValue[ZeroEscape]})
     in range  AcceptanceSet[RangeListany,nonDecimalDigit](nCapturingParens)
AcceptanceSet[RangeListSuffix  - ShortOctalEscape RangeListany,nonOctalDigit]
            (nCapturingParens: Integer, low: {Character})
  = let range: {Character}
             = characterRange(low, {CharacterValue[ShortOctalEscape](nCapturingParens)})
     in range  AcceptanceSet[RangeListany,nonOctalDigit](nCapturingParens)
characterRange(low: {Character}, high: {Character}) : {Character}
  = if (|low|) ≠ 1 or (|high|) ≠ 1
     then 
     else let l: Character = min low;
               h: Character = min high
           in if l ≤ h
               then {l ... h}
               else 
Character Class Range Atoms
Syntax
FinalRangeAtomany,  RangeAtomany,
FinalRangeAtomnoCaret,  RangeAtomnoCaret,
FinalRangeAtomnoDash,  RangeAtomany,
RangeAtom, 
	OrdinaryRangeAtom,
|	ZeroEscape
|	ShortOctalEscape
OrdinaryRangeAtom, 
	RangeCharacter,
|	RangeEscape
RangeCharacterany,normal  NonTerminator except \ | ]
RangeCharacterany,nonDecimalDigit  RangeCharacterany,normal except DecimalDigit
RangeCharacterany,nonOctalDigit  RangeCharacterany,normal except OctalDigit
RangeCharacternoCaret,normal  RangeCharacterany,normal except ^
RangeCharacternoDash,normal  RangeCharacterany,normal except -
RangeCharacternoDash,nonDecimalDigit  RangeCharacternoDash,normal except DecimalDigit
RangeCharacternoDash,nonOctalDigit  RangeCharacternoDash,normal except OctalDigit
RangeEscape 
	\ b
|	CharacterEscape
|	CharacterClassEscape
ZeroEscape  \ 0
Semantics
action AcceptanceSet[FinalRangeAtom,] : Integer  {Character}
AcceptanceSet[FinalRangeAtomany,  RangeAtomany,](nCapturingParens: Integer)
  = AcceptanceSet[RangeAtomany,](nCapturingParens)
AcceptanceSet[FinalRangeAtomnoCaret,  RangeAtomnoCaret,](nCapturingParens: Integer)
  = AcceptanceSet[RangeAtomnoCaret,](nCapturingParens)
AcceptanceSet[FinalRangeAtomnoDash,  RangeAtomany,](nCapturingParens: Integer)
  = AcceptanceSet[RangeAtomany,](nCapturingParens)
action AcceptanceSet[RangeAtom,] : Integer  {Character}
AcceptanceSet[RangeAtom,  OrdinaryRangeAtom,](nCapturingParens: Integer)
  = AcceptanceSet[OrdinaryRangeAtom,]
AcceptanceSet[RangeAtom,  ZeroEscape](nCapturingParens: Integer)
  = {CharacterValue[ZeroEscape]}
AcceptanceSet[RangeAtom,  ShortOctalEscape](nCapturingParens: Integer)
  = {CharacterValue[ShortOctalEscape](nCapturingParens)}
action AcceptanceSet[OrdinaryRangeAtom,] : {Character}
AcceptanceSet[OrdinaryRangeAtom,  RangeCharacter,] = {RangeCharacter,}
AcceptanceSet[OrdinaryRangeAtom,  RangeEscape] = AcceptanceSet[RangeEscape]
action AcceptanceSet[RangeEscape] : {Character}
AcceptanceSet[RangeEscape  \ b] = {‘«BS»’}
AcceptanceSet[RangeEscape  CharacterEscape] = {CharacterValue[CharacterEscape]}
AcceptanceSet[RangeEscape  CharacterClassEscape] = AcceptanceSet[CharacterClassEscape]
action CharacterValue[ZeroEscape] : Character
CharacterValue[ZeroEscape  \ 0] = ‘«NUL»’