Skip to content

Commit 27bd65c

Browse files
Refactor ParserStructure logic to extract mergeOperations for cleaner handling of operation merging and reduce duplication.
Benchmark Mode Cnt Score Error Units PythonDateTimeFormatBenchmark.buildPythonDateTimeFormat avgt 5 3708.643 ± 29.908 ns/op
1 parent c35a73d commit 27bd65c

File tree

1 file changed

+44
-56
lines changed
  • core/common/src/internal/format/parser

1 file changed

+44
-56
lines changed

core/common/src/internal/format/parser/Parser.kt

Lines changed: 44 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,43 @@ internal fun <T> List<ParserStructure<T>>.concat(): ParserStructure<T> {
4949
ParserStructure(operations, followedBy.map { it.append(other) })
5050
}
5151

52+
fun mergeOperations(
53+
baseOperations: List<ParserOperation<T>>,
54+
numberSpan: List<NumberConsumer<T>>?,
55+
unconditionalModifications: List<UnconditionalModification<T>>,
56+
operationsToMerge: List<ParserOperation<T>>,
57+
followedBy: List<ParserStructure<T>>
58+
): ParserStructure<T> {
59+
val operations = buildList {
60+
addAll(baseOperations)
61+
when (val firstOperation = operationsToMerge.firstOrNull()) {
62+
is NumberSpanParserOperation -> {
63+
if (numberSpan != null) {
64+
add(NumberSpanParserOperation(numberSpan + firstOperation.consumers))
65+
} else {
66+
add(firstOperation)
67+
}
68+
addAll(unconditionalModifications)
69+
addAll(operationsToMerge.drop(1))
70+
}
71+
null -> {
72+
if (numberSpan != null) {
73+
add(NumberSpanParserOperation(numberSpan))
74+
}
75+
addAll(unconditionalModifications)
76+
}
77+
else -> {
78+
if (numberSpan != null) {
79+
add(NumberSpanParserOperation(numberSpan))
80+
}
81+
addAll(unconditionalModifications)
82+
addAll(operationsToMerge)
83+
}
84+
}
85+
}
86+
return ParserStructure(operations, followedBy)
87+
}
88+
5289
fun ParserStructure<T>.simplifyAndAppend(other: ParserStructure<T>): ParserStructure<T> {
5390
val newOperations = mutableListOf<ParserOperation<T>>()
5491
var currentNumberSpan: MutableList<NumberConsumer<T>>? = null
@@ -73,34 +110,6 @@ internal fun <T> List<ParserStructure<T>>.concat(): ParserStructure<T> {
73110
}
74111
}
75112

76-
if (followedBy.isEmpty()) {
77-
if (other.operations.isNotEmpty()) {
78-
if (currentNumberSpan == null) {
79-
val firstOperation = other.operations.first()
80-
if (firstOperation is NumberSpanParserOperation) {
81-
newOperations.add(other.operations.first())
82-
newOperations.addAll(unconditionalModifications)
83-
newOperations.addAll(other.operations.drop(1))
84-
} else {
85-
newOperations.addAll(unconditionalModifications)
86-
newOperations.addAll(other.operations)
87-
}
88-
} else {
89-
val firstOperation = other.operations.first()
90-
if (firstOperation is NumberSpanParserOperation) {
91-
newOperations.add(NumberSpanParserOperation(currentNumberSpan + firstOperation.consumers))
92-
newOperations.addAll(unconditionalModifications)
93-
newOperations.addAll(other.operations.drop(1))
94-
} else {
95-
newOperations.add(NumberSpanParserOperation(currentNumberSpan))
96-
newOperations.addAll(unconditionalModifications)
97-
newOperations.addAll(other.operations)
98-
}
99-
}
100-
return ParserStructure(newOperations, other.followedBy)
101-
}
102-
}
103-
104113
val mergedTails = followedBy.flatMap {
105114
val simplified = it.simplifyAndAppend(other)
106115
// parser `ParserStructure(emptyList(), p)` is equivalent to `p`,
@@ -111,7 +120,12 @@ internal fun <T> List<ParserStructure<T>>.concat(): ParserStructure<T> {
111120
simplified.followedBy.ifEmpty { listOf(simplified) }
112121
else
113122
listOf(simplified)
114-
}.ifEmpty { other.followedBy }
123+
}.ifEmpty {
124+
if (other.operations.isNotEmpty()) {
125+
return mergeOperations(newOperations, currentNumberSpan, unconditionalModifications, other.operations, other.followedBy)
126+
}
127+
other.followedBy
128+
}
115129
return if (currentNumberSpan == null) {
116130
// the last operation was not a number span, or it was a number span that we are allowed to interrupt
117131
newOperations.addAll(unconditionalModifications)
@@ -125,33 +139,7 @@ internal fun <T> List<ParserStructure<T>>.concat(): ParserStructure<T> {
125139
ParserStructure(newOperations, mergedTails)
126140
} else {
127141
val newTails = mergedTails.map {
128-
when (val firstOperation = it.operations.firstOrNull()) {
129-
is NumberSpanParserOperation -> ParserStructure(
130-
buildList(unconditionalModifications.size + it.operations.size) {
131-
add(NumberSpanParserOperation(currentNumberSpan + firstOperation.consumers))
132-
addAll(unconditionalModifications)
133-
addAll(it.operations.drop(1))
134-
},
135-
it.followedBy
136-
)
137-
138-
null -> ParserStructure(
139-
buildList(unconditionalModifications.size + 1) {
140-
add(NumberSpanParserOperation(currentNumberSpan))
141-
addAll(unconditionalModifications)
142-
},
143-
it.followedBy
144-
)
145-
146-
else -> ParserStructure(
147-
buildList(unconditionalModifications.size + 1 + it.operations.size) {
148-
add(NumberSpanParserOperation(currentNumberSpan))
149-
addAll(unconditionalModifications)
150-
addAll(it.operations)
151-
},
152-
it.followedBy
153-
)
154-
}
142+
mergeOperations(emptyList(), currentNumberSpan, unconditionalModifications, it.operations, it.followedBy)
155143
}
156144
ParserStructure(newOperations, newTails)
157145
}

0 commit comments

Comments
 (0)