anchor.diff:            '0b1_0_0': 0x4,
             '0b1000': 0x8,
             '0b1_000': 0x8,
  -        }.map((key, value) {
  -          final newValue = Literal(
  -            IntegerLiteralToken(value, span: SourceSpan(0, key.length)),
  -          );
  -          return MapEntry(key, newValue);
  -        }),
  +        },
  +        astMapper: (value, fullSpan) =>
  +            Literal(IntegerLiteralToken(value, span: fullSpan)),
         );
       });
  -    tableTestExpressionParser<Literal<bool>>(
  +    tableTestExpressionParser<bool, Literal<bool>>(
         'BooleanLiteral',
         table: {
           'true': true,
           'false': false,
  -      }.map((key, value) {
  -        final newValue = Literal(
  -          BooleanLiteralToken(value, span: SourceSpan(0, key.length)),
  -        );
  -        return MapEntry(key, newValue);
  -      }),
  +      },
  +      astMapper: (value, fullSpan) =>
  +          Literal(BooleanLiteralToken(value, span: fullSpan)),
       );
     });
   }
  
positive.code: }
  
  @isTestGroup
  void tableTestParser<R extends AstNode>(
    String description, {
    @required Map<String, R> table,
    @required Parser parser,
  }) {
    assert(table != null);
    assert(parser != null);
  
    tableTest<String, R>(
      description,
      table: table,
      converter: (source) {
        final result = parser.parse(source);
        expect(result.isSuccess, isTrue);
  
negative.code:   group('literals', () {
      group('IntegerLiteral', () {
        // TODO(JonasWanke): negative literals
        tableTestExpressionParser<int, Literal<int>>(
          'decimal',
          table: {
            '0': 0,
  