@@ -52,7 +52,35 @@ module Make<LocationSig Location, InputSig<Location> Input> {
5252 /** Gets the rank of element `e`, which is used internally in the string encoding. */
5353 int getRank ( Element e ) { e = DenseRank< DenseRankInput > :: denseRank ( result ) }
5454
55- private string encode ( Element e ) { result = getRank ( e ) .toString ( ) }
55+ pragma [ nomagic]
56+ private string interpretUnicodeCodePoint ( int codePoint ) {
57+ codePoint = [ 0 , getRank ( _) ] and
58+ codePoint .toUnicode ( ) = result and
59+ result != "." // used as element separator
60+ }
61+
62+ private int unicodeCodePoints ( ) { result = strictcount ( interpretUnicodeCodePoint ( _) ) }
63+
64+ private int getUnicodeCodePointPart ( Element e , int i ) {
65+ result = getRank ( e ) and
66+ i = 0
67+ or
68+ exists ( int mid |
69+ mid = getUnicodeCodePointPart ( e , i - 1 ) and
70+ mid > 0 and
71+ result = mid / unicodeCodePoints ( )
72+ )
73+ }
74+
75+ pragma [ nomagic]
76+ private string encode ( Element e ) {
77+ result =
78+ strictconcat ( string s , int i |
79+ s = interpretUnicodeCodePoint ( getUnicodeCodePointPart ( e , i ) % unicodeCodePoints ( ) )
80+ |
81+ s order by i
82+ )
83+ }
5684
5785 bindingset [ s]
5886 private Element decode ( string s ) { encode ( result ) = s }
@@ -88,7 +116,7 @@ module Make<LocationSig Location, InputSig<Location> Input> {
88116 // Same as
89117 // `result = count(this.indexOf("."))`
90118 // but performs better because it doesn't use an aggregate
91- result = this .regexpReplaceAll ( "[0-9 ]+" , "" ) .length ( )
119+ result = this .regexpReplaceAll ( "[^\\. ]+" , "" ) .length ( )
92120 }
93121
94122 /** Gets the list obtained by appending `suffix` onto this list. */
@@ -123,7 +151,7 @@ module Make<LocationSig Location, InputSig<Location> Input> {
123151 // `regexpCapture` will then always join in both groups, only to afterwards filter
124152 // based on the requested group (the group number is not part of the binding set
125153 // of `regexpCapture`)
126- elem = this .regexpCapture ( "^([0-9 ]+)\\..*$" , 1 ) and
154+ elem = this .regexpCapture ( "^([^\\. ]+)\\..*$" , 1 ) and
127155 e = decode ( elem ) and
128156 suffix = this .suffix ( elem .length ( ) + 1 )
129157 )
@@ -133,7 +161,7 @@ module Make<LocationSig Location, InputSig<Location> Input> {
133161 bindingset [ this ]
134162 predicate isSnoc ( UnboundList prefix , Element e ) {
135163 // same remark as above about not using multiple capture groups
136- prefix = this .regexpCapture ( "^(|.+\\.)[0-9 ]+\\.$" , 1 ) and
164+ prefix = this .regexpCapture ( "^(|.+\\.)[^\\. ]+\\.$" , 1 ) and
137165 e = decode ( this .substring ( prefix .stringLength ( ) , this .stringLength ( ) - 1 ) )
138166 }
139167
@@ -148,7 +176,7 @@ module Make<LocationSig Location, InputSig<Location> Input> {
148176 */
149177 bindingset [ this ]
150178 UnboundList getProperPrefix ( int i ) {
151- exists ( string regexp , int occurrenceOffset | regexp = "[0-9 ]+\\." |
179+ exists ( string regexp , int occurrenceOffset | regexp = "[^\\. ]+\\." |
152180 exists ( this .regexpFind ( regexp , i , occurrenceOffset ) ) and
153181 result = this .prefix ( occurrenceOffset )
154182 )
0 commit comments