bison-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

FYI: Exp: %output


From: Akim Demaille
Subject: FYI: Exp: %output
Date: 05 Nov 2001 10:09:11 +0100
User-agent: Gnus/5.0808 (Gnus v5.8.8) XEmacs/21.4 (Artificial Intelligence)

Here is the port of the %output patch to the trunk.  I suppose your
muscles are able to cope with this more elegantly, but it is still
unclear to me.   There is really a lot of work of clarification to
perform...

Index: ChangeLog
from  Akim Demaille  <address@hidden>

        * src/options.h (struct option_table_struct): set_flags is void*.
        * src/options.c (longopts): Support `--output' and `%output'.
        (usage): Adjust.
        * src/lex.h (tok_setopt): Remove, replaced with...
        (tok_intopt, tok_stropt): these new guys.
        * src/lex.c (getopt.h): Not needed.
        (token_buffer, unlexed_token_buffer): Not const.
        (percent_table): Promote `-' over `_' in directive names.
        Active `%name-prefix', `file-prefix', and `output'.
        (parse_percent_token): Accept possible arguments to directives.
        Promote `-' over `_' in directive names.

Index: src/getargs.c
===================================================================
RCS file: /cvsroot/bison/bison/src/getargs.c,v
retrieving revision 1.26
diff -u -u -r1.26 getargs.c
--- src/getargs.c 2001/10/04 14:55:20 1.26
+++ src/getargs.c 2001/11/05 09:07:38
@@ -89,9 +89,9 @@
   -d, --defines              also produce a header file\n\
   -v, --verbose              also produce an explanation of the automaton\n\
   -b, --file-prefix=PREFIX   specify a PREFIX for output files\n\
-  -o, --output-file=FILE     leave output to FILE\n\
-  -g, --graph                also produce a VCG graph description of the \
-automaton\n"), stream);
+  -o, --output=FILE          leave output to FILE\n\
+  -g, --graph                also produce a VCG description of the automaton\n\
+"), stream);
   putc ('\n', stream);
 
   fputs (_("\
Index: src/lex.c
===================================================================
RCS file: /cvsroot/bison/bison/src/lex.c,v
retrieving revision 1.43
diff -u -u -r1.43 lex.c
--- src/lex.c 2001/11/02 15:27:11 1.43
+++ src/lex.c 2001/11/05 09:07:38
@@ -21,7 +21,6 @@
 #include "system.h"
 #include "getargs.h"
 #include "files.h"
-#include "getopt.h"            /* for optarg */
 #include "symtab.h"
 #include "options.h"
 #include "lex.h"
@@ -31,7 +30,7 @@
 
 /* Buffer for storing the current token.  */
 static struct obstack token_obstack;
-const char *token_buffer = NULL;
+char *token_buffer = NULL;
 
 bucket *symval;
 int numval;
@@ -39,7 +38,7 @@
 /* A token to be reread, see unlex and lex. */
 static token_t unlexed = tok_undef;
 static bucket *unlexed_symval = NULL;
-static const char *unlexed_token_buffer = NULL;
+static char *unlexed_token_buffer = NULL;
 
 void
 lex_init (void)
@@ -428,7 +427,7 @@
       /* parse the literal token and compute character code in  code  */
 
       {
-       int code, discode;
+       int code;
 
        obstack_1grow (&token_obstack, '\'');
        literalchar (&token_obstack, &code, '\'');
@@ -436,6 +435,7 @@
        c = getc (finput);
        if (c != '\'')
          {
+           int discode;
            complain (_("use \"...\" for multi-character literal tokens"));
            while (1)
              if (!literalchar (0, &discode, '\''))
@@ -553,7 +553,10 @@
 token_t
 parse_percent_token (void)
 {
-  const struct option_table_struct *tx;
+  const struct option_table_struct *tx = NULL;
+  /* Where `=' was found in token_buffer. */
+  size_t equal_offset = 0;
+  char *arg = NULL;
 
   int c = getc (finput);
 
@@ -565,6 +568,8 @@
     case '{':
       return tok_percent_left_curly;
 
+      /* FIXME: Who the heck are those 5 guys!?! `%<' = `%left'!!!
+        Let's ask for there removal.  */
     case '<':
       return tok_left;
 
@@ -593,9 +598,33 @@
       c = getc (finput);
     }
 
-  ungetc (c, finput);
+  if (c == '=')
+    {
+      equal_offset = obstack_object_size (&token_obstack);
+      obstack_1grow (&token_obstack, c);
+      c = getc (finput);
+      if (c = '"')
+       {
+         int code;             /* ignored here */
+
+         obstack_1grow (&token_obstack, '"');
+         /* Read up to and including ".  */
+         while (literalchar (&token_obstack, &code, '"'))
+           /* nothing */;
+       }
+    }
+  else
+    ungetc (c, finput);
+
   obstack_1grow (&token_obstack, '\0');
   token_buffer = obstack_finish (&token_obstack);
+  if (equal_offset)
+    {
+      /* %token_buffer="arg" */
+      arg = token_buffer + equal_offset + 2;
+      arg[strlen (arg) - 1] = '\0';
+      token_buffer[equal_offset] = '\0';
+    }
 
   /* table lookup % directive */
   for (tx = option_table; tx->name; tx++)
@@ -603,27 +632,42 @@
        && option_strcmp (token_buffer + 1, tx->name) == 0)
       break;
 
-  if (tx->set_flag)
-    {
-      *((int *) (tx->set_flag)) = 1;
-      return tok_noop;
-    }
+  if (arg && !tx->ret_val == tok_stropt)
+    fatal (_("`%s' supports no argument: %s"), token_buffer, quotearg (arg));
+
 
   switch (tx->ret_val)
     {
-    case tok_setopt:
-      *((char **) (tx->set_flag)) = optarg;
+    case tok_stropt:
+      assert (tx->set_flag);
+      if (arg)
+       {
+         /* Keep only the first assignment: command line options have
+            already been processed, and we want them to have
+            precedence.  Side effect: if this %-option is used
+            several times, only the first is honored.  Bah.  */
+         if (!*((char **) (tx->set_flag)))
+           *((char **) (tx->set_flag)) = arg;
+       }
+      else
+       fatal (_("`%s' requires an argument"), token_buffer);
       return tok_noop;
       break;
 
+    case tok_intopt:
+      assert (tx->set_flag);
+      *((int *) (tx->set_flag)) = 1;
+      return tok_noop;
+      break;
+
     case tok_obsolete:
       fatal (_("`%s' is no longer supported"), token_buffer);
+      return tok_noop;
       break;
 
     default:
-      /* Other cases do not apply here. */
+      return tx->ret_val;
       break;
     }
-
-  return tx->ret_val;
+  abort ();
 }
Index: src/lex.h
===================================================================
RCS file: /cvsroot/bison/bison/src/lex.h,v
retrieving revision 1.18
diff -u -u -r1.18 lex.h
--- src/lex.h 2001/10/04 14:55:20 1.18
+++ src/lex.h 2001/11/05 09:07:38
@@ -51,12 +51,13 @@
     tok_define,
     tok_skel,
     tok_noop,
-    tok_setopt,
+    tok_intopt,
+    tok_stropt,
     tok_illegal,
     tok_obsolete
   } token_t;
 
-extern const char *token_buffer;
+extern char *token_buffer;
 extern bucket *symval;
 extern int numval;
 
Index: src/options.c
===================================================================
RCS file: /cvsroot/bison/bison/src/options.c,v
retrieving revision 1.5
diff -u -u -r1.5 options.c
--- src/options.c 2001/10/15 19:01:12 1.5
+++ src/options.c 2001/11/05 09:07:38
@@ -22,6 +22,7 @@
 #include "xalloc.h"
 #include "system.h"
 #include "getopt.h"
+#include "files.h"
 #include "getargs.h"
 #include "gram.h"
 #include "symtab.h"
@@ -52,10 +53,13 @@
 
   /* Output. */
   {opt_cmd_line, "file-prefix",        required_argument,         0,         
0,   'b'},
+  {opt_cmd_line, "output",     required_argument,         0,         0,   'o'},
   {opt_cmd_line, "output-file",        required_argument,         0,         
0,   'o'},
   {opt_cmd_line, "graph",      optional_argument,         0,         0,   'g'},
 
   /* Hidden. */
+  /* Fixme: What is this `1' doing here!!!  Sounds dead wrong.  See
+     locations too below.  */
   {opt_cmd_line, "statistics", no_argument, &statistics_flag,        0,     1},
 
   /*
@@ -76,19 +80,18 @@
   {opt_percent, "nonassoc",            0,              NULL, tok_nonassoc,  0},
   {opt_percent, "binary",              0,              NULL, tok_nonassoc,  0},
   {opt_percent, "prec",                        0,              NULL, tok_prec, 
     0},
-#if 0
-  /* For the time being, this is not enabled yet, while it's possible
-     though, since we use obstacks.  The only risk is with semantic
-     parsers which will output an `include' of an output file: be sure
-     that the naem included is indeed the name of the output file.  */
-  /* FIXME Should we activate this options ?  */
-  {opt_both, "output-file", required_argument, &spec_outfile, tok_setopt,  
'o'},
-  {opt_both, "file-prefix", 
required_argument,&spec_file_prefix,tok_setopt,'b'},
-  {opt_both, "name-prefix", 
required_argument,&spec_name_prefix,tok_setopt,'p'},
-#endif
+
+  /* FIXME: semantic parsers will output an `include' of an
+     output file: be sure that the naem included is indeed the name of
+     the output file.  */ /* FIXME Should we activate this options ?
+     */
+  {opt_both, "output",             required_argument, &spec_outfile, 
tok_stropt,  'o'},
+  {opt_both, "file-prefix", 
required_argument,&spec_file_prefix,tok_stropt,'b'},
+  {opt_both, "name-prefix", 
required_argument,&spec_name_prefix,tok_stropt,'p'},
+
   {opt_percent, "define",              0,              NULL, tok_define,    0},
-  {opt_percent, "semantic-parser",     0,  &semantic_parser, tok_noop,      0},
-  {opt_percent, "pure-parser",         0,      &pure_parser, tok_noop,      0},
+  {opt_percent, "semantic-parser",     0,  &semantic_parser, tok_intopt,       
     0},
+  {opt_percent, "pure-parser",         0,      &pure_parser, tok_intopt,      
0},
 
   /*
    * Percent and command line declarations.
@@ -99,21 +102,21 @@
      the same, the char `-'.  */
 
   /* Output.  */
-  {opt_both, "defines",               optional_argument,   &defines_flag, 
tok_noop,       'd'},
-  {opt_both, "verbose",               no_argument,   &verbose_flag, tok_noop,  
   'v'},
+  {opt_both, "defines",         optional_argument,   &defines_flag, 
tok_intopt,   'd'},
+  {opt_both, "verbose",               no_argument,   &verbose_flag, 
tok_intopt,   'v'},
 
   /* Operation modes.  */
-  {opt_both, "fixed-output-files", no_argument,  &yacc_flag, tok_noop,    'y'},
-  {opt_both, "yacc",          no_argument,      &yacc_flag, tok_noop,     'y'},
+  {opt_both, "fixed-output-files", no_argument,  &yacc_flag, tok_intopt,   
'y'},
+  {opt_both, "yacc",          no_argument,      &yacc_flag, tok_intopt,   'y'},
 
   /* Parser.  */
-  {opt_both, "debug",         no_argument,     &debug_flag, tok_noop,     't'},
-  {opt_both, "locations",      no_argument, &locations_flag, tok_noop,       
1},
-  {opt_both, "no-lines",       no_argument,  &no_lines_flag, tok_noop,    'l'},
-  {opt_both, "no-parser",      no_argument, &no_parser_flag, tok_noop,    'n'},
+  {opt_both, "debug",         no_argument,     &debug_flag, tok_intopt,        
   't'},
+  {opt_both, "locations",      no_argument, &locations_flag, tok_intopt,       
1},
+  {opt_both, "no-lines",       no_argument,  &no_lines_flag, tok_intopt,       
   'l'},
+  {opt_both, "no-parser",      no_argument, &no_parser_flag, tok_intopt,       
   'n'},
   {opt_both, "raw",           no_argument,               0, tok_obsolete, 'r'},
   {opt_both, "skeleton",       required_argument,         0, tok_skel,    'S'},
-  {opt_both, "token-table",    no_argument, &token_table_flag, tok_noop,   
'k'},
+  {opt_both, "token-table",    no_argument, &token_table_flag, tok_intopt,   
'k'},
 
   {0, 0, 0, 0, 0, 0}
 };
@@ -143,7 +146,7 @@
        longopts[j].name = option_table[i].name;
        longopts[j].has_arg = option_table[i].has_arg;
        /* When an options is declared having 'optional_argument' and
-          a flag is specified to be set, the option is skipped on 
+          a flag is specified to be set, the option is skipped on
           command line. So we never use a flag when a command line
           option is declared 'optional_argument.  */
        if (longopts[j].has_arg == optional_argument)
Index: src/options.h
===================================================================
RCS file: /cvsroot/bison/bison/src/options.h,v
retrieving revision 1.1
diff -u -u -r1.1 options.h
--- src/options.h 2001/09/20 18:32:20 1.1
+++ src/options.h 2001/11/05 09:07:38
@@ -21,7 +21,7 @@
 #ifndef OPTIONS_H_
 # define OPTIONS_H_
 
-/* opt_access_t and struct option_table_struct need to be declare 
+/* opt_access_t and struct option_table_struct need to be declare
    here, for the parse_percent_token function in lex.c.  */
 
 /* Option accessibility.  */
@@ -43,7 +43,7 @@
   /* Use for command line.  */
   int has_arg;
   /* A set_flag value causes the named flag to be set.  */
-  int *set_flag;
+  void *set_flag;
   /* A retval action returns the code.  */
   int ret_val;
   /* The short option value, frequently a letter.  */
Index: src/reader.c
===================================================================
RCS file: /cvsroot/bison/bison/src/reader.c,v
retrieving revision 1.93
diff -u -u -r1.93 reader.c
--- src/reader.c 2001/11/02 15:27:11 1.93
+++ src/reader.c 2001/11/05 09:07:38
@@ -962,16 +962,13 @@
 static void
 read_declarations (void)
 {
-  int c;
-  int tok;
-
   for (;;)
     {
-      c = skip_white_space ();
+      int c = skip_white_space ();
 
       if (c == '%')
        {
-         tok = parse_percent_token ();
+         token_t tok = parse_percent_token ();
 
          switch (tok)
            {
@@ -1031,6 +1028,13 @@
              break;
 
            case tok_noop:
+             break;
+
+           case tok_stropt:
+           case tok_intopt:
+           case tok_obsolete:
+           case tok_illegal:
+             abort ();
              break;
 
            default:
Index: tests/output.at
===================================================================
RCS file: /cvsroot/bison/bison/tests/output.at,v
retrieving revision 1.2
diff -u -u -r1.2 output.at
--- tests/output.at 2001/10/04 14:55:21 1.2
+++ tests/output.at 2001/11/05 09:07:38
@@ -53,6 +53,16 @@
 AT_CHECK_OUTPUT([foo.y], [%defines %verbose %yacc],[],
                 [y.output y.tab.c y.tab.h])
 
+# Exercise %output and %file-prefix
+AT_CHECK_OUTPUT([foo.y], [%file-prefix="bar" %defines %verbose],      [],
+                [bar.output bar.tab.c bar.tab.h])
+AT_CHECK_OUTPUT([foo.y], [%output="bar.c" %defines %verbose %yacc],[],
+                [bar.output bar.c bar.h])
+AT_CHECK_OUTPUT([foo.y],
+                [%file-prefix="baz" %output="bar.c" %defines %verbose %yacc],
+                [],
+                [bar.output bar.c bar.h])
+
 
 # Check priorities of extension control.
 AT_CHECK_OUTPUT([foo.yy], [%defines %verbose], [],



reply via email to

[Prev in Thread] Current Thread [Next in Thread]