@@ -3,38 +3,54 @@ package com.github.h0tk3y.betterParse.lexer
3
3
import java.util.*
4
4
import java.util.regex.Matcher
5
5
6
- public actual class RegexToken : Token {
7
- private val pattern: String
6
+ public actual class RegexToken private constructor(
7
+ name : String? ,
8
+ ignored : Boolean ,
9
+ private val pattern : String ,
8
10
private val regex : Regex
9
- private val matcher : Matcher
11
+ ) : Token(name, ignored) {
10
12
11
- private companion object {
12
- const val inputStartPrefix = " \\ A "
13
+ private val threadLocalMatcher = object : ThreadLocal < Matcher >() {
14
+ override fun initialValue () = regex.toPattern().matcher( " " )
13
15
}
14
16
15
- private fun prependPatternWithInputStart (patternString : String , options : Set <RegexOption >) =
16
- if (patternString.startsWith(inputStartPrefix))
17
- patternString.toRegex(options)
18
- else {
19
- val newlineAfterComments = if (RegexOption .COMMENTS in options) " \n " else " "
20
- val patternToEmbed = if (RegexOption .LITERAL in options) Regex .escape(patternString) else patternString
21
- (" $inputStartPrefix (?:$patternToEmbed$newlineAfterComments )" ).toRegex(options - RegexOption .LITERAL )
22
- }
17
+ private val matcher: Matcher get() = threadLocalMatcher.get()
18
+
19
+ private companion object {
20
+ private const val inputStartPrefix = " \\ A"
23
21
24
- public actual constructor (name: String? , @Language(" RegExp" , " " , " " ) patternString: String , ignored: Boolean )
25
- : super (name, ignored) {
26
- pattern = patternString
27
- regex = prependPatternWithInputStart(patternString, emptySet())
22
+ private fun prependPatternWithInputStart (patternString : String , options : Set <RegexOption >) =
23
+ if (patternString.startsWith(Companion .inputStartPrefix))
24
+ patternString.toRegex(options)
25
+ else {
26
+ val newlineAfterComments = if (RegexOption .COMMENTS in options) " \n " else " "
27
+ val patternToEmbed = if (RegexOption .LITERAL in options) Regex .escape(patternString) else patternString
28
+ (" ${inputStartPrefix} (?:$patternToEmbed$newlineAfterComments )" ).toRegex(options - RegexOption .LITERAL )
29
+ }
28
30
29
- matcher = regex.toPattern().matcher(" " )
30
31
}
31
32
32
- public actual constructor (name: String? , regex: Regex , ignored: Boolean )
33
- : super (name, ignored) {
34
- pattern = regex.pattern
35
- this .regex = prependPatternWithInputStart(pattern, regex.options)
36
- matcher = this .regex.toPattern().matcher(" " )
37
- }
33
+ public actual constructor (
34
+ name: String? ,
35
+ @Language(" RegExp" , " " , " " ) patternString: String ,
36
+ ignored: Boolean
37
+ ) : this (
38
+ name,
39
+ ignored,
40
+ patternString,
41
+ prependPatternWithInputStart(patternString, emptySet())
42
+ )
43
+
44
+ public actual constructor (
45
+ name: String? ,
46
+ regex: Regex ,
47
+ ignored: Boolean
48
+ ) : this (
49
+ name,
50
+ ignored,
51
+ regex.pattern,
52
+ prependPatternWithInputStart(regex.pattern, regex.options)
53
+ )
38
54
39
55
override fun match (input : CharSequence , fromIndex : Int ): Int {
40
56
matcher.reset(input).region(fromIndex, input.length)
0 commit comments