On Mon, Jan 7, 2013 at 4:18 PM, Tiago Rodrigues <wtrm...@gmail.com> wrote:

> Oops, Dominique alerted me to the fact that the patch I included was
> stripped by the listserver...  I'm including it inline, then.
>


This patch does not work in the general case.  I don't doubt that it works
for your use case, but in general it does not.  The reason:  The function
prototypes depend on the "lempar.c" template file.  Some applications (ex:
SQLite) change the lempar.c parser template in ways that could change the
function signatures.  (The function signatures for SQLite are unchanged,
but that doesn't exclude the possibility that they might in the future.)

For this to really work in general, I suppose you would have to somehow
extract the function signatures from the lempar.c template file.  Or maybe
have a separate lempar.h template that contains the header.  Or something.



>
> (Begin patch)
>
> --- lemon.c    2013-01-04 20:39:20 +0000
> +++ lemon-new.c    2013-01-04 23:09:59 +0000
> @@ -109,7 +109,7 @@
>  void Reprint(struct lemon *);
>  void ReportOutput(struct lemon *);
>  void ReportTable(struct lemon *, int);
> -void ReportHeader(struct lemon *);
> +void ReportHeader(struct lemon *, int);
>  void CompressTables(struct lemon *);
>  void ResortStates(struct lemon *);
>
> @@ -1393,11 +1393,13 @@
>    static int mhflag = 0;
>    static int nolinenosflag = 0;
>    static int noResort = 0;
> +  static int fpflag = 0;
>    static struct s_options options[] = {
>      {OPT_FLAG, "b", (char*)&basisflag, "Print only the basis in report."},
>      {OPT_FLAG, "c", (char*)&compress, "Don't compress the action table."},
>      {OPT_FSTR, "D", (char*)handle_D_option, "Define an %ifdef macro."},
>      {OPT_FSTR, "T", (char*)handle_T_option, "Specify a template file."},
> +    {OPT_FLAG, "f", (char*)&fpflag, "Generate function prototypes in
> header."},
>      {OPT_FLAG, "g", (char*)&rpflag, "Print grammar without actions."},
>      {OPT_FLAG, "m", (char*)&mhflag, "Output a makeheaders compatible
> file."},
>      {OPT_FLAG, "l", (char*)&nolinenosflag, "Do not print #line
> statements."},
> @@ -1502,7 +1504,7 @@
>      /* Produce a header file for use by the scanner.  (This step is
>      ** omitted if the "-m" option is used because makeheaders will
>      ** generate the file for us.) */
> -    if( !mhflag ) ReportHeader(&lem);
> +    if( !mhflag ) ReportHeader(&lem, fpflag);
>    }
>    if( statistics ){
>      printf("Parser statistics: %d terminals, %d nonterminals, %d rules\n",
> @@ -4009,16 +4011,20 @@
>  }
>
>  /* Generate a header file for the parser */
> -void ReportHeader(struct lemon *lemp)
> +void ReportHeader(struct lemon *lemp, int fpflag)
>  {
>    FILE *out, *in;
> +  const char *name;
>    const char *prefix;
>    char line[LINESIZE];
>    char pattern[LINESIZE];
>    int i;
> +  int protok = 1;
>
>    if( lemp->tokenprefix ) prefix = lemp->tokenprefix;
>    else                    prefix = "";
> +  if( lemp->name ) name = lemp->name;
> +  else             name = "Parse";
>    in = file_open(lemp,".h","rb");
>    if( in ){
>      int nextChar;
> @@ -4026,9 +4032,24 @@
>        sprintf(pattern,"#define %s%-30s
> %2d\n",prefix,lemp->symbols[i]->name,i);
>        if( strcmp(line,pattern) ) break;
>      }
> +    if( fpflag ){
> +        sprintf(pattern,"void *%sAlloc(void *(*)(size_t));\n",name);
> +        if( !fgets(line,LINESIZE,in) || strcmp(line,pattern) ){ protok =
> 0; goto after; }
> +
> +        if( lemp->arg ){
> +            sprintf(pattern,"void %s(void
> *,int,%s,%s);\n",name,lemp->tokentype,lemp->arg);
> +        }else{
> +            sprintf(pattern,"void %s(void
> *,int,%s);\n",name,lemp->tokentype);
> +        }
> +        if( !fgets(line,LINESIZE,in) || strcmp(line,pattern) ){ protok =
> 0; goto after; }
> +
> +        sprintf(pattern,"void *%sFree(void *,void (*)(void *));\n",name);
> +        if( !fgets(line,LINESIZE,in) || strcmp(line,pattern) ){ protok =
> 0; goto after; }
> +    }
> +after:
>      nextChar = fgetc(in);
>      fclose(in);
> -    if( i==lemp->nterminal && nextChar==EOF ){
> +    if( i==lemp->nterminal && protok && nextChar==EOF ){
>        /* No change in the file.  Don't rewrite it. */
>        return;
>      }
> @@ -4038,6 +4059,16 @@
>      for(i=1; i<lemp->nterminal; i++){
>        fprintf(out,"#define %s%-30s
> %2d\n",prefix,lemp->symbols[i]->name,i);
>      }
> +    if( fpflag ){
> +        /* emit function prototypes */
> +        fprintf(out,"void *%sAlloc(void *(*)(size_t));\n",name);
> +        if( lemp->arg ){
> +            fprintf(out,"void %s(void
> *,int,%s,%s);\n",name,lemp->tokentype,lemp->arg);
> +        }else{
> +            fprintf(out,"void %s(void *,int,%s);\n",name,lemp->tokentype);
> +        }
> +        fprintf(out,"void *%sFree(void *,void (*)(void *));\n",name);
> +    }
>      fclose(out);
>    }
>    return;
>
> (End patch)
>
> Thanks,
>
>           -Tiago
>
>
> On Mon, Jan 7, 2013 at 6:15 AM, Dominique Devienne <ddevie...@gmail.com
> >wrote:
>
> > On Sat, Jan 5, 2013 at 6:22 PM, Tiago Rodrigues <wtrm...@gmail.com>
> wrote:
> > > [...]
> > > This patch works against the current version of lemon.c, as linked to
> by
> > > the Lemon page.  This is probably not correct, as the file is
> amalgamated
> > > from other sources, but still might be useful to somebody.
> >
> > Hi Tiago. Looks like the patch was stripped by the mailing list.
> > Perhaps you should include it inline to your message. Thanks, --DD
> >
>
>
>
> --
> In those days, in those distant days, in those nights, in those remote
> nights, in those years, in those distant years...
>           - Gilgamesh, Enkidu and the Underworld
> _______________________________________________
> sqlite-users mailing list
> sqlite-users@sqlite.org
> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
>



-- 
D. Richard Hipp
d...@sqlite.org
_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to