parseString static method
基本的に space で区切る.
aaa bbb ccc -> 'aaa', 'bbb', 'ccc'
space を要素の中に含めたい場合 variety or double quotation でその要素を囲む.
aaa 'b b' "c c" -> 'aaa', 'b b', 'c c'
variety or double quotation を要素の中に含めたい場合 \ で escape できる.
aaa 'b\'b' "c\"c" -> 'aaa', 'b'b', 'c"c'
要素の中に含まれる quotation の種類が異なる場合 escape する必要が無い.
aaa 'b"b' "c'c" -> 'aaa', 'b"b', 'c'c'
Implementation
static Danger<List<String>, ChainException> parseString(String source) {
final log = Log(classLocation: Chain, functionLocation: 'parseString');
const varietyQuotation = "'";
const doubleQuotation = '"';
const space = ' ';
const escapeSequence = '\\';
final _source = source.trim().split('');
final scanner = StringScanner<String>(_source);
String string = '';
while (true) {
final lookResult = scanner.look();
log.add(lookResult);
if (lookResult is! Success<String, ScannerExceptionA>) {
if (string.isNotEmpty) scanner.scan(string);
break;
}
final look = lookResult.wrapped;
switch (look) {
case varietyQuotation:
case doubleQuotation:
// abc'xyz' のような space を挟まずに variety quotation が来た時は abc を1つの塊と見なす.
if (string.isNotEmpty) {
final result = scanner.scan(string);
log.add(result);
string = ''; // string をリセット.
}
// variety quotation で挟まれた文字列を 1つの塊として見なす.
final lookWhileResult = scanner.lookWhileUntils([look], escapeSequence);
log.add(lookWhileResult);
if (lookWhileResult is! Survive<List<String>, StringScannerExceptionA, StringScannerErrorA>) {
switch (look) {
case varietyQuotation: return Failure(ChainExceptionB(), log);
case doubleQuotation: return Failure(ChainExceptionC(), log);
case _: Result.panic(ChainErrorB(), log.monitor({
'look': look,
}));
}
}
final result = scanner.scan(lookWhileResult.wrapped.join());
log.add(result);
case space:
// space は区切りの開始となる.
final lookWhileResult = scanner.lookWhileCharacters([' ']);
log.add(lookWhileResult);
if (string.isNotEmpty) {
final result = scanner.scan(string);
log.add(result);
string = ''; // string をリセット.
}
case _:
string = string + look;
}
}
return Success(scanner.outcome, log);
}