1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
|
package GraphQL::Language::Parser;
use 5.014;
use strict;
use warnings;
use base qw(Pegex::Parser);
use Exporter 'import';
use Types::Standard -all;
use GraphQL::MaybeTypeCheck;
use GraphQL::Language::Grammar;
use GraphQL::Language::Receiver;
use GraphQL::Error;
our $VERSION = '0.02';
our @EXPORT_OK = qw(
parse
);
=head1 NAME
GraphQL::Language::Parser - GraphQL Pegex parser
=head1 SYNOPSIS
use GraphQL::Language::Parser qw(parse);
my $parsed = parse(
$source
);
=head1 DESCRIPTION
Provides both an outside-accessible point of entry into the GraphQL
parser (see above), and a subclass of L<Pegex::Parser> to parse a document
into an AST usable by GraphQL.
=head1 METHODS
=head2 parse
parse($source, $noLocation);
B<NB> that unlike in C<Pegex::Parser> this is a function, not an instance
method. This achieves hiding of Pegex implementation details.
=cut
my $GRAMMAR = GraphQL::Language::Grammar->new; # singleton
fun parse(
Str $source,
Bool $noLocation = undef,
) :ReturnType(ArrayRef[HashRef]) {
my $parser = __PACKAGE__->SUPER::new(
grammar => $GRAMMAR,
receiver => GraphQL::Language::Receiver->new,
);
my $input = Pegex::Input->new(string => $source);
scalar $parser->SUPER::parse($input);
}
=head2 format_error
Override of parent method. Returns a L<GraphQL::Error>.
=cut
sub format_error :ReturnType(InstanceOf['GraphQL::Error']) {
my ($self, $msg) = @_;
my $buffer = $self->{buffer};
my $position = $self->{farthest};
my $real_pos = $self->{position};
my ($line, $column) = @{$self->line_column($position)};
my $pretext = substr(
$$buffer,
$position < 50 ? 0 : $position - 50,
$position < 50 ? $position : 50
);
my $context = substr($$buffer, $position, 50);
$pretext =~ s/.*\n//gs;
$context =~ s/\n/\\n/g;
return GraphQL::Error->new(
locations => [ { line => $line, column => $column } ],
message => <<EOF);
Error parsing Pegex document:
msg: $msg
context: $pretext$context
${\ (' ' x (length($pretext)) . '^')}
position: $position ($real_pos pre-lookahead)
EOF
}
1;
|