@@ -3,6 +3,7 @@ package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.gra
33import com.intellij.openapi.project.Project
44import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.Validator
55import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.OptionValueInformation
6+ import org.apache.ivy.plugins.version.Match
67
78interface Combinator {
89
@@ -29,7 +30,7 @@ interface Combinator {
2930 *
3031 * The return value is -1 for no match, or a new offset if this token matched something.
3132 */
32- fun SyntacticMatch (value : String , offset : Int ): Int
33+ fun SyntacticMatch (value : String , offset : Int ): MatchResult
3334
3435 /* *
3536 * This checks the value string, starting at offset for a semantic match.
@@ -38,29 +39,31 @@ interface Combinator {
3839 *
3940 * The return value is -1 for no match, or a new offset if this token matched something.
4041 */
41- fun SemanticMatch (value : String , offset : Int ): Int
42+ fun SemanticMatch (value : String , offset : Int ): MatchResult
4243
4344
4445}
4546
47+ data class MatchResult (val tokens : List <String >, val matchResult : Int )
4648
49+ val NoMatch = MatchResult (emptyList(), - 1 )
4750
4851class RegexTerminal (val syntaticMatchStr : String , val semanticMatchStr : String ) : Combinator {
4952
5053 val syntaticMatch = syntaticMatchStr.toRegex()
5154 val semanticMatch = semanticMatchStr.toRegex()
5255
53- override fun SyntacticMatch (value : String , offset : Int ): Int {
54- val matchResult = syntaticMatch.matchAt(value, offset) ? : return - 1
56+ override fun SyntacticMatch (value : String , offset : Int ): MatchResult {
57+ val matchResult = syntaticMatch.matchAt(value, offset) ? : return NoMatch
5558
56- return offset + matchResult.value.length
59+ return MatchResult ( listOf (matchResult.value), offset + matchResult.value.length)
5760
5861 }
5962
60- override fun SemanticMatch (value : String , offset : Int ): Int {
61- val matchResult = semanticMatch.matchAt(value, offset) ? : return - 1
63+ override fun SemanticMatch (value : String , offset : Int ): MatchResult {
64+ val matchResult = semanticMatch.matchAt(value, offset) ? : return NoMatch
6265
63- return offset + matchResult.value.length
66+ return MatchResult ( listOf (matchResult.value), offset + matchResult.value.length)
6467 }
6568}
6669
@@ -69,22 +72,22 @@ val DEVICE = RegexTerminal("\\S+\\s*", "/[^\\u0000.]+\\s*")
6972val IOPS = RegexTerminal (" [0-9]+[a-zA-Z]*\\ s*" , " [0-9]+[KMGT]?\\ s*" )
7073
7174class LiteralChoiceTerminal (vararg val choices : String ) : Combinator {
72- override fun SyntacticMatch (value : String , offset : Int ): Int {
75+ override fun SyntacticMatch (value : String , offset : Int ): MatchResult {
7376 for (choice in choices) {
7477 if (value.substring(offset).startsWith(choice)) {
75- return offset + choice.length
78+ return MatchResult ( listOf (choice), offset + choice.length)
7679 }
7780 }
78- return - 1
81+ return NoMatch
7982 }
8083
81- override fun SemanticMatch (value : String , offset : Int ): Int {
84+ override fun SemanticMatch (value : String , offset : Int ): MatchResult {
8285 for (choice in choices) {
8386 if (value.substring(offset).startsWith(choice)) {
84- return offset + choice.length
87+ return MatchResult ( listOf (choice), offset + choice.length)
8588 }
8689 }
87- return - 1
90+ return NoMatch
8891 }
8992}
9093
@@ -108,30 +111,39 @@ val IMAGE_POLICY_COMBINATOR = SequenceCombinator(IMAGE_POLICY, ZeroOrMore(Sequen
108111 * This is a sequence of tokens that must match all of them.
109112 */
110113class SequenceCombinator (vararg val tokens : Combinator ) : Combinator{
111- override fun SyntacticMatch (value : String , offset : Int ): Int {
114+ override fun SyntacticMatch (value : String , offset : Int ): MatchResult {
112115 var index = offset
116+ val resultTokens = mutableListOf<String >()
117+
113118 for (token in tokens) {
114119 val match = token.SyntacticMatch (value, index)
115- if (match == - 1 ) {
120+
121+ if (match.matchResult == - 1 ) {
116122 // No forward progress
117- return - 1
123+ return NoMatch
118124 }
119- index = match
125+ index = match.matchResult
126+ resultTokens.addAll(match.tokens)
120127 }
121- return index
128+ return MatchResult (resultTokens, index)
122129 }
123130
124- override fun SemanticMatch (value : String , offset : Int ): Int {
131+ override fun SemanticMatch (value : String , offset : Int ): MatchResult {
125132 var index = offset
133+
134+ val resultTokens = mutableListOf<String >()
135+
126136 for (token in tokens) {
127137 val match = token.SemanticMatch (value, index)
128- if (match == - 1 ) {
138+ if (match.matchResult == - 1 ) {
129139 // No forward progress
130- return - 1
140+ return NoMatch
131141 }
132- index = match
142+ index = match.matchResult
143+ resultTokens.addAll(match.tokens)
144+
133145 }
134- return index
146+ return MatchResult (resultTokens, index)
135147 }
136148}
137149
@@ -140,24 +152,24 @@ class SequenceCombinator(vararg val tokens: Combinator) : Combinator{
140152 * This is a sequence of tokens that must match any of them.
141153 */
142154class AlternativeCombinator (vararg val tokens : Combinator ) : Combinator {
143- override fun SyntacticMatch (value : String , offset : Int ): Int {
155+ override fun SyntacticMatch (value : String , offset : Int ): MatchResult {
144156 for (token in tokens) {
145157 val match = token.SyntacticMatch (value, offset)
146- if (match != - 1 ) {
158+ if (match.matchResult != - 1 ) {
147159 return match
148160 }
149161 }
150- return - 1
162+ return NoMatch
151163 }
152164
153- override fun SemanticMatch (value : String , offset : Int ): Int {
165+ override fun SemanticMatch (value : String , offset : Int ): MatchResult {
154166 for (token in tokens) {
155167 val match = token.SemanticMatch (value, offset)
156- if (match != - 1 ) {
168+ if (match.matchResult != - 1 ) {
157169 return match
158170 }
159171 }
160- return - 1
172+ return NoMatch
161173 }
162174}
163175
@@ -166,34 +178,32 @@ class AlternativeCombinator(vararg val tokens: Combinator) : Combinator {
166178 */
167179
168180class OneOrMore (val combinator : Combinator ) : Combinator {
169- override fun SyntacticMatch (value : String , offset : Int ): Int {
181+
182+ private fun match (value : String , offset : Int , f : (String , Int ) -> MatchResult ): MatchResult {
170183 var index = offset
171- var match = combinator. SyntacticMatch (value, index)
184+ var match = f (value, index)
172185
173- if (match == - 1 ) {
174- return - 1
186+ val tokens = mutableListOf<String >()
187+ if (match.matchResult == - 1 ) {
188+ return NoMatch
175189 }
176190
177- while (match != - 1 ) {
178- index = match
179- match = combinator.SyntacticMatch (value, index)
191+ while (match.matchResult != - 1 ) {
192+ index = match.matchResult
193+ tokens.addAll(match.tokens)
194+
195+ match = f(value, index)
180196 }
181- return index
182- }
183197
184- override fun SemanticMatch (value : String , offset : Int ): Int {
185- var index = offset
186- var match = combinator.SemanticMatch (value, index)
198+ return MatchResult (tokens, index)
199+ }
187200
188- if (match == - 1 ) {
189- return - 1
190- }
201+ override fun SyntacticMatch ( value : String , offset : Int ): MatchResult {
202+ return match(value, offset, combinator:: SyntacticMatch )
203+ }
191204
192- while (match != - 1 ) {
193- index = match
194- match = combinator.SemanticMatch (value, index)
195- }
196- return index
205+ override fun SemanticMatch (value : String , offset : Int ): MatchResult {
206+ return match(value, offset, combinator::SemanticMatch )
197207 }
198208}
199209
@@ -202,52 +212,50 @@ class OneOrMore(val combinator : Combinator) : Combinator {
202212 */
203213
204214class ZeroOrMore (val combinator : Combinator ) : Combinator {
205- override fun SyntacticMatch (value : String , offset : Int ): Int {
215+
216+ private fun match (value : String , offset : Int , f : (String , Int ) -> MatchResult ): MatchResult {
206217 var index = offset
207- var match = combinator. SyntacticMatch (value, index)
218+ var match = f (value, index)
208219
209- if (match == - 1 ) {
210- return offset
220+ val tokens = mutableListOf<String >()
221+ if (match.matchResult == - 1 ) {
222+ return MatchResult (tokens, offset)
211223 }
212224
213- while (match != - 1 ) {
214- index = match
215- match = combinator.SyntacticMatch (value, index)
225+ while (match.matchResult != - 1 ) {
226+ index = match.matchResult
227+ tokens.addAll(match.tokens)
228+
229+ match = f(value, index)
216230 }
217- return index
218- }
219231
220- override fun SemanticMatch (value : String , offset : Int ): Int {
221- var index = offset
222- var match = combinator.SemanticMatch (value, index)
232+ return MatchResult (tokens, index)
233+ }
223234
224- if (match == - 1 ) {
225- return offset
226- }
235+ override fun SyntacticMatch ( value : String , offset : Int ): MatchResult {
236+ return match(value, offset, combinator:: SyntacticMatch )
237+ }
227238
228- while (match != - 1 ) {
229- index = match
230- match = combinator.SemanticMatch (value, index)
231- }
232- return index
239+ override fun SemanticMatch (value : String , offset : Int ): MatchResult {
240+ return match(value, offset, combinator::SemanticMatch )
233241 }
234242}
235243
236244
237245class EOF : Combinator {
238- override fun SyntacticMatch (value : String , offset : Int ): Int {
246+ override fun SyntacticMatch (value : String , offset : Int ): MatchResult {
239247 return if (offset == value.length) {
240- offset
248+ MatchResult (emptyList(), offset)
241249 } else {
242- - 1
250+ NoMatch
243251 }
244252 }
245253
246- override fun SemanticMatch (value : String , offset : Int ): Int {
254+ override fun SemanticMatch (value : String , offset : Int ): MatchResult {
247255 return if (offset == value.length) {
248- offset
256+ MatchResult (emptyList(), offset)
249257 } else {
250- - 1
258+ NoMatch
251259 }
252260 }
253261}
@@ -265,13 +273,13 @@ open class GrammarOptionValue(
265273 override fun getErrorMessage (value : String ): String? {
266274 val syntaticMatch = combinator.SyntacticMatch (value, 0 )
267275
268- if (syntaticMatch == - 1 ) {
276+ if (syntaticMatch.matchResult == - 1 ) {
269277 return " Could not parse value"
270278 }
271279
272280 val semanticMatch = combinator.SemanticMatch (value, 0 )
273281
274- if (semanticMatch == - 1 ) {
282+ if (semanticMatch.matchResult == - 1 ) {
275283 return " Value did not semantically match"
276284 }
277285
0 commit comments