Created
January 28, 2024 09:39
-
-
Save sma/d45556007f351f1d2b569114d13b1fdf to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// Parses a plist file into a Dart object. | |
dynamic parsePlist(String plist) { | |
final tokens = RegExp(r'(\s+|<[!?].*?>)|<(/?\w+)[^>]*>|([^<]*)', dotAll: true) | |
.allMatches(plist) | |
.where((match) => match[1] == null) | |
.map((match) => match[2] != null ? (1, match[2]!) : (2, match[3]!)) | |
.followedBy([(0, '')]).iterator | |
..moveNext(); | |
bool at(String s) => tokens.current == (1, s) && tokens.moveNext(); | |
bool expect(String s) => at(s) || (throw 'Expected <$s>, got ${tokens.current}'); | |
T andExpect<T>(T Function() f, String s) { | |
final result = f(); | |
expect(s); | |
return result; | |
} | |
String text() { | |
final (t, s) = tokens.current; | |
if (t != 2) throw 'Expected text, got ${tokens.current}'; | |
tokens.moveNext(); | |
return s.replaceAll('&', '&').replaceAll('<', '<'); | |
} | |
dynamic parse() { | |
if (at('dict')) { | |
return andExpect(() => <String, dynamic>{for (; at('key');) andExpect(text, '/key'): parse()}, '/dict'); | |
} else if (at('array')) { | |
return <dynamic>[for (; !at('/array');) parse()]; | |
} else if (at('string')) { | |
return at('/string') ? '' : andExpect(text, '/string'); | |
} else { | |
throw 'Expected dict, array or string, got ${tokens.current}'; | |
} | |
} | |
expect('plist'); | |
return andExpect(parse, '/plist'); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment