Hi Richard, As promised, the second followup. The main issue that I've tried to solve was the use of global function names. Even if I use the `%name` directive to mangle them, there is still the potential of accidentally stepping on the names from other parser, which means that we need to have `some_long_maybe_unique_` prefix. Beyond that, these Lemon routines should never be touched directly by a user once embedded in one or more libraries (in this case paranoid, not pedantic). I also really wanted to avoid exposing more of the Lemon interface than necessary, for fear of entering one of those header interdependencies like flex/bison/flex etc. In the C++ world, these problems are usually solved with namespaces. If we solve the problem confined to a C domain (notwithstanding the `-e` option), we arrive at a simple solution that works equally well for me and should be good for you in terms of cost/benefit, and benefit others wanting to wrap lemon parsers into large libraries. If we drop all of my fancy handling of begin/end namespace with anonymous or nesting and simply allow specification of the linkage type, the patched version of `lempar.c` becomes quite small. ``` --- lempar.c.orig 2020-07-07 15:27:12.506352634 +0200 +++ lempar.c 2020-07-07 15:37:58.957932854 +0200 @@ -88,6 +88,10 @@ #ifndef INTERFACE # define INTERFACE 1 #endif +/* Default is global linkage. Alternative is 'static' */ +#ifndef LEMON_LINKAGE +# define LEMON_LINKAGE +#endif /************* Begin control #defines *****************************************/ %% /************* End control #defines *******************************************/ @@ -251,6 +255,7 @@ ** Outputs: ** None. */ +LEMON_LINKAGE void ParseTrace(FILE *TraceFILE, char *zTracePrompt){ yyTraceFILE = TraceFILE; yyTracePrompt = zTracePrompt; @@ -320,6 +325,7 @@ /* Initialize a new parser that has already been allocated. */ +LEMON_LINKAGE void ParseInit(void *yypRawParser ParseCTX_PDECL){ yyParser *yypParser = (yyParser*)yypRawParser; ParseCTX_STORE @@ -359,6 +365,7 @@ ** A pointer to a parser. This pointer is used in subsequent calls ** to Parse and ParseFree. */ +LEMON_LINKAGE void *ParseAlloc(void *(*mallocProc)(YYMALLOCARGTYPE) ParseCTX_PDECL){ yyParser *yypParser; yypParser = (yyParser*)(*mallocProc)( (YYMALLOCARGTYPE)sizeof(yyParser) ); @@ -427,6 +434,7 @@ /* ** Clear all secondary memory allocations from the parser */ +LEMON_LINKAGE void ParseFinalize(void *p){ yyParser *pParser = (yyParser*)p; while( pParser->yytos>pParser->yystack ) yy_pop_parser_stack(pParser); @@ -444,6 +452,7 @@ ** is defined in a %include section of the input grammar) then it is ** assumed that the input pointer is never NULL. */ +LEMON_LINKAGE void ParseFree( void *p, /* The parser to be deleted */ void (*freeProc)(void*) /* Function used to reclaim memory */ @@ -460,6 +469,7 @@ ** Return the peak depth of the stack for a parser. */ #ifdef YYTRACKMAXSTACKDEPTH +LEMON_LINKAGE int ParseStackPeak(void *p){ yyParser *pParser = (yyParser*)p; return pParser->yyhwm; @@ -484,6 +494,7 @@ ** Return the number of missed state/lookahead combinations. */ #if defined(YYCOVERAGE) +LEMON_LINKAGE int ParseCoverage(FILE *out){ int stateno, iLookAhead, i; int nMissed = 0; @@ -891,6 +902,7 @@ ** Outputs: ** None. */ +LEMON_LINKAGE void Parse( void *yyp, /* The parser */ int yymajor, /* The major token code number */ @@ -1065,6 +1077,7 @@ ** Return the fallback token corresponding to canonical token iToken, or ** 0 if iToken has no fallback. */ +LEMON_LINKAGE int ParseFallback(int iToken){ #ifdef YYFALLBACK assert( iToken<(int)(sizeof(yyFallback)/sizeof(yyFallback[0])) ); ``` If this seems reasonable, then the only nice thing to change afterwards could be a Lemon directive (eg, `%static`?) to emit `#define LEMON_LINKAGE static` from `lemon.c` to restrict the type of things that people could write and reduce the number of pre-processor macros to document or remember. For the C++ people, I think this is also a pretty good solution. In the end, I have only ever used an anonymous namespace for localising the lemon functions and that is very much what this is. _Except_ that it works for C++ **and** C and it doesn't carve as deeply into lemon (even with an additional directive).