You can create your own simple calculator parser for this purpose and use it.
Building (generation) of the parser will take less than one second.
You can always modify it to suit your needs and generate an updated parser.
Below is an example of definition such a parser.
It contains (also for example) a value calculation for your data (as an expression).
This script will generate a parser into example/calculator.dart.
File tool/calculator_builder.dart:
import 'package:parser_builder/branch.dart';
import 'package:parser_builder/bytes.dart';
import 'package:parser_builder/char_class.dart';
import 'package:parser_builder/character.dart';
import 'package:parser_builder/combinator.dart';
import 'package:parser_builder/error.dart';
import 'package:parser_builder/expression.dart';
import 'package:parser_builder/fast_build.dart';
import 'package:parser_builder/parser_builder.dart';
import 'package:parser_builder/sequence.dart';
Future<void> main(List<String> args) async {
final context = Context();
return fastBuild(context, [_parse, _expression_], 'example/calculator.dart',
header: __header, publish: {'parse': _parse});
}
const __header = '''
import 'package:source_span/source_span.dart';
import 'package:tuple/tuple.dart';
void main() {
final List items = [5.0, "-", 2, "*", 3];
final source = items.join(' ');
final result = parse(source);
print(result);
}
num _calculate(num left, String operator, num right) {
switch (operator) {
case '+':
return left + right;
case '-':
return left - right;
case '*':
return left * right;
case '/':
return left / right;
case '~/':
return left ~/ right;
default:
throw StateError('Unknown operator: \$operator');
}
}
''';
const _additive = Named(
'_additive',
BinaryExpression(
_multiplicative, _additiveOperator, _multiplicative, _calculate));
const _additiveOperator =
Named('_additiveOperator', Terminated(Tags(['+', '-']), _ws));
const _calculate = ExpressionAction<num>(
['left', 'op', 'right'], '_calculate({{left}}, {{op}}, {{right}})');
const _closeParen = Named('_closeParen', Terminated(Tag(')'), _ws));
const _decimal = Named(
'_decimal',
Terminated(
Map1(
Recognize(
Tuple3(Digit1(), Tag('.'), Digit1()),
),
ExpressionAction<num>(['x'], 'num.parse({{x}})')),
_ws));
const _expression = Ref<String, num>('_expression');
const _expression_ = Named('_expression', _additive);
const _integer = Named(
'_integer',
Terminated(
Map1(Digit1(), ExpressionAction<num>(['x'], 'int.parse({{x}})')), _ws));
const _isWhitespace = CharClass('#x9 | #xA | #xD | #x20');
const _multiplicative = Named('_multiplicative',
BinaryExpression(_primary, _multiplicativeOperator, _primary, _calculate));
const _multiplicativeOperator =
Named('_multiplicativeOperator', Terminated(Tags(['*', '/', '~/']), _ws));
const _openParen = Named('_openParen', Terminated(Tag('('), _ws));
const _parse = Named('_parse', Delimited(_ws, _expression, Eof<String>()));
const _primary = Named(
'_primary',
Nested(
'expression',
Alt3(
_decimal,
_integer,
Delimited(_openParen, _expression, _closeParen),
)));
const _ws = Named('_ws', SkipWhile(_isWhitespace));
If you run example/calculator.dart you will get the result.
-1.0
You can modify the build script and generate it as a library (eg as lib/calculator.dart).
Then import this library and use it.
It requires some programming skills from you, but there is nothing difficult about it.
Everything is very simple.