1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverpackage ANTLR::Runtime::Lexer;
2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruveruse English qw( -no_match_vars );
4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruveruse Readonly;
5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruveruse Carp;
6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruveruse Switch;
7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruveruse ANTLR::Runtime::Token;
9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruveruse ANTLR::Runtime::CommonToken;
10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruveruse ANTLR::Runtime::CharStream;
11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruveruse ANTLR::Runtime::MismatchedTokenException;
12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruveruse Moose;
14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverextends 'ANTLR::Runtime::BaseRecognizer';
16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverwith 'ANTLR::Runtime::TokenSource';
17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverhas 'input' => (
19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    is => 'rw',
20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    does => 'ANTLR::Runtime::CharStream',
21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver);
22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruversub reset {
24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    my ($self) = @_;
25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # reset all recognizer state variables
27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    $self->SUPER::reset();
28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # wack Lexer state variables
30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if (defined $self->input) {
31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # rewind the input
32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        $self->input->seek(0);
33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if (defined $self->state) {
36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        $self->state->token(undef);
37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        $self->state->type(ANTLR::Runtime::Token->INVALID_TOKEN_TYPE);
38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        $self->state->channel(ANTLR::Runtime::Token->DEFAULT_CHANNEL);
39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        $self->state->token_start_char_index(-1);
40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        $self->state->token_start_char_position_in_line(-1);
41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        $self->state->start_line(-1);
42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        $self->state->text(undef);
43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# Return a token from this source; i.e., match a token on the char
47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# stream.
48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruversub next_token {
49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    my ($self) = @_;
50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    while (1) {
52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        $self->state->token(undef);
53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        $self->state->channel(ANTLR::Runtime::Token->DEFAULT_CHANNEL);
54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        $self->state->token_start_char_index($self->input->index());
55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        $self->state->token_start_char_position_in_line($self->input->get_char_position_in_line());
56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        $self->state->token_start_line($self->input->get_line());
57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        $self->state->text(undef);
58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if ($self->input->LA(1) eq ANTLR::Runtime::CharStream->EOF) {
60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return ANTLR::Runtime::Token->EOF_TOKEN;
61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        my $rv;
64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        my $op = '';
65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        eval {
66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            $self->m_tokens();
67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (!defined $self->state->token) {
68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                $self->emit();
69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            elsif ($self->state->token == ANTLR::Runtime::Token->SKIP_TOKEN) {
71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                $op = 'next';
72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return;
73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            $op = 'return';
75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            $rv = $self->state->token;
76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        };
77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return $rv if $op eq 'return';
78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        next if $op eq 'next';
79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if ($EVAL_ERROR) {
81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            my $exception = $EVAL_ERROR;
82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ($exception->isa('ANTLR::Runtime::RecognitionException')) {
83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                $self->report_error($exception);
84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                $self->recover($exception);
85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            } else {
86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                croak $exception;
87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# Instruct the lexer to skip creating a token for current lexer rule
93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# and look for another token.  nextToken() knows to keep looking when
94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# a lexer rule finishes with token set to SKIP_TOKEN.  Recall that
95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# if token==null at end of any token rule, it creates one for you
96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# and emits it.
97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruversub skip {
98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    my ($self) = @_;
99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    $self->state->token(ANTLR::Runtime::Token->SKIP_TOKEN);
101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return;
102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# This is the lexer entry point that sets instance var 'token'
105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruversub m_tokens {
106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    croak "Unimplemented";
107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# Set the char stream and reset the lexer
110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruversub set_char_stream {
111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    my ($self, $input) = @_;
112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    $self->input(undef);
114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    $self->reset();
115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    $self->input($input);
116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruversub get_char_stream {
119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    my ($self) = @_;
120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return $self->input;
121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruversub get_source_name {
124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    my ($self) = @_;
125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return $self->input->get_source_name();
126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruversub emit {
129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if (@_ == 1) {
130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        my ($self) = @_;
131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	# The standard method called to automatically emit a token at the
132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	# outermost lexical rule.  The token object should point into the
133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	# char buffer start..stop.  If there is a text override in 'text',
134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	# use that to set the token's text.  Override this method to emit
135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	# custom Token objects.
136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        my $t = ANTLR::Runtime::CommonToken->new({
137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            input => $self->input,
138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            type  => $self->state->type,
139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            channel => $self->state->channel,
140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            start => $self->state->token_start_char_index,
141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            stop => $self->get_char_index() - 1
142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        });
143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        $t->set_line($self->state->token_start_line);
145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        $t->set_text($self->state->text);
146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        $t->set_char_position_in_line($self->state->token_start_char_position_in_line);
147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        $self->emit($t);
148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return $t;
149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    } elsif (@_ == 2) {
150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        my ($self, $token) = @_;
151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	# Currently does not support multiple emits per nextToken invocation
152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	# for efficiency reasons.  Subclass and override this method and
153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	# nextToken (to push tokens into a list and pull from that list rather
154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	# than a single variable as this implementation does).
155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        $self->state->token($token);
156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruversub match {
160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    my ($self, $s) = @_;
161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    foreach my $c (split //, $s) {
163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if ($self->input->LA(1) ne $c) {
164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ($self->state->backtracking > 0) {
165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                $self->state->failed(1);
166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return;
167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            my $mte = ANTLR::Runtime::MismatchedTokenException->new({
169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                expecting => $c,
170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                input => $self->input
171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            });
172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            $self->recover($mte);
173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            croak $mte;
174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        $self->input->consume();
176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        $self->state->failed(0);
177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruversub match_any {
181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    my ($self) = @_;
182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    $self->input->consume();
184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruversub match_range {
187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    my ($self, $a, $b) = @_;
188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if ($self->input->LA(1) lt $a || $self->input->LA(1) gt $b) {
190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if ($self->state->backtracking > 0) {
191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            $self->state->failed(1);
192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return;
193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        my $mre = ANTLR::Runtime::MismatchedRangeException($a, $b, $self->input);
196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        $self->recover($mre);
197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        croak $mre;
198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    $self->input->consume();
201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    $self->state->failed(0);
202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruversub get_line {
205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    my ($self) = @_;
206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return $self->input->get_line();
208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruversub get_char_position_in_line {
211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    my ($self) = @_;
212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return $self->input->get_char_position_in_line();
214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# What is the index of the current character of lookahead?
217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruversub get_char_index {
218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    my ($self) = @_;
219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return $self->input->index();
221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# Return the text matched so far for the current token or any
224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# text override.
225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruversub get_text {
226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    my ($self) = @_;
227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if (defined $self->state->text) {
229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return $self->state->text;
230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return $self->input->substring($self->state->token_start_char_index, $self->get_char_index() - 1);
232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# Set the complete text of this token; it wipes any previous
235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# changes to the text.
236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruversub set_text {
237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    my ($self, $text) = @_;
238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    $self->state->text($text);
240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruversub report_error {
243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    Readonly my $usage => 'void report_error(RecognitionException e)';
244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    croak $usage if @_ != 2;
245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    my ($self, $e) = @_;
246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    $self->display_recognition_error($self->get_token_names(), $e);
248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruversub get_error_message {
251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    my ($self, $e, $token_names) = @_;
252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    my $msg;
254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if ($e->isa('ANTLR::Runtime::MismatchedTokenException')) {
255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        $msg = 'mismatched character '
256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          . $self->get_char_error_display($e->get_c())
257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          . ' expecting '
258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          . $self->get_char_error_display($e->expecting);
259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    } elsif ($e->isa('ANTLR::Runtime::NoViableAltException')) {
260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        $msg = 'no viable alternative at character ' . $self->get_char_error_display($e->get_c());
261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    } elsif ($e->isa('ANTLR::Runtime::EarlyExitException')) {
262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        $msg = 'required (...)+ loop did not match anything at character '
263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          . $self->get_char_error_display($e->get_c());
264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    } elsif ($e->isa('ANTLR::Runtime::MismatchedSetException')) {
265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        $msg = 'mismatched character ' . $self->get_char_error_display($e->get_c())
266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          . ' expecting set ' . $e->expecting;
267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    } elsif ($e->isa('ANTLR::Runtime::MismatchedNotSetException')) {
268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        $msg = 'mismatched character ' . $self->get_char_error_display($e->get_c())
269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          . ' expecting set ' . $e->expecting;
270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    } elsif ($e->isa('ANTLR::Runtime::MismatchedRangeException')) {
271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        $msg = 'mismatched character ' . $self->get_char_error_display($e->get_c())
272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          . ' expecting set ' . $self->get_char_error_display($e->a)
273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          . '..' . $self->get_char_error_display($e->b);
274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    } else {
275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        $msg = $self->SUPER::get_error_message($e, $token_names);
276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return $msg;
278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruversub get_char_error_display {
281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    my ($self, $c) = @_;
282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    my $s;
284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if ($c eq ANTLR::Runtime::Token->EOF) {
285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        $s = '<EOF>';
286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    } elsif ($c eq "\n") {
287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        $s = '\n';
288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    } elsif ($c eq "\t") {
289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        $s = '\t';
290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    } elsif ($c eq "\r") {
291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        $s = '\r';
292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    } else {
293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        $s = $c;
294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return "'$s'";
297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# Lexers can normally match any char in it's vocabulary after matching
300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# a token, so do the easy thing and just kill a character and hope
301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# it all works out.  You can instead use the rule invocation stack
302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# to do sophisticated error recovery if you are in a fragment rule.
303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruversub recover {
304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    my ($self, $re) = @_;
305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    $self->input->consume();
307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruversub trace_in {
310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    my ($self, $rule_name, $rule_index) = @_;
311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    my $input_symbol = $self->input->LT(1) . ' line=' . $self->get_line() . ':' . $self->get_char_position_in_line();
313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    $self->SUPER::trace_in($rule_name, $rule_index, $input_symbol);
314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruversub trace_out {
317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    my ($self, $rule_name, $rule_index) = @_;
318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    my $input_symbol = $self->input->LT(1) . ' line=' . $self->get_line() . ':' . $self->get_char_position_in_line();
320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    $self->SUPER::trace_out($rule_name, $rule_index, $input_symbol);
321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverno Moose;
324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver__PACKAGE__->meta->make_immutable();
325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver1;
326