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