regex: Refactor predefined character classes.
This commit is contained in:
+1
-11
@@ -9,21 +9,15 @@ fun codePointToString(codePoint: Int): String {
|
|||||||
return fromCharArray(charArray, 0, charArray.size)
|
return fromCharArray(charArray, 0, charArray.size)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun box() {}
|
|
||||||
|
|
||||||
// TODO: Here is a performance problem: an execution of this test requires much more time than it in Kotlin/JVM.
|
// TODO: Here is a performance problem: an execution of this test requires much more time than it in Kotlin/JVM.
|
||||||
fun box1() {
|
fun box() {
|
||||||
// Regression for HARMONY-3145
|
// Regression for HARMONY-3145
|
||||||
var p = Regex("(\\p{all})+")
|
var p = Regex("(\\p{all})+")
|
||||||
var res = true
|
var res = true
|
||||||
var cnt = 0
|
var cnt = 0
|
||||||
var s: String
|
var s: String
|
||||||
for (i in 0..1114111) {
|
for (i in 0..1114111) {
|
||||||
if (i % 200000 == 0) {
|
|
||||||
println(i)
|
|
||||||
}
|
|
||||||
s = codePointToString(i)
|
s = codePointToString(i)
|
||||||
// if (!s.matches(p.toString().toRegex())) { TODO: Uncomment when caching is done.
|
|
||||||
if (!s.matches(p)) {
|
if (!s.matches(p)) {
|
||||||
cnt++
|
cnt++
|
||||||
res = false
|
res = false
|
||||||
@@ -37,11 +31,7 @@ fun box1() {
|
|||||||
cnt = 0
|
cnt = 0
|
||||||
|
|
||||||
for (i in 0..1114111) {
|
for (i in 0..1114111) {
|
||||||
if (i % 200000 == 0) {
|
|
||||||
println(i)
|
|
||||||
}
|
|
||||||
s = codePointToString(i)
|
s = codePointToString(i)
|
||||||
// if (!s.matches(p.toString().toRegex())) { TODO: Uncomment when caching is done.
|
|
||||||
if (!s.matches(p)) {
|
if (!s.matches(p)) {
|
||||||
cnt++
|
cnt++
|
||||||
res = false
|
res = false
|
||||||
|
|||||||
@@ -65,13 +65,12 @@ internal abstract class AbstractCharClass : SpecialToken() {
|
|||||||
* Returns BitSet representing this character class or `null`
|
* Returns BitSet representing this character class or `null`
|
||||||
* if this character class does not have character representation;
|
* if this character class does not have character representation;
|
||||||
*/
|
*/
|
||||||
// TODO: @C++?. Or implement a BitSet
|
|
||||||
open internal val bits: BitSet?
|
open internal val bits: BitSet?
|
||||||
get() = null
|
get() = null
|
||||||
|
|
||||||
fun hasLowHighSurrogates(): Boolean {
|
fun hasLowHighSurrogates(): Boolean {
|
||||||
return if (altSurrogates)
|
return if (altSurrogates)
|
||||||
lowHighSurrogates.nextClearBit(0) != -1 // TODO: What if the bitset is empty?
|
lowHighSurrogates.nextClearBit(0) != -1
|
||||||
else
|
else
|
||||||
lowHighSurrogates.nextSetBit(0) != -1
|
lowHighSurrogates.nextSetBit(0) != -1
|
||||||
}
|
}
|
||||||
@@ -81,7 +80,6 @@ internal abstract class AbstractCharClass : SpecialToken() {
|
|||||||
open val instance: AbstractCharClass
|
open val instance: AbstractCharClass
|
||||||
get() = this
|
get() = this
|
||||||
|
|
||||||
// TODO: refactor
|
|
||||||
val surrogates: AbstractCharClass by lazy {
|
val surrogates: AbstractCharClass by lazy {
|
||||||
val result = object : AbstractCharClass() {
|
val result = object : AbstractCharClass() {
|
||||||
override fun contains(ch: Int): Boolean {
|
override fun contains(ch: Int): Boolean {
|
||||||
@@ -98,7 +96,6 @@ internal abstract class AbstractCharClass : SpecialToken() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO: refactor
|
|
||||||
val withoutSurrogates: AbstractCharClass by lazy {
|
val withoutSurrogates: AbstractCharClass by lazy {
|
||||||
val result = object : AbstractCharClass() {
|
val result = object : AbstractCharClass() {
|
||||||
override fun contains(ch: Int): Boolean {
|
override fun contains(ch: Int): Boolean {
|
||||||
@@ -109,7 +106,6 @@ internal abstract class AbstractCharClass : SpecialToken() {
|
|||||||
else
|
else
|
||||||
false
|
false
|
||||||
|
|
||||||
|
|
||||||
return this@AbstractCharClass.contains(ch) && !containslHS
|
return this@AbstractCharClass.contains(ch) && !containslHS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -125,7 +121,6 @@ internal abstract class AbstractCharClass : SpecialToken() {
|
|||||||
* Although this method will not alternate all the already set characters,
|
* Although this method will not alternate all the already set characters,
|
||||||
* just overall meaning of the class.
|
* just overall meaning of the class.
|
||||||
*/
|
*/
|
||||||
// TODO: replace with a property
|
|
||||||
fun setNegative(value: Boolean): AbstractCharClass {
|
fun setNegative(value: Boolean): AbstractCharClass {
|
||||||
if (alt xor value) {
|
if (alt xor value) {
|
||||||
alt = !alt
|
alt = !alt
|
||||||
@@ -141,8 +136,7 @@ internal abstract class AbstractCharClass : SpecialToken() {
|
|||||||
return alt
|
return alt
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: replace getValue with property access?
|
internal abstract class CachedCharClass {
|
||||||
internal abstract class LazyCharClass {
|
|
||||||
private val posValue: AbstractCharClass by lazy { computeValue() }
|
private val posValue: AbstractCharClass by lazy { computeValue() }
|
||||||
private val negValue: AbstractCharClass by lazy { computeValue().setNegative(true) }
|
private val negValue: AbstractCharClass by lazy { computeValue().setNegative(true) }
|
||||||
|
|
||||||
@@ -150,147 +144,113 @@ internal abstract class AbstractCharClass : SpecialToken() {
|
|||||||
protected abstract fun computeValue(): AbstractCharClass
|
protected abstract fun computeValue(): AbstractCharClass
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class LazyDigit : LazyCharClass() {
|
internal class CachedDigit : CachedCharClass() {
|
||||||
override fun computeValue(): AbstractCharClass {
|
override fun computeValue(): AbstractCharClass = CharClass().add('0', '9')
|
||||||
return CharClass().add('0', '9')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: DO we need it? But we have LazyCharCLass.negValue. May be it's connected with mayContainSupplCodepoints?
|
internal class CachedNonDigit : CachedCharClass() {
|
||||||
// TODO: Don't use bitmaps in preset classes?
|
override fun computeValue(): AbstractCharClass =
|
||||||
internal class LazyNonDigit : LazyCharClass() {
|
CharClass().add('0', '9').setNegative(true).apply { mayContainSupplCodepoints = true }
|
||||||
override fun computeValue(): AbstractCharClass {
|
|
||||||
val result = CharClass().add('0', '9').setNegative(true)
|
|
||||||
|
|
||||||
result.mayContainSupplCodepoints = true
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class LazySpace : LazyCharClass() {
|
internal class CachedSpace : CachedCharClass() {
|
||||||
override fun computeValue(): AbstractCharClass {
|
/* 9-13 - \t\n\x0B\f\r; 32 - ' ' */
|
||||||
/* 9-13 - \t\n\x0B\f\r; 32 - ' ' */
|
override fun computeValue(): AbstractCharClass = CharClass().add(9, 13).add(32)
|
||||||
return CharClass().add(9, 13).add(32)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class LazyNonSpace : LazyCharClass() {
|
internal class CachedNonSpace : CachedCharClass() {
|
||||||
override fun computeValue(): AbstractCharClass {
|
override fun computeValue(): AbstractCharClass =
|
||||||
val result = LazySpace().getValue(negative = true)
|
CachedSpace().getValue(negative = true).apply { mayContainSupplCodepoints = true }
|
||||||
|
|
||||||
result.mayContainSupplCodepoints = true
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class LazyWord : LazyCharClass() {
|
internal class CachedWord : CachedCharClass() {
|
||||||
override fun computeValue(): AbstractCharClass {
|
override fun computeValue(): AbstractCharClass = CharClass().add('a', 'z').add('A', 'Z').add('0', '9').add('_')
|
||||||
return CharClass().add('a', 'z').add('A', 'Z').add('0', '9')
|
|
||||||
.add('_')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class LazyNonWord : LazyCharClass() {
|
internal class CachedNonWord : CachedCharClass() {
|
||||||
override fun computeValue(): AbstractCharClass {
|
override fun computeValue(): AbstractCharClass =
|
||||||
val result = LazyWord().getValue(negative = true)
|
CachedWord().getValue(negative = true).apply { mayContainSupplCodepoints = true }
|
||||||
|
|
||||||
result.mayContainSupplCodepoints = true
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: It is only for latin in Harmony.
|
internal class CachedLower : CachedCharClass() {
|
||||||
internal class LazyLower : LazyCharClass() {
|
override fun computeValue(): AbstractCharClass = CharClass().add('a', 'z')
|
||||||
override fun computeValue(): AbstractCharClass {
|
|
||||||
return CharClass().add('a', 'z')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class LazyUpper : LazyCharClass() {
|
internal class CachedUpper : CachedCharClass() {
|
||||||
override fun computeValue(): AbstractCharClass {
|
override fun computeValue(): AbstractCharClass = CharClass().add('A', 'Z')
|
||||||
return CharClass().add('A', 'Z')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class LazyASCII : LazyCharClass() {
|
internal class CachedASCII : CachedCharClass() {
|
||||||
override fun computeValue(): AbstractCharClass {
|
override fun computeValue(): AbstractCharClass = CharClass().add(0x00, 0x7F)
|
||||||
return CharClass().add(0x00, 0x7F)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class LazyAlpha : LazyCharClass() {
|
internal class CachedAlpha : CachedCharClass() {
|
||||||
override fun computeValue(): AbstractCharClass {
|
override fun computeValue(): AbstractCharClass = CharClass().add('a', 'z').add('A', 'Z')
|
||||||
return CharClass().add('a', 'z').add('A', 'Z')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class LazyAlnum : LazyCharClass() {
|
internal class CachedAlnum : CachedCharClass() {
|
||||||
override fun computeValue(): AbstractCharClass {
|
override fun computeValue(): AbstractCharClass =
|
||||||
// TODO: Get rid of the cast?
|
(CachedAlpha().getValue(negative = false) as CharClass).add('0', '9')
|
||||||
return (LazyAlpha().getValue(negative = false) as CharClass).add('0', '9')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class LazyPunct : LazyCharClass() {
|
internal class CachedPunct : CachedCharClass() {
|
||||||
override fun computeValue(): AbstractCharClass {
|
/* Punctuation !"#$%&'()*+,-./:;<=>?@ [\]^_` {|}~ */
|
||||||
/* Punctuation !"#$%&'()*+,-./:;<=>?@ [\]^_` {|}~ */
|
override fun computeValue(): AbstractCharClass = CharClass().add(0x21, 0x40).add(0x5B, 0x60).add(0x7B, 0x7E)
|
||||||
return CharClass().add(0x21, 0x40).add(0x5B, 0x60).add(0x7B,
|
|
||||||
0x7E)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class LazyGraph : LazyCharClass() {
|
internal class CachedGraph : CachedCharClass() {
|
||||||
override fun computeValue(): AbstractCharClass {
|
/* plus punctuation */
|
||||||
/* plus punctuation */
|
override fun computeValue(): AbstractCharClass =
|
||||||
return (LazyAlnum().getValue(negative = false) as CharClass)
|
(CachedAlnum().getValue(negative = false) as CharClass)
|
||||||
.add(0x21, 0x40)
|
.add(0x21, 0x40)
|
||||||
.add(0x5B, 0x60)
|
.add(0x5B, 0x60)
|
||||||
.add(0x7B, 0x7E)
|
.add(0x7B, 0x7E)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class LazyPrint : LazyCharClass() {
|
internal class CachedPrint : CachedCharClass() {
|
||||||
override fun computeValue(): AbstractCharClass {
|
override fun computeValue(): AbstractCharClass =
|
||||||
return (LazyGraph().getValue(negative = true) as CharClass).add(0x20)
|
(CachedGraph().getValue(negative = true) as CharClass).add(0x20)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class LazyBlank : LazyCharClass() {
|
internal class CachedBlank : CachedCharClass() {
|
||||||
override fun computeValue(): AbstractCharClass {
|
override fun computeValue(): AbstractCharClass = CharClass().add(' ').add('\t')
|
||||||
return CharClass().add(' ').add('\t')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class LazyCntrl : LazyCharClass() {
|
internal class CachedCntrl : CachedCharClass() {
|
||||||
override fun computeValue(): AbstractCharClass {
|
override fun computeValue(): AbstractCharClass = CharClass().add(0x00, 0x1F).add(0x7F)
|
||||||
return CharClass().add(0x00, 0x1F).add(0x7F)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class LazyXDigit : LazyCharClass() {
|
internal class CachedXDigit : CachedCharClass() {
|
||||||
override fun computeValue(): AbstractCharClass {
|
override fun computeValue(): AbstractCharClass = CharClass().add('0', '9').add('a', 'f').add('A', 'F')
|
||||||
return CharClass().add('0', '9').add('a', 'f').add('A', 'F')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class LazyRange(var start: Int, var end: Int) : LazyCharClass() {
|
internal class CachedRange(var start: Int, var end: Int) : CachedCharClass() {
|
||||||
|
override fun computeValue(): AbstractCharClass =
|
||||||
public override fun computeValue(): AbstractCharClass {
|
object: AbstractCharClass() {
|
||||||
val chCl = CharClass().add(start, end)
|
override fun contains(ch: Int): Boolean = alt xor (ch in start..end)
|
||||||
return chCl
|
}.apply {
|
||||||
}
|
if (end >= Char.MIN_SUPPLEMENTARY_CODE_POINT) {
|
||||||
|
mayContainSupplCodepoints = true
|
||||||
|
}
|
||||||
|
val minSurrogate = Char.MIN_SURROGATE.toInt()
|
||||||
|
val maxSurrogate = Char.MAX_SURROGATE.toInt()
|
||||||
|
// There is an intersection with surrogate characters.
|
||||||
|
if (end >= minSurrogate && start <= maxSurrogate && start <= end) {
|
||||||
|
val surrogatesStart = maxOf(start, minSurrogate) - minSurrogate
|
||||||
|
val surrogatesEnd = minOf(end, maxSurrogate) - minSurrogate
|
||||||
|
lowHighSurrogates.set(surrogatesStart..surrogatesEnd)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class LazySpecialsBlock : LazyCharClass() {
|
internal class CachedSpecialsBlock : CachedCharClass() {
|
||||||
public override fun computeValue(): AbstractCharClass {
|
public override fun computeValue(): AbstractCharClass = CharClass().add(0xFEFF, 0xFEFF).add(0xFFF0, 0xFFFD)
|
||||||
return CharClass().add(0xFEFF, 0xFEFF).add(0xFFF0, 0xFFFD)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class LazyCategoryScope(
|
internal class CachedCategoryScope(
|
||||||
val category: Int,
|
val category: Int,
|
||||||
val mayContainSupplCodepoints: Boolean,
|
val mayContainSupplCodepoints: Boolean,
|
||||||
val containsAllSurrogates: Boolean = false) : LazyCharClass() {
|
val containsAllSurrogates: Boolean = false) : CachedCharClass() {
|
||||||
|
|
||||||
override fun computeValue(): AbstractCharClass {
|
override fun computeValue(): AbstractCharClass {
|
||||||
val result = UnicodeCategoryScope(category)
|
val result = UnicodeCategoryScope(category)
|
||||||
@@ -303,10 +263,10 @@ internal abstract class AbstractCharClass : SpecialToken() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class LazyCategory(
|
internal class CachedCategory(
|
||||||
val category: Int,
|
val category: Int,
|
||||||
val mayContainSupplCodepoints: Boolean,
|
val mayContainSupplCodepoints: Boolean,
|
||||||
val containsAllSurrogates: Boolean = false) : LazyCharClass() {
|
val containsAllSurrogates: Boolean = false) : CachedCharClass() {
|
||||||
|
|
||||||
override fun computeValue(): AbstractCharClass {
|
override fun computeValue(): AbstractCharClass {
|
||||||
val result = UnicodeCategory(category)
|
val result = UnicodeCategory(category)
|
||||||
@@ -318,236 +278,229 @@ internal abstract class AbstractCharClass : SpecialToken() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------
|
|
||||||
// Static methods and predefined classes
|
|
||||||
// -----------------------------------------------------------------
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
//Char.MAX_SURROGATE - Char.MIN_SURROGATE + 1
|
//Char.MAX_SURROGATE - Char.MIN_SURROGATE + 1
|
||||||
var SURROGATE_CARDINALITY = 2048
|
const val SURROGATE_CARDINALITY = 2048
|
||||||
|
|
||||||
var space: LazyCharClass = LazySpace()
|
private var classCache: MutableMap<String, CachedCharClass>? = null
|
||||||
var digit: LazyCharClass = LazyDigit()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* character classes generated from
|
* Character classes.
|
||||||
* http://www.unicode.org/reports/tr18/
|
* See http://www.unicode.org/reports/tr18/, http://www.unicode.org/Public/4.1.0/ucd/Blocks.txt
|
||||||
* http://www.unicode.org/Public/4.1.0/ucd/Blocks.txt
|
|
||||||
*/
|
*/
|
||||||
// TODO: @C++ Harmony uses ListResourceBundle class here. TODO: perfrom a effector lookup on the C++ side.
|
// TODO: Make a faster implementation.
|
||||||
// Temporary solution: when
|
fun createClass(name: String) : CachedCharClass =
|
||||||
// TODO: @C++. Or make it in code. Or do something else.
|
when (name) {
|
||||||
// We can lazily create objects of char classes in C++ hashmap or Array.
|
"Lower" -> CachedLower()
|
||||||
// The main point of it is laziness
|
"Upper" -> CachedUpper()
|
||||||
fun getClass(name: String) : LazyCharClass {
|
"ASCII" -> CachedASCII()
|
||||||
|
"Alpha" -> CachedAlpha()
|
||||||
|
"Digit" -> CachedDigit()
|
||||||
|
"Alnum" -> CachedAlnum()
|
||||||
|
"Punct" -> CachedPunct()
|
||||||
|
"Graph" -> CachedGraph()
|
||||||
|
"Print" -> CachedPrint()
|
||||||
|
"Blank" -> CachedBlank()
|
||||||
|
"Cntrl" -> CachedCntrl()
|
||||||
|
"XDigit" -> CachedXDigit()
|
||||||
|
"Space" -> CachedSpace()
|
||||||
|
"w" -> CachedWord()
|
||||||
|
"W" -> CachedNonWord()
|
||||||
|
"s" -> CachedSpace()
|
||||||
|
"S" -> CachedNonSpace()
|
||||||
|
"d" -> CachedDigit()
|
||||||
|
"D" -> CachedNonDigit()
|
||||||
|
"BasicLatin" -> CachedRange(0x0000, 0x007F)
|
||||||
|
"Latin-1Supplement" -> CachedRange(0x0080, 0x00FF)
|
||||||
|
"LatinExtended-A" -> CachedRange(0x0100, 0x017F)
|
||||||
|
"LatinExtended-B" -> CachedRange(0x0180, 0x024F)
|
||||||
|
"IPAExtensions" -> CachedRange(0x0250, 0x02AF)
|
||||||
|
"SpacingModifierLetters" -> CachedRange(0x02B0, 0x02FF)
|
||||||
|
"CombiningDiacriticalMarks" -> CachedRange(0x0300, 0x036F)
|
||||||
|
"Greek" -> CachedRange(0x0370, 0x03FF)
|
||||||
|
"Cyrillic" -> CachedRange(0x0400, 0x04FF)
|
||||||
|
"CyrillicSupplement" -> CachedRange(0x0500, 0x052F)
|
||||||
|
"Armenian" -> CachedRange(0x0530, 0x058F)
|
||||||
|
"Hebrew" -> CachedRange(0x0590, 0x05FF)
|
||||||
|
"Arabic" -> CachedRange(0x0600, 0x06FF)
|
||||||
|
"Syriac" -> CachedRange(0x0700, 0x074F)
|
||||||
|
"ArabicSupplement" -> CachedRange(0x0750, 0x077F)
|
||||||
|
"Thaana" -> CachedRange(0x0780, 0x07BF)
|
||||||
|
"Devanagari" -> CachedRange(0x0900, 0x097F)
|
||||||
|
"Bengali" -> CachedRange(0x0980, 0x09FF)
|
||||||
|
"Gurmukhi" -> CachedRange(0x0A00, 0x0A7F)
|
||||||
|
"Gujarati" -> CachedRange(0x0A80, 0x0AFF)
|
||||||
|
"Oriya" -> CachedRange(0x0B00, 0x0B7F)
|
||||||
|
"Tamil" -> CachedRange(0x0B80, 0x0BFF)
|
||||||
|
"Telugu" -> CachedRange(0x0C00, 0x0C7F)
|
||||||
|
"Kannada" -> CachedRange(0x0C80, 0x0CFF)
|
||||||
|
"Malayalam" -> CachedRange(0x0D00, 0x0D7F)
|
||||||
|
"Sinhala" -> CachedRange(0x0D80, 0x0DFF)
|
||||||
|
"Thai" -> CachedRange(0x0E00, 0x0E7F)
|
||||||
|
"Lao" -> CachedRange(0x0E80, 0x0EFF)
|
||||||
|
"Tibetan" -> CachedRange(0x0F00, 0x0FFF)
|
||||||
|
"Myanmar" -> CachedRange(0x1000, 0x109F)
|
||||||
|
"Georgian" -> CachedRange(0x10A0, 0x10FF)
|
||||||
|
"HangulJamo" -> CachedRange(0x1100, 0x11FF)
|
||||||
|
"Ethiopic" -> CachedRange(0x1200, 0x137F)
|
||||||
|
"EthiopicSupplement" -> CachedRange(0x1380, 0x139F)
|
||||||
|
"Cherokee" -> CachedRange(0x13A0, 0x13FF)
|
||||||
|
"UnifiedCanadianAboriginalSyllabics" -> CachedRange(0x1400, 0x167F)
|
||||||
|
"Ogham" -> CachedRange(0x1680, 0x169F)
|
||||||
|
"Runic" -> CachedRange(0x16A0, 0x16FF)
|
||||||
|
"Tagalog" -> CachedRange(0x1700, 0x171F)
|
||||||
|
"Hanunoo" -> CachedRange(0x1720, 0x173F)
|
||||||
|
"Buhid" -> CachedRange(0x1740, 0x175F)
|
||||||
|
"Tagbanwa" -> CachedRange(0x1760, 0x177F)
|
||||||
|
"Khmer" -> CachedRange(0x1780, 0x17FF)
|
||||||
|
"Mongolian" -> CachedRange(0x1800, 0x18AF)
|
||||||
|
"Limbu" -> CachedRange(0x1900, 0x194F)
|
||||||
|
"TaiLe" -> CachedRange(0x1950, 0x197F)
|
||||||
|
"NewTaiLue" -> CachedRange(0x1980, 0x19DF)
|
||||||
|
"KhmerSymbols" -> CachedRange(0x19E0, 0x19FF)
|
||||||
|
"Buginese" -> CachedRange(0x1A00, 0x1A1F)
|
||||||
|
"PhoneticExtensions" -> CachedRange(0x1D00, 0x1D7F)
|
||||||
|
"PhoneticExtensionsSupplement" -> CachedRange(0x1D80, 0x1DBF)
|
||||||
|
"CombiningDiacriticalMarksSupplement" -> CachedRange(0x1DC0, 0x1DFF)
|
||||||
|
"LatinExtendedAdditional" -> CachedRange(0x1E00, 0x1EFF)
|
||||||
|
"GreekExtended" -> CachedRange(0x1F00, 0x1FFF)
|
||||||
|
"GeneralPunctuation" -> CachedRange(0x2000, 0x206F)
|
||||||
|
"SuperscriptsandSubscripts" -> CachedRange(0x2070, 0x209F)
|
||||||
|
"CurrencySymbols" -> CachedRange(0x20A0, 0x20CF)
|
||||||
|
"CombiningMarksforSymbols" -> CachedRange(0x20D0, 0x20FF)
|
||||||
|
"LetterlikeSymbols" -> CachedRange(0x2100, 0x214F)
|
||||||
|
"NumberForms" -> CachedRange(0x2150, 0x218F)
|
||||||
|
"Arrows" -> CachedRange(0x2190, 0x21FF)
|
||||||
|
"MathematicalOperators" -> CachedRange(0x2200, 0x22FF)
|
||||||
|
"MiscellaneousTechnical" -> CachedRange(0x2300, 0x23FF)
|
||||||
|
"ControlPictures" -> CachedRange(0x2400, 0x243F)
|
||||||
|
"OpticalCharacterRecognition" -> CachedRange(0x2440, 0x245F)
|
||||||
|
"EnclosedAlphanumerics" -> CachedRange(0x2460, 0x24FF)
|
||||||
|
"BoxDrawing" -> CachedRange(0x2500, 0x257F)
|
||||||
|
"BlockElements" -> CachedRange(0x2580, 0x259F)
|
||||||
|
"GeometricShapes" -> CachedRange(0x25A0, 0x25FF)
|
||||||
|
"MiscellaneousSymbols" -> CachedRange(0x2600, 0x26FF)
|
||||||
|
"Dingbats" -> CachedRange(0x2700, 0x27BF)
|
||||||
|
"MiscellaneousMathematicalSymbols-A" -> CachedRange(0x27C0, 0x27EF)
|
||||||
|
"SupplementalArrows-A" -> CachedRange(0x27F0, 0x27FF)
|
||||||
|
"BraillePatterns" -> CachedRange(0x2800, 0x28FF)
|
||||||
|
"SupplementalArrows-B" -> CachedRange(0x2900, 0x297F)
|
||||||
|
"MiscellaneousMathematicalSymbols-B" -> CachedRange(0x2980, 0x29FF)
|
||||||
|
"SupplementalMathematicalOperators" -> CachedRange(0x2A00, 0x2AFF)
|
||||||
|
"MiscellaneousSymbolsandArrows" -> CachedRange(0x2B00, 0x2BFF)
|
||||||
|
"Glagolitic" -> CachedRange(0x2C00, 0x2C5F)
|
||||||
|
"Coptic" -> CachedRange(0x2C80, 0x2CFF)
|
||||||
|
"GeorgianSupplement" -> CachedRange(0x2D00, 0x2D2F)
|
||||||
|
"Tifinagh" -> CachedRange(0x2D30, 0x2D7F)
|
||||||
|
"EthiopicExtended" -> CachedRange(0x2D80, 0x2DDF)
|
||||||
|
"SupplementalPunctuation" -> CachedRange(0x2E00, 0x2E7F)
|
||||||
|
"CJKRadicalsSupplement" -> CachedRange(0x2E80, 0x2EFF)
|
||||||
|
"KangxiRadicals" -> CachedRange(0x2F00, 0x2FDF)
|
||||||
|
"IdeographicDescriptionCharacters" -> CachedRange(0x2FF0, 0x2FFF)
|
||||||
|
"CJKSymbolsandPunctuation" -> CachedRange(0x3000, 0x303F)
|
||||||
|
"Hiragana" -> CachedRange(0x3040, 0x309F)
|
||||||
|
"Katakana" -> CachedRange(0x30A0, 0x30FF)
|
||||||
|
"Bopomofo" -> CachedRange(0x3100, 0x312F)
|
||||||
|
"HangulCompatibilityJamo" -> CachedRange(0x3130, 0x318F)
|
||||||
|
"Kanbun" -> CachedRange(0x3190, 0x319F)
|
||||||
|
"BopomofoExtended" -> CachedRange(0x31A0, 0x31BF)
|
||||||
|
"CJKStrokes" -> CachedRange(0x31C0, 0x31EF)
|
||||||
|
"KatakanaPhoneticExtensions" -> CachedRange(0x31F0, 0x31FF)
|
||||||
|
"EnclosedCJKLettersandMonths" -> CachedRange(0x3200, 0x32FF)
|
||||||
|
"CJKCompatibility" -> CachedRange(0x3300, 0x33FF)
|
||||||
|
"CJKUnifiedIdeographsExtensionA" -> CachedRange(0x3400, 0x4DB5)
|
||||||
|
"YijingHexagramSymbols" -> CachedRange(0x4DC0, 0x4DFF)
|
||||||
|
"CJKUnifiedIdeographs" -> CachedRange(0x4E00, 0x9FFF)
|
||||||
|
"YiSyllables" -> CachedRange(0xA000, 0xA48F)
|
||||||
|
"YiRadicals" -> CachedRange(0xA490, 0xA4CF)
|
||||||
|
"ModifierToneLetters" -> CachedRange(0xA700, 0xA71F)
|
||||||
|
"SylotiNagri" -> CachedRange(0xA800, 0xA82F)
|
||||||
|
"HangulSyllables" -> CachedRange(0xAC00, 0xD7A3)
|
||||||
|
"HighSurrogates" -> CachedRange(0xD800, 0xDB7F)
|
||||||
|
"HighPrivateUseSurrogates" -> CachedRange(0xDB80, 0xDBFF)
|
||||||
|
"LowSurrogates" -> CachedRange(0xDC00, 0xDFFF)
|
||||||
|
"PrivateUseArea" -> CachedRange(0xE000, 0xF8FF)
|
||||||
|
"CJKCompatibilityIdeographs" -> CachedRange(0xF900, 0xFAFF)
|
||||||
|
"AlphabeticPresentationForms" -> CachedRange(0xFB00, 0xFB4F)
|
||||||
|
"ArabicPresentationForms-A" -> CachedRange(0xFB50, 0xFDFF)
|
||||||
|
"VariationSelectors" -> CachedRange(0xFE00, 0xFE0F)
|
||||||
|
"VerticalForms" -> CachedRange(0xFE10, 0xFE1F)
|
||||||
|
"CombiningHalfMarks" -> CachedRange(0xFE20, 0xFE2F)
|
||||||
|
"CJKCompatibilityForms" -> CachedRange(0xFE30, 0xFE4F)
|
||||||
|
"SmallFormVariants" -> CachedRange(0xFE50, 0xFE6F)
|
||||||
|
"ArabicPresentationForms-B" -> CachedRange(0xFE70, 0xFEFF)
|
||||||
|
"HalfwidthandFullwidthForms" -> CachedRange(0xFF00, 0xFFEF)
|
||||||
|
"all" -> CachedRange(0x00, 0x10FFFF)
|
||||||
|
"Specials" -> CachedSpecialsBlock()
|
||||||
|
"Cn" -> CachedCategory(CharCategory.UNASSIGNED.value, true)
|
||||||
|
"IsL" -> CachedCategoryScope(0x3E, true)
|
||||||
|
"Lu" -> CachedCategory(CharCategory.UPPERCASE_LETTER.value, true)
|
||||||
|
"Ll" -> CachedCategory(CharCategory.LOWERCASE_LETTER.value, true)
|
||||||
|
"Lt" -> CachedCategory(CharCategory.TITLECASE_LETTER.value, false)
|
||||||
|
"Lm" -> CachedCategory(CharCategory.MODIFIER_LETTER.value, false)
|
||||||
|
"Lo" -> CachedCategory(CharCategory.OTHER_LETTER.value, true)
|
||||||
|
"IsM" -> CachedCategoryScope(0x1C0, true)
|
||||||
|
"Mn" -> CachedCategory(CharCategory.NON_SPACING_MARK.value, true)
|
||||||
|
"Me" -> CachedCategory(CharCategory.ENCLOSING_MARK.value, false)
|
||||||
|
"Mc" -> CachedCategory(CharCategory.COMBINING_SPACING_MARK.value, true)
|
||||||
|
"N" -> CachedCategoryScope(0xE00, true)
|
||||||
|
"Nd" -> CachedCategory(CharCategory.DECIMAL_DIGIT_NUMBER.value, true)
|
||||||
|
"Nl" -> CachedCategory(CharCategory.LETTER_NUMBER.value, true)
|
||||||
|
"No" -> CachedCategory(CharCategory.OTHER_NUMBER.value, true)
|
||||||
|
"IsZ" -> CachedCategoryScope(0x7000, false)
|
||||||
|
"Zs" -> CachedCategory(CharCategory.SPACE_SEPARATOR.value, false)
|
||||||
|
"Zl" -> CachedCategory(CharCategory.LINE_SEPARATOR.value, false)
|
||||||
|
"Zp" -> CachedCategory(CharCategory.PARAGRAPH_SEPARATOR.value, false)
|
||||||
|
"IsC" -> CachedCategoryScope(0xF0000, true, true)
|
||||||
|
"Cc" -> CachedCategory(CharCategory.CONTROL.value, false)
|
||||||
|
"Cf" -> CachedCategory(CharCategory.FORMAT.value, true)
|
||||||
|
"Co" -> CachedCategory(CharCategory.PRIVATE_USE.value, true)
|
||||||
|
"Cs" -> CachedCategory(CharCategory.SURROGATE.value, false, true)
|
||||||
|
"IsP" -> CachedCategoryScope(1 shl CharCategory.DASH_PUNCTUATION.value or
|
||||||
|
(1 shl CharCategory.START_PUNCTUATION.value) or
|
||||||
|
(1 shl CharCategory.END_PUNCTUATION.value) or
|
||||||
|
(1 shl CharCategory.CONNECTOR_PUNCTUATION.value) or
|
||||||
|
(1 shl CharCategory.OTHER_PUNCTUATION.value) or
|
||||||
|
(1 shl CharCategory.INITIAL_QUOTE_PUNCTUATION.value) or
|
||||||
|
(1 shl CharCategory.FINAL_QUOTE_PUNCTUATION.value), true)
|
||||||
|
"Pd" -> CachedCategory(CharCategory.DASH_PUNCTUATION.value, false)
|
||||||
|
"Ps" -> CachedCategory(CharCategory.START_PUNCTUATION.value, false)
|
||||||
|
"Pe" -> CachedCategory(CharCategory.END_PUNCTUATION.value, false)
|
||||||
|
"Pc" -> CachedCategory(CharCategory.CONNECTOR_PUNCTUATION.value, false)
|
||||||
|
"Po" -> CachedCategory(CharCategory.OTHER_PUNCTUATION.value, true)
|
||||||
|
"IsS" -> CachedCategoryScope(0x7E000000, true)
|
||||||
|
"Sm" -> CachedCategory(CharCategory.MATH_SYMBOL.value, true)
|
||||||
|
"Sc" -> CachedCategory(CharCategory.CURRENCY_SYMBOL.value, false)
|
||||||
|
"Sk" -> CachedCategory(CharCategory.MODIFIER_SYMBOL.value, false)
|
||||||
|
"So" -> CachedCategory(CharCategory.OTHER_SYMBOL.value, true)
|
||||||
|
"Pi" -> CachedCategory(CharCategory.INITIAL_QUOTE_PUNCTUATION.value, false)
|
||||||
|
"Pf" -> CachedCategory(CharCategory.FINAL_QUOTE_PUNCTUATION.value, false)
|
||||||
|
else -> throw PatternSyntaxException("No such character class")
|
||||||
|
}
|
||||||
|
|
||||||
return when (name) {
|
fun intersects(ch1: Int, ch2: Int): Boolean = ch1 == ch2
|
||||||
|
fun intersects(cc: AbstractCharClass, ch: Int): Boolean = cc.contains(ch)
|
||||||
|
|
||||||
"Lower" -> LazyLower()
|
fun intersects(cc1: AbstractCharClass, cc2: AbstractCharClass): Boolean {
|
||||||
"Upper" -> LazyUpper()
|
if (cc1.bits == null || cc2.bits == null) {
|
||||||
"ASCII" -> LazyASCII()
|
|
||||||
"Alpha" -> LazyAlpha()
|
|
||||||
"Digit" -> digit
|
|
||||||
"Alnum" -> LazyAlnum()
|
|
||||||
"Punct" -> LazyPunct()
|
|
||||||
"Graph" -> LazyGraph()
|
|
||||||
"Print" -> LazyPrint()
|
|
||||||
"Blank" -> LazyBlank()
|
|
||||||
"Cntrl" -> LazyCntrl()
|
|
||||||
"XDigit" -> LazyXDigit()
|
|
||||||
"Space" -> space
|
|
||||||
"w" -> LazyWord()
|
|
||||||
"W" -> LazyNonWord()
|
|
||||||
"s" -> space
|
|
||||||
"S" -> LazyNonSpace()
|
|
||||||
"d" -> digit
|
|
||||||
"D" -> LazyNonDigit()
|
|
||||||
"BasicLatin" -> LazyRange(0x0000, 0x007F)
|
|
||||||
"Latin-1Supplement" -> LazyRange(0x0080, 0x00FF)
|
|
||||||
"LatinExtended-A" -> LazyRange(0x0100, 0x017F)
|
|
||||||
"LatinExtended-B" -> LazyRange(0x0180, 0x024F)
|
|
||||||
"IPAExtensions" -> LazyRange(0x0250, 0x02AF)
|
|
||||||
"SpacingModifierLetters" -> LazyRange(0x02B0, 0x02FF)
|
|
||||||
"CombiningDiacriticalMarks" -> LazyRange(0x0300, 0x036F)
|
|
||||||
"Greek" -> LazyRange(0x0370, 0x03FF)
|
|
||||||
"Cyrillic" -> LazyRange(0x0400, 0x04FF)
|
|
||||||
"CyrillicSupplement" -> LazyRange(0x0500, 0x052F)
|
|
||||||
"Armenian" -> LazyRange(0x0530, 0x058F)
|
|
||||||
"Hebrew" -> LazyRange(0x0590, 0x05FF)
|
|
||||||
"Arabic" -> LazyRange(0x0600, 0x06FF)
|
|
||||||
"Syriac" -> LazyRange(0x0700, 0x074F)
|
|
||||||
"ArabicSupplement" -> LazyRange(0x0750, 0x077F)
|
|
||||||
"Thaana" -> LazyRange(0x0780, 0x07BF)
|
|
||||||
"Devanagari" -> LazyRange(0x0900, 0x097F)
|
|
||||||
"Bengali" -> LazyRange(0x0980, 0x09FF)
|
|
||||||
"Gurmukhi" -> LazyRange(0x0A00, 0x0A7F)
|
|
||||||
"Gujarati" -> LazyRange(0x0A80, 0x0AFF)
|
|
||||||
"Oriya" -> LazyRange(0x0B00, 0x0B7F)
|
|
||||||
"Tamil" -> LazyRange(0x0B80, 0x0BFF)
|
|
||||||
"Telugu" -> LazyRange(0x0C00, 0x0C7F)
|
|
||||||
"Kannada" -> LazyRange(0x0C80, 0x0CFF)
|
|
||||||
"Malayalam" -> LazyRange(0x0D00, 0x0D7F)
|
|
||||||
"Sinhala" -> LazyRange(0x0D80, 0x0DFF)
|
|
||||||
"Thai" -> LazyRange(0x0E00, 0x0E7F)
|
|
||||||
"Lao" -> LazyRange(0x0E80, 0x0EFF)
|
|
||||||
"Tibetan" -> LazyRange(0x0F00, 0x0FFF)
|
|
||||||
"Myanmar" -> LazyRange(0x1000, 0x109F)
|
|
||||||
"Georgian" -> LazyRange(0x10A0, 0x10FF)
|
|
||||||
"HangulJamo" -> LazyRange(0x1100, 0x11FF)
|
|
||||||
"Ethiopic" -> LazyRange(0x1200, 0x137F)
|
|
||||||
"EthiopicSupplement" -> LazyRange(0x1380, 0x139F)
|
|
||||||
"Cherokee" -> LazyRange(0x13A0, 0x13FF)
|
|
||||||
"UnifiedCanadianAboriginalSyllabics" -> LazyRange(0x1400, 0x167F)
|
|
||||||
"Ogham" -> LazyRange(0x1680, 0x169F)
|
|
||||||
"Runic" -> LazyRange(0x16A0, 0x16FF)
|
|
||||||
"Tagalog" -> LazyRange(0x1700, 0x171F)
|
|
||||||
"Hanunoo" -> LazyRange(0x1720, 0x173F)
|
|
||||||
"Buhid" -> LazyRange(0x1740, 0x175F)
|
|
||||||
"Tagbanwa" -> LazyRange(0x1760, 0x177F)
|
|
||||||
"Khmer" -> LazyRange(0x1780, 0x17FF)
|
|
||||||
"Mongolian" -> LazyRange(0x1800, 0x18AF)
|
|
||||||
"Limbu" -> LazyRange(0x1900, 0x194F)
|
|
||||||
"TaiLe" -> LazyRange(0x1950, 0x197F)
|
|
||||||
"NewTaiLue" -> LazyRange(0x1980, 0x19DF)
|
|
||||||
"KhmerSymbols" -> LazyRange(0x19E0, 0x19FF)
|
|
||||||
"Buginese" -> LazyRange(0x1A00, 0x1A1F)
|
|
||||||
"PhoneticExtensions" -> LazyRange(0x1D00, 0x1D7F)
|
|
||||||
"PhoneticExtensionsSupplement" -> LazyRange(0x1D80, 0x1DBF)
|
|
||||||
"CombiningDiacriticalMarksSupplement" -> LazyRange(0x1DC0, 0x1DFF)
|
|
||||||
"LatinExtendedAdditional" -> LazyRange(0x1E00, 0x1EFF)
|
|
||||||
"GreekExtended" -> LazyRange(0x1F00, 0x1FFF)
|
|
||||||
"GeneralPunctuation" -> LazyRange(0x2000, 0x206F)
|
|
||||||
"SuperscriptsandSubscripts" -> LazyRange(0x2070, 0x209F)
|
|
||||||
"CurrencySymbols" -> LazyRange(0x20A0, 0x20CF)
|
|
||||||
"CombiningMarksforSymbols" -> LazyRange(0x20D0, 0x20FF)
|
|
||||||
"LetterlikeSymbols" -> LazyRange(0x2100, 0x214F)
|
|
||||||
"NumberForms" -> LazyRange(0x2150, 0x218F)
|
|
||||||
"Arrows" -> LazyRange(0x2190, 0x21FF)
|
|
||||||
"MathematicalOperators" -> LazyRange(0x2200, 0x22FF)
|
|
||||||
"MiscellaneousTechnical" -> LazyRange(0x2300, 0x23FF)
|
|
||||||
"ControlPictures" -> LazyRange(0x2400, 0x243F)
|
|
||||||
"OpticalCharacterRecognition" -> LazyRange(0x2440, 0x245F)
|
|
||||||
"EnclosedAlphanumerics" -> LazyRange(0x2460, 0x24FF)
|
|
||||||
"BoxDrawing" -> LazyRange(0x2500, 0x257F)
|
|
||||||
"BlockElements" -> LazyRange(0x2580, 0x259F)
|
|
||||||
"GeometricShapes" -> LazyRange(0x25A0, 0x25FF)
|
|
||||||
"MiscellaneousSymbols" -> LazyRange(0x2600, 0x26FF)
|
|
||||||
"Dingbats" -> LazyRange(0x2700, 0x27BF)
|
|
||||||
"MiscellaneousMathematicalSymbols-A" -> LazyRange(0x27C0, 0x27EF)
|
|
||||||
"SupplementalArrows-A" -> LazyRange(0x27F0, 0x27FF)
|
|
||||||
"BraillePatterns" -> LazyRange(0x2800, 0x28FF)
|
|
||||||
"SupplementalArrows-B" -> LazyRange(0x2900, 0x297F)
|
|
||||||
"MiscellaneousMathematicalSymbols-B" -> LazyRange(0x2980, 0x29FF)
|
|
||||||
"SupplementalMathematicalOperators" -> LazyRange(0x2A00, 0x2AFF)
|
|
||||||
"MiscellaneousSymbolsandArrows" -> LazyRange(0x2B00, 0x2BFF)
|
|
||||||
"Glagolitic" -> LazyRange(0x2C00, 0x2C5F)
|
|
||||||
"Coptic" -> LazyRange(0x2C80, 0x2CFF)
|
|
||||||
"GeorgianSupplement" -> LazyRange(0x2D00, 0x2D2F)
|
|
||||||
"Tifinagh" -> LazyRange(0x2D30, 0x2D7F)
|
|
||||||
"EthiopicExtended" -> LazyRange(0x2D80, 0x2DDF)
|
|
||||||
"SupplementalPunctuation" -> LazyRange(0x2E00, 0x2E7F)
|
|
||||||
"CJKRadicalsSupplement" -> LazyRange(0x2E80, 0x2EFF)
|
|
||||||
"KangxiRadicals" -> LazyRange(0x2F00, 0x2FDF)
|
|
||||||
"IdeographicDescriptionCharacters" -> LazyRange(0x2FF0, 0x2FFF)
|
|
||||||
"CJKSymbolsandPunctuation" -> LazyRange(0x3000, 0x303F)
|
|
||||||
"Hiragana" -> LazyRange(0x3040, 0x309F)
|
|
||||||
"Katakana" -> LazyRange(0x30A0, 0x30FF)
|
|
||||||
"Bopomofo" -> LazyRange(0x3100, 0x312F)
|
|
||||||
"HangulCompatibilityJamo" -> LazyRange(0x3130, 0x318F)
|
|
||||||
"Kanbun" -> LazyRange(0x3190, 0x319F)
|
|
||||||
"BopomofoExtended" -> LazyRange(0x31A0, 0x31BF)
|
|
||||||
"CJKStrokes" -> LazyRange(0x31C0, 0x31EF)
|
|
||||||
"KatakanaPhoneticExtensions" -> LazyRange(0x31F0, 0x31FF)
|
|
||||||
"EnclosedCJKLettersandMonths" -> LazyRange(0x3200, 0x32FF)
|
|
||||||
"CJKCompatibility" -> LazyRange(0x3300, 0x33FF)
|
|
||||||
"CJKUnifiedIdeographsExtensionA" -> LazyRange(0x3400, 0x4DB5)
|
|
||||||
"YijingHexagramSymbols" -> LazyRange(0x4DC0, 0x4DFF)
|
|
||||||
"CJKUnifiedIdeographs" -> LazyRange(0x4E00, 0x9FFF)
|
|
||||||
"YiSyllables" -> LazyRange(0xA000, 0xA48F)
|
|
||||||
"YiRadicals" -> LazyRange(0xA490, 0xA4CF)
|
|
||||||
"ModifierToneLetters" -> LazyRange(0xA700, 0xA71F)
|
|
||||||
"SylotiNagri" -> LazyRange(0xA800, 0xA82F)
|
|
||||||
"HangulSyllables" -> LazyRange(0xAC00, 0xD7A3)
|
|
||||||
"HighSurrogates" -> LazyRange(0xD800, 0xDB7F)
|
|
||||||
"HighPrivateUseSurrogates" -> LazyRange(0xDB80, 0xDBFF)
|
|
||||||
"LowSurrogates" -> LazyRange(0xDC00, 0xDFFF)
|
|
||||||
"PrivateUseArea" -> LazyRange(0xE000, 0xF8FF)
|
|
||||||
"CJKCompatibilityIdeographs" -> LazyRange(0xF900, 0xFAFF)
|
|
||||||
"AlphabeticPresentationForms" -> LazyRange(0xFB00, 0xFB4F)
|
|
||||||
"ArabicPresentationForms-A" -> LazyRange(0xFB50, 0xFDFF)
|
|
||||||
"VariationSelectors" -> LazyRange(0xFE00, 0xFE0F)
|
|
||||||
"VerticalForms" -> LazyRange(0xFE10, 0xFE1F)
|
|
||||||
"CombiningHalfMarks" -> LazyRange(0xFE20, 0xFE2F)
|
|
||||||
"CJKCompatibilityForms" -> LazyRange(0xFE30, 0xFE4F)
|
|
||||||
"SmallFormVariants" -> LazyRange(0xFE50, 0xFE6F)
|
|
||||||
"ArabicPresentationForms-B" -> LazyRange(0xFE70, 0xFEFF)
|
|
||||||
"HalfwidthandFullwidthForms" -> LazyRange(0xFF00, 0xFFEF)
|
|
||||||
"all" -> LazyRange(0x00, 0x10FFFF)
|
|
||||||
"Specials" -> LazySpecialsBlock()
|
|
||||||
"Cn" -> LazyCategory(CharCategory.UNASSIGNED.value, true)
|
|
||||||
"IsL" -> LazyCategoryScope(0x3E, true)
|
|
||||||
"Lu" -> LazyCategory(CharCategory.UPPERCASE_LETTER.value, true)
|
|
||||||
"Ll" -> LazyCategory(CharCategory.LOWERCASE_LETTER.value, true)
|
|
||||||
"Lt" -> LazyCategory(CharCategory.TITLECASE_LETTER.value, false)
|
|
||||||
"Lm" -> LazyCategory(CharCategory.MODIFIER_LETTER.value, false)
|
|
||||||
"Lo" -> LazyCategory(CharCategory.OTHER_LETTER.value, true)
|
|
||||||
"IsM" -> LazyCategoryScope(0x1C0, true)
|
|
||||||
"Mn" -> LazyCategory(CharCategory.NON_SPACING_MARK.value, true)
|
|
||||||
"Me" -> LazyCategory(CharCategory.ENCLOSING_MARK.value, false)
|
|
||||||
"Mc" -> LazyCategory(CharCategory.COMBINING_SPACING_MARK.value, true)
|
|
||||||
"N" -> LazyCategoryScope(0xE00, true)
|
|
||||||
"Nd" -> LazyCategory(CharCategory.DECIMAL_DIGIT_NUMBER.value, true)
|
|
||||||
"Nl" -> LazyCategory(CharCategory.LETTER_NUMBER.value, true)
|
|
||||||
"No" -> LazyCategory(CharCategory.OTHER_NUMBER.value, true)
|
|
||||||
"IsZ" -> LazyCategoryScope(0x7000, false)
|
|
||||||
"Zs" -> LazyCategory(CharCategory.SPACE_SEPARATOR.value, false)
|
|
||||||
"Zl" -> LazyCategory(CharCategory.LINE_SEPARATOR.value, false)
|
|
||||||
"Zp" -> LazyCategory(CharCategory.PARAGRAPH_SEPARATOR.value, false)
|
|
||||||
"IsC" -> LazyCategoryScope(0xF0000, true, true)
|
|
||||||
"Cc" -> LazyCategory(CharCategory.CONTROL.value, false)
|
|
||||||
"Cf" -> LazyCategory(CharCategory.FORMAT.value, true)
|
|
||||||
"Co" -> LazyCategory(CharCategory.PRIVATE_USE.value, true)
|
|
||||||
"Cs" -> LazyCategory(CharCategory.SURROGATE.value, false, true)
|
|
||||||
"IsP" -> LazyCategoryScope(1 shl CharCategory.DASH_PUNCTUATION.value or
|
|
||||||
(1 shl CharCategory.START_PUNCTUATION.value) or
|
|
||||||
(1 shl CharCategory.END_PUNCTUATION.value) or
|
|
||||||
(1 shl CharCategory.CONNECTOR_PUNCTUATION.value) or
|
|
||||||
(1 shl CharCategory.OTHER_PUNCTUATION.value) or
|
|
||||||
(1 shl CharCategory.INITIAL_QUOTE_PUNCTUATION.value) or
|
|
||||||
(1 shl CharCategory.FINAL_QUOTE_PUNCTUATION.value), true)
|
|
||||||
"Pd" -> LazyCategory(CharCategory.DASH_PUNCTUATION.value, false)
|
|
||||||
"Ps" -> LazyCategory(CharCategory.START_PUNCTUATION.value, false)
|
|
||||||
"Pe" -> LazyCategory(CharCategory.END_PUNCTUATION.value, false)
|
|
||||||
"Pc" -> LazyCategory(CharCategory.CONNECTOR_PUNCTUATION.value, false)
|
|
||||||
"Po" -> LazyCategory(CharCategory.OTHER_PUNCTUATION.value, true)
|
|
||||||
"IsS" -> LazyCategoryScope(0x7E000000, true)
|
|
||||||
"Sm" -> LazyCategory(CharCategory.MATH_SYMBOL.value, true)
|
|
||||||
"Sc" -> LazyCategory(CharCategory.CURRENCY_SYMBOL.value, false)
|
|
||||||
"Sk" -> LazyCategory(CharCategory.MODIFIER_SYMBOL.value, false)
|
|
||||||
"So" -> LazyCategory(CharCategory.OTHER_SYMBOL.value, true)
|
|
||||||
"Pi" -> LazyCategory(CharCategory.INITIAL_QUOTE_PUNCTUATION.value, false)
|
|
||||||
"Pf" -> LazyCategory(CharCategory.FINAL_QUOTE_PUNCTUATION.value, false)
|
|
||||||
else -> throw PatternSyntaxException("No such character class")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun intersects(ch1: Int, ch2: Int): Boolean {
|
|
||||||
return ch1 == ch2
|
|
||||||
}
|
|
||||||
|
|
||||||
fun intersects(cc: AbstractCharClass, ch: Int): Boolean {
|
|
||||||
return cc.contains(ch)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun intersects(cc1: AbstractCharClass,
|
|
||||||
cc2: AbstractCharClass): Boolean {
|
|
||||||
if (cc1.bits == null || cc2.bits == null)
|
|
||||||
return true
|
return true
|
||||||
|
}
|
||||||
return cc1.bits!!.intersects(cc2.bits!!)
|
return cc1.bits!!.intersects(cc2.bits!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getPredefinedClass(name: String, negative: Boolean): AbstractCharClass {
|
fun getPredefinedClass(name: String, negative: Boolean): AbstractCharClass {
|
||||||
return (getClass(name)).getValue(negative)
|
var cache = classCache
|
||||||
|
if (cache == null) {
|
||||||
|
cache = mutableMapOf()
|
||||||
|
classCache = cache
|
||||||
|
}
|
||||||
|
var cachedClass = cache[name]
|
||||||
|
if (cachedClass == null) {
|
||||||
|
cachedClass = createClass(name)
|
||||||
|
cache[name] = cachedClass
|
||||||
|
}
|
||||||
|
return cachedClass.getValue(negative)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ package kotlin.text.regex
|
|||||||
*
|
*
|
||||||
* @author Nikolay A. Kuznetsov
|
* @author Nikolay A. Kuznetsov
|
||||||
*/
|
*/
|
||||||
/*
|
// TODO: replace the implementation with one using BitSet for first 256 symbols and a hash table / tree for the rest of UTF.
|
||||||
* TODO: replace the implementation with one using BitSet for first 256 symbols and a hash table / tree for the rest of UTF.
|
|
||||||
*/
|
|
||||||
internal class CharClass(val ignoreCase: Boolean = false, negative: Boolean = false) : AbstractCharClass() {
|
internal class CharClass(val ignoreCase: Boolean = false, negative: Boolean = false) : AbstractCharClass() {
|
||||||
|
|
||||||
var invertedSurrogates = false
|
var invertedSurrogates = false
|
||||||
@@ -38,7 +36,6 @@ internal class CharClass(val ignoreCase: Boolean = false, negative: Boolean = fa
|
|||||||
*/
|
*/
|
||||||
var inverted = false
|
var inverted = false
|
||||||
|
|
||||||
// TODO: May be we can get rid of it?
|
|
||||||
var hideBits = false
|
var hideBits = false
|
||||||
|
|
||||||
internal var bits_ = BitSet()
|
internal var bits_ = BitSet()
|
||||||
@@ -155,9 +152,6 @@ internal class CharClass(val ignoreCase: Boolean = false, negative: Boolean = fa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Some of charclasses hides its bits
|
// Some of charclasses hides its bits
|
||||||
// Looks like hideBits and nonBitSet are used when we add another class which have no bitmask.
|
|
||||||
// TODO: We can potentially remove nonBitSet and hideBits. What is alt?
|
|
||||||
// TODO: The same for or operation.
|
|
||||||
} else {
|
} else {
|
||||||
val curAlt = alt
|
val curAlt = alt
|
||||||
|
|
||||||
@@ -222,17 +216,28 @@ internal class CharClass(val ignoreCase: Boolean = false, negative: Boolean = fa
|
|||||||
fun add(start: Int, end: Int): CharClass {
|
fun add(start: Int, end: Int): CharClass {
|
||||||
if (start > end)
|
if (start > end)
|
||||||
throw IllegalArgumentException()
|
throw IllegalArgumentException()
|
||||||
//no intersection with surrogate characters
|
val minSurrogate = Char.MIN_SURROGATE.toInt()
|
||||||
if (!ignoreCase && (end < Char.MIN_SURROGATE.toInt() || start > Char.MAX_SURROGATE.toInt())) {
|
val maxSurrogate = Char.MAX_SURROGATE.toInt()
|
||||||
if (!inverted) {
|
if (ignoreCase) {
|
||||||
bits_.set(start, end + 1)
|
// TODO: Make a faster implementation.
|
||||||
} else {
|
|
||||||
bits_.clear(start, end + 1)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (i in start..end) {
|
for (i in start..end) {
|
||||||
add(i)
|
add(i)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// No intersection with surrogate characters.
|
||||||
|
if (end < minSurrogate || start > maxSurrogate) {
|
||||||
|
bits_.set(start, end + 1, !inverted)
|
||||||
|
} else {
|
||||||
|
val surrogatesStart = maxOf(start, minSurrogate)
|
||||||
|
val surrogatesEnd = minOf(end, maxSurrogate)
|
||||||
|
bits_.set(start, end + 1, !inverted)
|
||||||
|
lowHighSurrogates.set(surrogatesStart - minSurrogate,
|
||||||
|
surrogatesEnd - minSurrogate + 1,
|
||||||
|
!invertedSurrogates)
|
||||||
|
if (!mayContainSupplCodepoints && end >= Char.MIN_SUPPLEMENTARY_CODE_POINT) {
|
||||||
|
mayContainSupplCodepoints = true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
@@ -489,7 +494,7 @@ internal class CharClass(val ignoreCase: Boolean = false, negative: Boolean = fa
|
|||||||
*/
|
*/
|
||||||
override operator fun contains(ch: Int): Boolean {
|
override operator fun contains(ch: Int): Boolean {
|
||||||
if (nonBitSet == null) {
|
if (nonBitSet == null) {
|
||||||
return this.alt xor bits_.get(ch) // TODO alt xor bits. It must make sense.
|
return alt xor bits_.get(ch)
|
||||||
} else {
|
} else {
|
||||||
return alt xor nonBitSet!!.contains(ch)
|
return alt xor nonBitSet!!.contains(ch)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user