[...]
> >
> I'll take a look - does that snippet of code above reproduce it? What
> options {} have you got set etc? If you have the time, then a small,
> but complete, grammar would be helpful :-)
>
It does. I have attached the grammar and and the resulting C file. With
1 argument, this is the code that is generated from that template:
#if 1 == 2
(pANTLR3_BASE_TREE)ADAPTOR->createTypeTokenText(ADAPTOR, BAR,
TOKTEXT(b))
#else
(pANTLR3_BASE_TREE)ADAPTOR->createTypeText(ADAPTOR, BAR,
(pANTLR3_UINT8)b)
#endif
While, on the other hand, with 2 arguments you get this:
#if 2 == 2
(pANTLR3_BASE_TREE)ADAPTOR->createTypeTokenText(ADAPTOR, BAR, TOKTEXT(b,
""))
#else
(pANTLR3_BASE_TREE)ADAPTOR->createTypeText(ADAPTOR, BAR,
(pANTLR3_UINT8)b, "")
#endif
With one argument, you can see that a node is created from the text,
while with 2 arguments the token along with the text is passed.
Thanks for looking into this, even though there is an easy workaround.
Sven
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"il-antlr-interest" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/il-antlr-interest?hl=en
-~----------~----~----~----~------~----~------~--~---
grammar imgnodes;
options {
language = C ;
output=AST ;
ASTLabelType = pANTLR3_BASE_TREE;
}
tokens {
BAR;
}
//foo : b='bar' -> ^( BAR[ $b, "" ] )
foo : b='bar' -> ^( BAR[ $b ] )
;
/** \file
* This C source file was generated by $ANTLR version 3.1.1
*
* - From the grammar source file : imgnodes.g
* - On : 2008-12-12 09:35:37
* - for the parser : imgnodesParserParser *
* Editing it, at least manually, is not wise.
*
* C language generator and runtime by Jim Idle, jimi|hereisanat|idle|dotgoeshere|ws.
*
*
*/
/* -----------------------------------------
* Include the ANTLR3 generated header file.
*/
#include "imgnodesParser.h"
/* ----------------------------------------- */
/* MACROS that hide the C interface implementations from the
* generated code, which makes it a little more understandable to the human eye.
* I am very much against using C pre-processor macros for function calls and bits
* of code as you cannot see what is happening when single stepping in debuggers
* and so on. The exception (in my book at least) is for generated code, where you are
* not maintaining it, but may wish to read and understand it. If you single step it, you know that input()
* hides some indirect calls, but is always referring to the input stream. This is
* probably more readable than ctx->input->istream->input(snarfle0->blarg) and allows me to rejig
* the runtime interfaces without changing the generated code too often, without
* confusing the reader of the generated output, who may not wish to know the gory
* details of the interface inheritance.
*/
#define CTX ctx
/* Aids in accessing scopes for grammar programmers
*/
#undef SCOPE_TYPE
#undef SCOPE_STACK
#undef SCOPE_TOP
#define SCOPE_TYPE(scope) pimgnodesParser_##scope##_SCOPE
#define SCOPE_STACK(scope) pimgnodesParser_##scope##Stack
#define SCOPE_TOP(scope) ctx->pimgnodesParser_##scope##Top
#define SCOPE_SIZE(scope) (ctx->SCOPE_STACK(scope)->size(ctx->SCOPE_STACK(scope)))
#define SCOPE_INSTANCE(scope, i) (ctx->SCOPE_STACK(scope)->get(ctx->SCOPE_STACK(scope),i))
/* Macros for accessing things in the parser
*/
#undef PARSER
#undef RECOGNIZER
#undef HAVEPARSEDRULE
#undef MEMOIZE
#undef INPUT
#undef STRSTREAM
#undef HASEXCEPTION
#undef EXCEPTION
#undef MATCHT
#undef MATCHANYT
#undef FOLLOWSTACK
#undef FOLLOWPUSH
#undef FOLLOWPOP
#undef PRECOVER
#undef PREPORTERROR
#undef LA
#undef LT
#undef CONSTRUCTEX
#undef CONSUME
#undef MARK
#undef REWIND
#undef REWINDLAST
#undef PERRORRECOVERY
#undef HASFAILED
#undef FAILEDFLAG
#undef RECOVERFROMMISMATCHEDSET
#undef RECOVERFROMMISMATCHEDELEMENT
#undef INDEX
#undef ADAPTOR
#undef SEEK
#undef RULEMEMO
#undef DBG
#define PARSER ctx->pParser
#define RECOGNIZER PARSER->rec
#define PSRSTATE RECOGNIZER->state
#define HAVEPARSEDRULE(r) RECOGNIZER->alreadyParsedRule(RECOGNIZER, r)
#define MEMOIZE(ri,si) RECOGNIZER->memoize(RECOGNIZER, ri, si)
#define INPUT PARSER->tstream
#define STRSTREAM INPUT
#define ISTREAM INPUT->istream
#define INDEX() ISTREAM->index(INPUT->istream)
#define HASEXCEPTION() (PSRSTATE->error == ANTLR3_TRUE)
#define EXCEPTION PSRSTATE->exception
#define MATCHT(t, fs) RECOGNIZER->match(RECOGNIZER, t, fs)
#define MATCHANYT() RECOGNIZER->matchAny(RECOGNIZER)
#define FOLLOWSTACK PSRSTATE->following
#define FOLLOWPUSH(x) FOLLOWSTACK->push(FOLLOWSTACK, ((void *)(&(x))), NULL)
#define FOLLOWPOP() FOLLOWSTACK->pop(FOLLOWSTACK)
#define PRECOVER() RECOGNIZER->recover(RECOGNIZER)
#define PREPORTERROR() RECOGNIZER->reportError(RECOGNIZER)
#define LA(n) INPUT->istream->_LA(ISTREAM, n)
#define LT(n) INPUT->_LT(INPUT, n)
#define CONSTRUCTEX() RECOGNIZER->exConstruct(RECOGNIZER)
#define CONSUME() ISTREAM->consume(ISTREAM)
#define MARK() ISTREAM->mark(ISTREAM)
#define REWIND(m) ISTREAM->rewind(ISTREAM, m)
#define REWINDLAST() ISTREAM->rewindLast(ISTREAM)
#define SEEK(n) ISTREAM->seek(ISTREAM, n)
#define PERRORRECOVERY PSRSTATE->errorRecovery
#define FAILEDFLAG PSRSTATE->failed
#define HASFAILED() (FAILEDFLAG == ANTLR3_TRUE)
#define BACKTRACKING PSRSTATE->backtracking
#define RECOVERFROMMISMATCHEDSET(s) RECOGNIZER->recoverFromMismatchedSet(RECOGNIZER, s)
#define RECOVERFROMMISMATCHEDELEMENT(e) RECOGNIZER->recoverFromMismatchedElement(RECOGNIZER, s)
#define ADAPTOR ctx->adaptor
#define RULEMEMO PSRSTATE->ruleMemo
#define DBG RECOGNIZER->debugger
#define TOKTEXT(tok, txt) tok, (pANTLR3_UINT8)txt
/* The 4 tokens defined below may well clash with your own #defines or token types. If so
* then for the present you must use different names for your defines as these are hard coded
* in the code generator. It would be better not to use such names internally, and maybe
* we can change this in a forthcoming release. I deliberately do not #undef these
* here as this will at least give you a redefined error somewhere if they clash.
*/
#define UP ANTLR3_TOKEN_UP
#define DOWN ANTLR3_TOKEN_DOWN
#define EOR ANTLR3_TOKEN_EOR
#define INVALID ANTLR3_TOKEN_INVALID
/* =============================================================================
* Functions to create and destroy scopes. First come the rule scopes, followed
* by the global declared scopes.
*/
/* ============================================================================= */
/* =============================================================================
* Start of recognizer
*/
/** \brief Table of all token names in symbolic order, mainly used for
* error reporting.
*/
pANTLR3_UINT8 imgnodesParserTokenNames[2+4]
= {
(pANTLR3_UINT8) "<invalid>", /* String to print to indicate an invalid token */
(pANTLR3_UINT8) "<EOR>",
(pANTLR3_UINT8) "<DOWN>",
(pANTLR3_UINT8) "<UP>",
(pANTLR3_UINT8) "BAR",
(pANTLR3_UINT8) "'bar'"
};
// Forward declare the locally static matching functions we have generated.
//
static imgnodesParser_foo_return foo (pimgnodesParser ctx);
static void imgnodesParserFree(pimgnodesParser ctx);
/* For use in tree output where we are accumulating rule labels via label += ruleRef
* we need a function that knows how to free a return scope when the list is destroyed.
* We cannot just use ANTLR3_FREE because in debug tracking mode, this is a macro.
*/
static void ANTLR3_CDECL freeScope(void * scope)
{
ANTLR3_FREE(scope);
}
/** \brief Name of the grammar file that generated this code
*/
static const char fileName[] = "imgnodes.g";
/** \brief Return the name of the grammar file that generated this code.
*/
static const char * getGrammarFileName()
{
return fileName;
}
/** \brief Create a new imgnodesParser parser and return a context for it.
*
* \param[in] instream Pointer to an input stream interface.
*
* \return Pointer to new parser context upon success.
*/
ANTLR3_API pimgnodesParser
imgnodesParserNew (pANTLR3_COMMON_TOKEN_STREAM instream)
{
// See if we can create a new parser with the standard constructor
//
return imgnodesParserNewSSD(instream, NULL);
}
/** \brief Create a new imgnodesParser parser and return a context for it.
*
* \param[in] instream Pointer to an input stream interface.
*
* \return Pointer to new parser context upon success.
*/
ANTLR3_API pimgnodesParser
imgnodesParserNewSSD (pANTLR3_COMMON_TOKEN_STREAM instream, pANTLR3_RECOGNIZER_SHARED_STATE state)
{
pimgnodesParser ctx; /* Context structure we will build and return */
ctx = (pimgnodesParser) ANTLR3_CALLOC(1, sizeof(imgnodesParser));
if (ctx == NULL)
{
// Failed to allocate memory for parser context
//
return NULL;
}
/* -------------------------------------------------------------------
* Memory for basic structure is allocated, now to fill in
* the base ANTLR3 structures. We initialize the function pointers
* for the standard ANTLR3 parser function set, but upon return
* from here, the programmer may set the pointers to provide custom
* implementations of each function.
*
* We don't use the macros defined in imgnodesParser.h here, in order that you can get a sense
* of what goes where.
*/
/* Create a base parser/recognizer, using the supplied token stream
*/
ctx->pParser = antlr3ParserNewStream(ANTLR3_SIZE_HINT, instream->tstream, state);
/* Install the implementation of our imgnodesParser interface
*/
ctx->foo = foo;
ctx->free = imgnodesParserFree;
ctx->getGrammarFileName = getGrammarFileName;
/* Install the scope pushing methods.
*/
ADAPTOR = ANTLR3_TREE_ADAPTORNew(instream->tstream->tokenSource->strFactory);
ctx->vectors = antlr3VectorFactoryNew(64);
/* Install the token table
*/
PSRSTATE->tokenNames = imgnodesParserTokenNames;
/* Return the newly built parser to the caller
*/
return ctx;
}
/** Free the parser resources
*/
static void
imgnodesParserFree(pimgnodesParser ctx)
{
/* Free any scope memory
*/
ctx->vectors->close(ctx->vectors);
/* We created the adaptor so we must free it
*/
ADAPTOR->free(ADAPTOR);
// Free this parser
//
ctx->pParser->free(ctx->pParser);
ANTLR3_FREE(ctx);
/* Everything is released, so we can return
*/
return;
}
/** Return token names used by this parser
*
* The returned pointer is used as an index into the token names table (using the token
* number as the index).
*
* \return Pointer to first char * in the table.
*/
static pANTLR3_UINT8 *getTokenNames()
{
return imgnodesParserTokenNames;
}
/* Declare the bitsets
*/
/** Bitset defining follow set for error recovery in rule state: FOLLOW_5_in_foo63 */
static ANTLR3_BITWORD FOLLOW_5_in_foo63_bits[] = { ANTLR3_UINT64_LIT(0x0000000000000002) };
static ANTLR3_BITSET_LIST FOLLOW_5_in_foo63 = { FOLLOW_5_in_foo63_bits, 1 };
/* ==============================================
* Parsing rules
*/
/**
* $ANTLR start foo
* imgnodes.g:16:1: foo : b= 'bar' -> ^( BAR[ $b ] ) ;
*/
static imgnodesParser_foo_return
foo(pimgnodesParser ctx)
{
imgnodesParser_foo_return retval;
pANTLR3_BASE_TREE root_0;
pANTLR3_COMMON_TOKEN b;
pANTLR3_BASE_TREE b_tree;
pANTLR3_REWRITE_RULE_TOKEN_STREAM stream_5;
/* Initialize rule variables
*/
root_0 = NULL;
b = NULL;
retval.start = LT(1);
b_tree = NULL;
stream_5 = antlr3RewriteRuleTOKENStreamNewAE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"token 5");
retval.tree = NULL;
{
// imgnodes.g:16:5: (b= 'bar' -> ^( BAR[ $b ] ) )
// imgnodes.g:16:7: b= 'bar'
{
b = (pANTLR3_COMMON_TOKEN) MATCHT(5, &FOLLOW_5_in_foo63);
if (HASEXCEPTION())
{
goto rulefooEx;
}
stream_5->add(stream_5, b, NULL);
/* AST REWRITE
* elements :
* token labels :
* rule labels : retval
* token list labels :
* rule list labels :
*/
{
pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream_retval;
stream_retval=antlr3RewriteRuleSubtreeStreamNewAEE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"token retval", retval.tree != NULL ? retval.tree : NULL);
root_0 = (pANTLR3_BASE_TREE)(ADAPTOR->nilNode(ADAPTOR));
retval.tree = root_0;
// 16:15: -> ^( BAR[ $b ] )
{
// imgnodes.g:16:18: ^( BAR[ $b ] )
{
pANTLR3_BASE_TREE root_1 = (pANTLR3_BASE_TREE)(ADAPTOR->nilNode(ADAPTOR));
root_1 = (pANTLR3_BASE_TREE)(ADAPTOR->becomeRoot(ADAPTOR,
#if 1 == 2
(pANTLR3_BASE_TREE)ADAPTOR->createTypeTokenText(ADAPTOR, BAR, TOKTEXT(b))
#else
(pANTLR3_BASE_TREE)ADAPTOR->createTypeText(ADAPTOR, BAR, (pANTLR3_UINT8)b)
#endif
, root_1));
ADAPTOR->addChild(ADAPTOR, root_0, root_1);
}
}
retval.tree = root_0; // set result root
stream_retval->free(stream_retval);
}
}
}
// This is where rules clean up and exit
//
goto rulefooEx; /* Prevent compiler warnings */
rulefooEx: ;
retval.stop = LT(-1);
retval.stop = LT(-1);
retval.tree = (pANTLR3_BASE_TREE)(ADAPTOR->rulePostProcessing(ADAPTOR, root_0));
ADAPTOR->setTokenBoundaries(ADAPTOR, retval.tree, retval.start, retval.stop);
stream_5->free(stream_5);
if (HASEXCEPTION())
{
PREPORTERROR();
PRECOVER();
retval.tree = (pANTLR3_BASE_TREE)(ADAPTOR->errorNode(ADAPTOR, INPUT, retval.start, LT(-1), EXCEPTION));
}
return retval;
}
/* $ANTLR end foo */
/* End of parsing rules
* ==============================================
*/
/* ==============================================
* Syntactic predicates
*/
/* End of syntactic predicates
* ==============================================
*/
/* End of code
* =============================================================================
*/
List: http://www.antlr.org:8080/mailman/listinfo/antlr-interest
Unsubscribe:
http://www.antlr.org:8080/mailman/options/antlr-interest/your-email-address