@@ -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