platform/packages/combinator/example/json.dart

71 lines
1.7 KiB
Dart
Raw Normal View History

2021-03-17 23:04:36 +00:00
import 'dart:io';
2021-05-14 06:11:50 +00:00
import 'package:angel3_combinator/angel3_combinator.dart';
2021-03-17 23:04:36 +00:00
import 'package:string_scanner/string_scanner.dart';
Parser jsonGrammar() {
var expr = reference();
// Parse a number
2021-05-14 06:11:50 +00:00
var number = match<num>(RegExp(r'-?[0-9]+(\.[0-9]+)?'),
2021-03-17 23:04:36 +00:00
errorMessage: 'Expected a number.')
.value(
2021-03-18 00:00:56 +00:00
(r) => num.parse(r.span!.text),
2021-03-17 23:04:36 +00:00
);
// Parse a string (no escapes supported, because lazy).
var string =
2021-05-14 06:11:50 +00:00
match(RegExp(r'"[^"]*"'), errorMessage: 'Expected a string.').value(
2021-03-18 00:00:56 +00:00
(r) => r.span!.text.substring(1, r.span!.text.length - 1),
2021-03-17 23:04:36 +00:00
);
// Parse an array
var array = expr
.space()
.separatedByComma()
.surroundedBySquareBrackets(defaultValue: []);
// KV pair
var keyValuePair = chain([
string.space(),
match(':').space(),
expr.error(errorMessage: 'Missing expression.'),
2021-03-18 00:00:56 +00:00
]).castDynamic().cast<Map>().value((r) => {r.value![0]: r.value![2]});
2021-03-17 23:04:36 +00:00
// Parse an object.
var object = keyValuePair
.separatedByComma()
.castDynamic()
.surroundedByCurlyBraces(defaultValue: {});
expr.parser = longest(
[
array,
number,
string,
object.error(),
],
errorMessage: 'Expected an expression.',
).space();
return expr.foldErrors();
}
main() {
var JSON = jsonGrammar();
while (true) {
stdout.write('Enter some JSON: ');
2021-03-18 00:00:56 +00:00
var line = stdin.readLineSync()!;
2021-05-14 06:11:50 +00:00
var scanner = SpanScanner(line, sourceUrl: 'stdin');
2021-05-02 04:12:43 +00:00
var result = JSON.parse(scanner);
2021-03-17 23:04:36 +00:00
if (!result.successful) {
for (var error in result.errors) {
print(error.toolString);
2021-03-18 00:00:56 +00:00
print(error.span!.highlight(color: true));
2021-03-17 23:04:36 +00:00
}
} else
print(result.value);
}
}