Nathaniel Waisbrot
Nathaniel Waisbrot

Reputation: 24513

Outputting a context-appropriate error message on a missing token

I have a grammar to parse some source code:

document
  : header body_block* EOF
    -> body_block*
  ;

header
  : header_statement*
  ;

body_block
  : '{' block_contents '}'
  ;

block_contents
  : declaration_list
  | ... other things ....

It's legal for a document to have a header without a body or a body without a header.

If I try to parse a document that looks like

int i;

then ANTLR complains that it found int when it was expecting EOF. This is true, but I'd like it to say that it was expecting {. That is, if the input contains something between the header and the EOF that's not a body_block, then I'd like to suggest to the user that they meant to enclose that text inside a body_block.

I've made a couple almost working attempts at this that I can post if that's illuminating, but I'm hoping that I've just missed something easy.

Upvotes: 1

Views: 68

Answers (1)

Bart Kiers
Bart Kiers

Reputation: 170227

Not pretty, but something like this would do it:

body_block
 : ('{')=> '{' block_contents '}'
 | t=.
   {
     if(!$t.text.equals("{")) {
       String message = "expected a '{' on line " + $t.getLine() + " near '" + $t.text + "'";
     }
     else {
       String message = "encountered a '{' without a '}' on line " + $t.getLine();
     }
     throw new RuntimeException(message);
   }
 ;

(not tested, may contain syntax errors!)

So, whenever '{' ... '}' is not matched, it falls through to .1 and produces a more understandable error message.



1 note that a . in a parser rule matches any token, not any character!

Upvotes: 1

Related Questions