One major advantage that JavaCC has is no runtime component. It
generates the files needed, and your parser is completely self
contained. ANTLR build parsers can run into problems if you have two
libraries which both use ANTLR. This is more common than you might
think.

For example, I help maintain a copy paste detector which uses ANTLR
(same-code-duplication-detector). It can be run from Ant, but it may
fail if you also use CheckStyle. If the runtime component was binary
compatible, this wouldn't be so much of an issue, but unfortunately,
it changes between point releases. The solution in the above case is
to put my tool into a separate classloader, which makes using it more
complicated.

If your app has multiple parsers, and they're all built off from
whatever version on ANTLR you have, then you're probably going to be
OK, and may even be smaller than multiple JavaCC parsers. But, if you
take someone else's jar file, and they have an ANTLR dependency, then
your project can become quite complicated.

ANTLR v3 has a lot of great features, like being able to target other
languages. But, I think some of these features make it a bit harder
to learn.

I would check to see if there is a existing grammar available for what
you want to parse, and start with the tool that you can find the
grammar for.