[antlr-interest] Antlr3 does not report error with incorrect input.

Martin Fowler fowler at acm.org
Mon Mar 5 09:00:09 PST 2007


I'm doing a simple hello-world style thing with Antlr 3 just to get it
going. The idea is to read text in the form of

   item camera
   item laser

where item is a keyword and I want to store all the things I read. I
can write a grammar that reads in the values, but the odd thing is
that this grammar doesn't seem to throw an exception if I put in
something incorrect like "xitem camera". Instead it reads the file,
not recognizing anything, and indicates no error. I would expect an
error if the file contains text that doesn't conform to the
grammar. Can anyone let me know where I'm goofing?

BTW If I do this in AntlrWorks it does generate a NoViableAltException.

Gory Details
============

Here's the various files. I've looked at the tokens coming out the
lexer, and for "xitem item" it reports two strings, as I would
expect. The generated parser just looks for a token and if it isn't
the 'item' keyword it seems to just terminate without an error.

I'm running this using the IntelliJ plug in.


------------ Grammar File ----------------

grammar Catalog;

@header{
package parser;
import model.*;
}
@lexer::header {
package parser;
}

@members {
   public Configuration result = new Configuration();
}

catalog :  item*;

item 	: ITEM_DEC n=name {result.addItem(new Item ($n.text));};

name 	: STRING;

ITEM_DEC
	: 'item';
STRING 	: ('a'..'z' | 'A'..'Z')+ ;

fragment NEWLINE:'\r' ? '\n' ;
WS : (' ' |'\t' | NEWLINE)+ {skip();} ;

------------------ Test File --------------

import static org.junit.Assert.*;
import org.junit.*;

import parser.*;
import model.*;

import java.io.*;

public class CatalogTest {

  // This test fails
   @Test(expected = RuntimeException.class)
   public void failOnParseError() {
     StringReader input = new StringReader("xitem foo");
     Configuration config = ParserCommand.parse(input);
   }

}

---- Command wrapper ----------------
package parser;

import model.*;

import org.antlr.runtime.*;

import java.io.*;

public class ParserCommand {
   private CatalogParser parser;
   private Reader input;

   public ParserCommand(Reader input) {
     this.input = input;
   }

   public static Configuration parse(Reader input) {
     ParserCommand cmd = new ParserCommand(input);
     cmd.run();
     return cmd.getConfiguration();
   }

   private Configuration getConfiguration() {
     return parser.result;
   }

   public void run() {
     try {
       CatalogLexer lexer = new CatalogLexer(new ANTLRReaderStream(input));
       CommonTokenStream tokens = new CommonTokenStream(lexer);
       for (Object t : tokens.getTokens()) System.out.printf("<%s> = ", t);
       parser = new CatalogParser(tokens);
       parser.catalog();
     } catch (Exception e) {
       throw new RuntimeException(e);
     }
   }

}


-- 
Martin Fowler
http://martinfowler.com


More information about the antlr-interest mailing list