* 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.
This commit is contained in:
Akim Demaille
2001-11-05 09:09:19 +00:00
parent 9f4503d6e9
commit 951366c145
8 changed files with 126 additions and 50 deletions

View File

@@ -1,3 +1,17 @@
2001-11-05 Akim Demaille <akim@epita.fr>
* 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.
2001-11-04 Akim Demaille <akim@epita.fr> 2001-11-04 Akim Demaille <akim@epita.fr>
* doc/bison.texinfo (Decl Summary): Split the list into * doc/bison.texinfo (Decl Summary): Split the list into

View File

@@ -89,9 +89,9 @@ Output:\n\
-d, --defines also produce a header file\n\ -d, --defines also produce a header file\n\
-v, --verbose also produce an explanation of the automaton\n\ -v, --verbose also produce an explanation of the automaton\n\
-b, --file-prefix=PREFIX specify a PREFIX for output files\n\ -b, --file-prefix=PREFIX specify a PREFIX for output files\n\
-o, --output-file=FILE leave output to FILE\n\ -o, --output=FILE leave output to FILE\n\
-g, --graph also produce a VCG graph description of the \ -g, --graph also produce a VCG description of the automaton\n\
automaton\n"), stream); "), stream);
putc ('\n', stream); putc ('\n', stream);
fputs (_("\ fputs (_("\

View File

@@ -21,7 +21,6 @@
#include "system.h" #include "system.h"
#include "getargs.h" #include "getargs.h"
#include "files.h" #include "files.h"
#include "getopt.h" /* for optarg */
#include "symtab.h" #include "symtab.h"
#include "options.h" #include "options.h"
#include "lex.h" #include "lex.h"
@@ -31,7 +30,7 @@
/* Buffer for storing the current token. */ /* Buffer for storing the current token. */
static struct obstack token_obstack; static struct obstack token_obstack;
const char *token_buffer = NULL; char *token_buffer = NULL;
bucket *symval; bucket *symval;
int numval; int numval;
@@ -39,7 +38,7 @@ int numval;
/* A token to be reread, see unlex and lex. */ /* A token to be reread, see unlex and lex. */
static token_t unlexed = tok_undef; static token_t unlexed = tok_undef;
static bucket *unlexed_symval = NULL; static bucket *unlexed_symval = NULL;
static const char *unlexed_token_buffer = NULL; static char *unlexed_token_buffer = NULL;
void void
lex_init (void) lex_init (void)
@@ -428,7 +427,7 @@ lex (void)
/* parse the literal token and compute character code in code */ /* parse the literal token and compute character code in code */
{ {
int code, discode; int code;
obstack_1grow (&token_obstack, '\''); obstack_1grow (&token_obstack, '\'');
literalchar (&token_obstack, &code, '\''); literalchar (&token_obstack, &code, '\'');
@@ -436,6 +435,7 @@ lex (void)
c = getc (finput); c = getc (finput);
if (c != '\'') if (c != '\'')
{ {
int discode;
complain (_("use \"...\" for multi-character literal tokens")); complain (_("use \"...\" for multi-character literal tokens"));
while (1) while (1)
if (!literalchar (0, &discode, '\'')) if (!literalchar (0, &discode, '\''))
@@ -553,7 +553,10 @@ option_strcmp (const char *left, const char *right)
token_t token_t
parse_percent_token (void) 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); int c = getc (finput);
@@ -565,6 +568,8 @@ parse_percent_token (void)
case '{': case '{':
return tok_percent_left_curly; return tok_percent_left_curly;
/* FIXME: Who the heck are those 5 guys!?! `%<' = `%left'!!!
Let's ask for there removal. */
case '<': case '<':
return tok_left; return tok_left;
@@ -593,9 +598,33 @@ parse_percent_token (void)
c = getc (finput); 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'); obstack_1grow (&token_obstack, '\0');
token_buffer = obstack_finish (&token_obstack); 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 */ /* table lookup % directive */
for (tx = option_table; tx->name; tx++) for (tx = option_table; tx->name; tx++)
@@ -603,27 +632,42 @@ parse_percent_token (void)
&& option_strcmp (token_buffer + 1, tx->name) == 0) && option_strcmp (token_buffer + 1, tx->name) == 0)
break; break;
if (tx->set_flag) if (arg && !tx->ret_val == tok_stropt)
{ fatal (_("`%s' supports no argument: %s"), token_buffer, quotearg (arg));
*((int *) (tx->set_flag)) = 1;
return tok_noop;
}
switch (tx->ret_val) switch (tx->ret_val)
{ {
case tok_setopt: case tok_stropt:
*((char **) (tx->set_flag)) = optarg; 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; return tok_noop;
break; break;
case tok_obsolete: case tok_obsolete:
fatal (_("`%s' is no longer supported"), token_buffer); fatal (_("`%s' is no longer supported"), token_buffer);
return tok_noop;
break; break;
default: default:
/* Other cases do not apply here. */ return tx->ret_val;
break; break;
} }
abort ();
return tx->ret_val;
} }

View File

@@ -51,12 +51,13 @@ typedef enum token_e
tok_define, tok_define,
tok_skel, tok_skel,
tok_noop, tok_noop,
tok_setopt, tok_intopt,
tok_stropt,
tok_illegal, tok_illegal,
tok_obsolete tok_obsolete
} token_t; } token_t;
extern const char *token_buffer; extern char *token_buffer;
extern bucket *symval; extern bucket *symval;
extern int numval; extern int numval;

View File

@@ -22,6 +22,7 @@
#include "xalloc.h" #include "xalloc.h"
#include "system.h" #include "system.h"
#include "getopt.h" #include "getopt.h"
#include "files.h"
#include "getargs.h" #include "getargs.h"
#include "gram.h" #include "gram.h"
#include "symtab.h" #include "symtab.h"
@@ -52,10 +53,13 @@ const struct option_table_struct option_table[] =
/* Output. */ /* Output. */
{opt_cmd_line, "file-prefix", required_argument, 0, 0, 'b'}, {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, "output-file", required_argument, 0, 0, 'o'},
{opt_cmd_line, "graph", optional_argument, 0, 0, 'g'}, {opt_cmd_line, "graph", optional_argument, 0, 0, 'g'},
/* Hidden. */ /* 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}, {opt_cmd_line, "statistics", no_argument, &statistics_flag, 0, 1},
/* /*
@@ -76,19 +80,18 @@ const struct option_table_struct option_table[] =
{opt_percent, "nonassoc", 0, NULL, tok_nonassoc, 0}, {opt_percent, "nonassoc", 0, NULL, tok_nonassoc, 0},
{opt_percent, "binary", 0, NULL, tok_nonassoc, 0}, {opt_percent, "binary", 0, NULL, tok_nonassoc, 0},
{opt_percent, "prec", 0, NULL, tok_prec, 0}, {opt_percent, "prec", 0, NULL, tok_prec, 0},
#if 0
/* For the time being, this is not enabled yet, while it's possible /* FIXME: semantic parsers will output an `include' of an
though, since we use obstacks. The only risk is with semantic output file: be sure that the naem included is indeed the name of
parsers which will output an `include' of an output file: be sure the output file. */ /* FIXME Should we activate this options ?
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, "output-file", required_argument, &spec_outfile, tok_setopt, 'o'}, {opt_both, "file-prefix", required_argument,&spec_file_prefix,tok_stropt,'b'},
{opt_both, "file-prefix", required_argument,&spec_file_prefix,tok_setopt,'b'}, {opt_both, "name-prefix", required_argument,&spec_name_prefix,tok_stropt,'p'},
{opt_both, "name-prefix", required_argument,&spec_name_prefix,tok_setopt,'p'},
#endif
{opt_percent, "define", 0, NULL, tok_define, 0}, {opt_percent, "define", 0, NULL, tok_define, 0},
{opt_percent, "semantic-parser", 0, &semantic_parser, tok_noop, 0}, {opt_percent, "semantic-parser", 0, &semantic_parser, tok_intopt, 0},
{opt_percent, "pure-parser", 0, &pure_parser, tok_noop, 0}, {opt_percent, "pure-parser", 0, &pure_parser, tok_intopt, 0},
/* /*
* Percent and command line declarations. * Percent and command line declarations.
@@ -99,21 +102,21 @@ const struct option_table_struct option_table[] =
the same, the char `-'. */ the same, the char `-'. */
/* Output. */ /* Output. */
{opt_both, "defines", optional_argument, &defines_flag, tok_noop, 'd'}, {opt_both, "defines", optional_argument, &defines_flag, tok_intopt, 'd'},
{opt_both, "verbose", no_argument, &verbose_flag, tok_noop, 'v'}, {opt_both, "verbose", no_argument, &verbose_flag, tok_intopt, 'v'},
/* Operation modes. */ /* Operation modes. */
{opt_both, "fixed-output-files", 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_noop, 'y'}, {opt_both, "yacc", no_argument, &yacc_flag, tok_intopt, 'y'},
/* Parser. */ /* Parser. */
{opt_both, "debug", no_argument, &debug_flag, tok_noop, 't'}, {opt_both, "debug", no_argument, &debug_flag, tok_intopt, 't'},
{opt_both, "locations", no_argument, &locations_flag, tok_noop, 1}, {opt_both, "locations", no_argument, &locations_flag, tok_intopt, 1},
{opt_both, "no-lines", no_argument, &no_lines_flag, tok_noop, 'l'}, {opt_both, "no-lines", no_argument, &no_lines_flag, tok_intopt, 'l'},
{opt_both, "no-parser", no_argument, &no_parser_flag, tok_noop, 'n'}, {opt_both, "no-parser", no_argument, &no_parser_flag, tok_intopt, 'n'},
{opt_both, "raw", no_argument, 0, tok_obsolete, 'r'}, {opt_both, "raw", no_argument, 0, tok_obsolete, 'r'},
{opt_both, "skeleton", required_argument, 0, tok_skel, 'S'}, {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} {0, 0, 0, 0, 0, 0}
}; };
@@ -143,7 +146,7 @@ create_long_option_table ()
longopts[j].name = option_table[i].name; longopts[j].name = option_table[i].name;
longopts[j].has_arg = option_table[i].has_arg; longopts[j].has_arg = option_table[i].has_arg;
/* When an options is declared having 'optional_argument' and /* 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 command line. So we never use a flag when a command line
option is declared 'optional_argument. */ option is declared 'optional_argument. */
if (longopts[j].has_arg == optional_argument) if (longopts[j].has_arg == optional_argument)

View File

@@ -21,7 +21,7 @@
#ifndef OPTIONS_H_ #ifndef OPTIONS_H_
# define 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. */ here, for the parse_percent_token function in lex.c. */
/* Option accessibility. */ /* Option accessibility. */
@@ -43,7 +43,7 @@ struct option_table_struct
/* Use for command line. */ /* Use for command line. */
int has_arg; int has_arg;
/* A set_flag value causes the named flag to be set. */ /* A set_flag value causes the named flag to be set. */
int *set_flag; void *set_flag;
/* A retval action returns the code. */ /* A retval action returns the code. */
int ret_val; int ret_val;
/* The short option value, frequently a letter. */ /* The short option value, frequently a letter. */

View File

@@ -962,16 +962,13 @@ parse_skel_decl (void)
static void static void
read_declarations (void) read_declarations (void)
{ {
int c;
int tok;
for (;;) for (;;)
{ {
c = skip_white_space (); int c = skip_white_space ();
if (c == '%') if (c == '%')
{ {
tok = parse_percent_token (); token_t tok = parse_percent_token ();
switch (tok) switch (tok)
{ {
@@ -1033,6 +1030,13 @@ read_declarations (void)
case tok_noop: case tok_noop:
break; break;
case tok_stropt:
case tok_intopt:
case tok_obsolete:
case tok_illegal:
abort ();
break;
default: default:
complain (_("unrecognized: %s"), token_buffer); complain (_("unrecognized: %s"), token_buffer);
skip_to_char ('%'); skip_to_char ('%');

View File

@@ -53,6 +53,16 @@ AT_CHECK_OUTPUT([foo.y], [%defines %verbose], [],
AT_CHECK_OUTPUT([foo.y], [%defines %verbose %yacc],[], AT_CHECK_OUTPUT([foo.y], [%defines %verbose %yacc],[],
[y.output y.tab.c y.tab.h]) [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. # Check priorities of extension control.
AT_CHECK_OUTPUT([foo.yy], [%defines %verbose], [], AT_CHECK_OUTPUT([foo.yy], [%defines %verbose], [],