I see; well, that's unfortunate.  At any rate, parsing lempar.c will
probably be much more complex than the code I have now, which solves a
simple (but common) case.  Maybe I'll look into parsing lempar.c, but since
this solves my use case, I probably won't be in a hurry to do it.  I
apologise to everyone this doesn't help, then.

Cheers,

          -Tiago


On Mon, Jan 7, 2013 at 9:13 PM, Richard Hipp <[email protected]> wrote:

> On Mon, Jan 7, 2013 at 4:18 PM, Tiago Rodrigues <[email protected]> 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 <[email protected]
> > >wrote:
> >
> > > On Sat, Jan 5, 2013 at 6:22 PM, Tiago Rodrigues <[email protected]>
> > 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
> > [email protected]
> > http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
> >
>
>
>
> --
> D. Richard Hipp
> [email protected]
> _______________________________________________
> sqlite-users mailing list
> [email protected]
> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
>



-- 
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
[email protected]
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to