[antlr-interest] ANTLR3C displayRecognitionError

Jim Idle jimi at temporal-wave.com
Wed May 20 08:45:37 PDT 2009


Mark Rosen wrote:
> Jim,
>  
> Great job with ANTLR3C, by the way. Very useful... The documentation 
> page below describes how to install your own custom 
> displayRecognitionError handler. I've done this, but what escapes me 
> is how to remember the errors to print out for later display. Sure, I 
> could put them in a global variable, but I'd like for multiple 
> instances of my parser to be able to be called concurrently. Is there 
> any way to add a data structure (like a list<string>) to the 
> ANTLR3_BASE_RECOGNIZER class?
>  
> http://antlr.org/api/C/group__apistructures.html
>  
Hi Mark,

Yes, you can indeed do this (comes from using the code myself - I run in 
to the same things :-), but you do not add it to the . For some reason, 
the doxygen generated docs are not including the doc pages about this, I 
will have to find out why.

I generally use an ANTLR3_VECTOR (because then it is ordered), but tend 
to collect all such things (counters, parameters etc) in a mast 
structure like this:

@parser::context
{
        pMY_PARSE_SESSION              ps;                     // MY 
compiler session context for parser
}

Anything in the @lexer/@parser ::context section is adding verbatim into 
the context struct (referenced via ctx), and you can initialize it in 
@apifuncs, or externally.

The base recognizer has a void * pointer called super, which will point 
to the parser instance (you can see that the the default error display 
routines pick this up.). However, ANTLR3_PARSER also has this field, but 
it is not initialized by default because I cannot know that the instance 
of your generated parser is what you want it to point at (I suppose I 
could assume this and let you override it, but it is probably better to 
explicitly initialize it for future reference.

So, in your apifuncs section:

@parser::apifuncs {

  ctx->ps = myNewContextGrooveThang;

  PARSER->super = (void *)ctx;
}


Now, in your display routine, you will get the parser pointer from base 
recognizer, get the ctx pointer from super, and your custom, thread safe 
collection will be in your master structure. A few pointer chases, but 
this provides maximum flexibility:

displayRecognitionError        (pANTLR3_BASE_RECOGNIZER recognizer, 
pANTLR3_UINT8 * tokenNames)
{
   pANTLR3_PARSER            parser;
   pmyParser                             generated;
   pMY_PARSE_SESSION              ps;

   parser        = (pANTLR3_PARSER) (recognizer->super);
   generated  = (pmyParser)(generated->super);
   ps               = generated->ps;

   // Bob's your uncle.....


Jim


More information about the antlr-interest mailing list