@@ -368,7 +368,7 @@ private function doParse(string $value, int $flags)
368
368
}
369
369
370
370
try {
371
- $ parsedMapping = Inline::parse ($ this ->lexInlineMapping ($ this -> currentLine ), $ flags , $ this ->refs );
371
+ $ parsedMapping = Inline::parse ($ this ->lexInlineMapping (), $ flags , $ this ->refs );
372
372
373
373
while ($ this ->moveToNextLine ()) {
374
374
if (!$ this ->isCurrentLineEmpty ()) {
@@ -389,7 +389,7 @@ private function doParse(string $value, int $flags)
389
389
}
390
390
391
391
try {
392
- $ parsedSequence = Inline::parse ($ this ->lexInlineSequence ($ this -> currentLine ), $ flags , $ this ->refs );
392
+ $ parsedSequence = Inline::parse ($ this ->lexInlineSequence (), $ flags , $ this ->refs );
393
393
394
394
while ($ this ->moveToNextLine ()) {
395
395
if (!$ this ->isCurrentLineEmpty ()) {
@@ -736,9 +736,13 @@ private function parseValue(string $value, int $flags, string $context)
736
736
737
737
try {
738
738
if ('' !== $ value && '{ ' === $ value [0 ]) {
739
- return Inline::parse ($ this ->lexInlineMapping ($ value ), $ flags , $ this ->refs );
739
+ $ cursor = \strlen ($ this ->currentLine ) - \strlen ($ value );
740
+
741
+ return Inline::parse ($ this ->lexInlineMapping ($ cursor ), $ flags , $ this ->refs );
740
742
} elseif ('' !== $ value && '[ ' === $ value [0 ]) {
741
- return Inline::parse ($ this ->lexInlineSequence ($ value ), $ flags , $ this ->refs );
743
+ $ cursor = \strlen ($ this ->currentLine ) - \strlen ($ value );
744
+
745
+ return Inline::parse ($ this ->lexInlineSequence ($ cursor ), $ flags , $ this ->refs );
742
746
}
743
747
744
748
$ quotation = '' !== $ value && ('" ' === $ value [0 ] || "' " === $ value [0 ]) ? $ value [0 ] : null ;
@@ -1204,60 +1208,138 @@ private function parseQuotedString(string $yaml): ?string
1204
1208
}
1205
1209
}
1206
1210
1207
- private function lexInlineMapping ( string $ yaml ): string
1211
+ private function lexInlineQuotedString ( int & $ cursor ): string
1208
1212
{
1209
- if ('' === $ yaml || '{ ' !== $ yaml [0 ]) {
1210
- throw new \InvalidArgumentException (sprintf ('"%s" is not a sequence. ' , $ yaml ));
1211
- }
1212
-
1213
- for ($ i = 1 ; isset ($ yaml [$ i ]) && '} ' !== $ yaml [$ i ]; ++$ i ) {
1214
- }
1215
-
1216
- if (isset ($ yaml [$ i ]) && '} ' === $ yaml [$ i ]) {
1217
- return $ yaml ;
1218
- }
1213
+ $ quotedStringOffset = $ cursor ;
1214
+ $ cursor += strcspn ($ this ->currentLine , $ this ->currentLine [$ cursor ], $ cursor + 1 ) + 2 ;
1219
1215
1220
- $ lines = [$ yaml ];
1216
+ return substr ($ this ->currentLine , $ quotedStringOffset , $ cursor - $ quotedStringOffset );
1217
+ }
1221
1218
1222
- while ($ this ->moveToNextLine ()) {
1223
- $ lines [] = $ this ->currentLine ;
1224
- }
1219
+ private function lexUnquotedString (int &$ cursor ): string
1220
+ {
1221
+ $ offset = $ cursor ;
1222
+ $ cursor += strcspn ($ this ->currentLine , '[]{},: ' , $ cursor );
1225
1223
1226
- return implode ( "\n" , $ lines );
1224
+ return substr ( $ this -> currentLine , $ offset , $ cursor - $ offset );
1227
1225
}
1228
1226
1229
- private function lexInlineSequence ( string $ yaml ): string
1227
+ private function lexInlineMapping ( int & $ cursor = 0 ): string
1230
1228
{
1231
- if ('' === $ yaml || '[ ' !== $ yaml [0 ]) {
1232
- throw new \InvalidArgumentException (sprintf ('"%s" is not a sequence. ' , $ yaml ));
1233
- }
1229
+ $ value = $ this ->currentLine [$ cursor ];
1230
+ ++$ cursor ;
1234
1231
1235
- for ($ i = 1 ; isset ($ yaml [$ i ]) && '] ' !== $ yaml [$ i ]; ++$ i ) {
1236
- }
1232
+ do {
1233
+ $ this ->consumeWhitespaces ($ cursor );
1234
+
1235
+ while (isset ($ this ->currentLine [$ cursor ])) {
1236
+ switch ($ this ->currentLine [$ cursor ]) {
1237
+ case '" ' :
1238
+ case "' " :
1239
+ $ value .= $ this ->lexInlineQuotedString ($ cursor );
1240
+
1241
+ break ;
1242
+ case ': ' :
1243
+ case ', ' :
1244
+ $ value .= $ this ->currentLine [$ cursor ];
1245
+ ++$ cursor ;
1246
+
1247
+ break ;
1248
+ case '{ ' :
1249
+ $ value .= $ this ->lexInlineMapping ($ cursor );
1250
+
1251
+ break ;
1252
+ case '} ' :
1253
+ $ value .= '} ' ;
1254
+ ++$ cursor ;
1255
+
1256
+ return $ value ;
1257
+ case '[ ' :
1258
+ $ value .= $ this ->lexInlineSequence ($ cursor );
1259
+
1260
+ break ;
1261
+ default :
1262
+ $ value .= $ this ->lexUnquotedString ($ cursor );
1263
+ }
1237
1264
1238
- if (isset ($ yaml [$ i ]) && '] ' === $ yaml [$ i ]) {
1239
- return $ yaml ;
1240
- }
1265
+ if ($ this ->consumeWhitespaces ($ cursor )) {
1266
+ $ value .= ' ' ;
1267
+ }
1268
+ }
1269
+
1270
+ $ cursor = 0 ;
1271
+ } while ($ this ->moveToNextLine ());
1241
1272
1242
- $ value = $ yaml ;
1273
+ return $ value ;
1274
+ }
1243
1275
1244
- while ($ this ->moveToNextLine ()) {
1245
- for ($ i = 1 ; isset ($ this ->currentLine [$ i ]) && '] ' !== $ this ->currentLine [$ i ]; ++$ i ) {
1246
- }
1276
+ private function lexInlineSequence (int &$ cursor = 0 ): string
1277
+ {
1278
+ $ value = $ this ->currentLine [$ cursor ];
1279
+ ++$ cursor ;
1247
1280
1248
- $ trimmedValue = trim ($ this ->currentLine );
1281
+ do {
1282
+ $ this ->consumeWhitespaces ($ cursor );
1283
+
1284
+ while (isset ($ this ->currentLine [$ cursor ])) {
1285
+ switch ($ this ->currentLine [$ cursor ]) {
1286
+ case '" ' :
1287
+ case "' " :
1288
+ $ value .= $ this ->lexInlineQuotedString ($ cursor );
1289
+
1290
+ break ;
1291
+ case ': ' :
1292
+ case ', ' :
1293
+ $ value .= $ this ->currentLine [$ cursor ];
1294
+ ++$ cursor ;
1295
+
1296
+ break ;
1297
+ case '[ ' :
1298
+ $ value .= $ this ->lexInlineSequence ($ cursor );
1299
+
1300
+ break ;
1301
+ case '] ' :
1302
+ $ value .= '] ' ;
1303
+ ++$ cursor ;
1304
+
1305
+ return $ value ;
1306
+ case '{ ' :
1307
+ $ value .= $ this ->lexInlineMapping ($ cursor );
1308
+
1309
+ break ;
1310
+ case '# ' :
1311
+ break 2 ;
1312
+ default :
1313
+ $ value .= $ this ->lexUnquotedString ($ cursor );
1314
+ }
1249
1315
1250
- if ('' !== $ trimmedValue && '# ' === $ trimmedValue [0 ]) {
1251
- continue ;
1316
+ if ($ this ->consumeWhitespaces ($ cursor )) {
1317
+ $ value .= ' ' ;
1318
+ }
1252
1319
}
1253
1320
1254
- $ value .= $ trimmedValue ;
1321
+ $ cursor = 0 ;
1322
+ } while ($ this ->moveToNextLine ());
1255
1323
1256
- if (isset ($ this ->currentLine [$ i ]) && '] ' === $ this ->currentLine [$ i ]) {
1257
- break ;
1324
+ return $ value ;
1325
+ }
1326
+
1327
+ private function consumeWhitespaces (int &$ cursor ): bool
1328
+ {
1329
+ $ whitespacesConsumed = 0 ;
1330
+
1331
+ do {
1332
+ $ whitespaceOnlyTokenLength = strspn ($ this ->currentLine , ' ' , $ cursor );
1333
+ $ whitespacesConsumed += $ whitespaceOnlyTokenLength ;
1334
+ $ cursor += $ whitespaceOnlyTokenLength ;
1335
+
1336
+ if (isset ($ this ->currentLine [$ cursor ])) {
1337
+ return 0 < $ whitespacesConsumed ;
1258
1338
}
1259
- }
1260
1339
1261
- return $ value ;
1340
+ $ cursor = 0 ;
1341
+ } while ($ this ->moveToNextLine ());
1342
+
1343
+ return 0 < $ whitespacesConsumed ;
1262
1344
}
1263
1345
}
0 commit comments