flex & bison: parse command line arguments? - Unix
This is a discussion on flex & bison: parse command line arguments? - Unix ; Is it possible to parse command line arguments with the help of flex and
bison? If so, how is it done? I suspect that it may be simply a matter of
tweaking flex into processing arrays of null-terminated strings instead
...
-
flex & bison: parse command line arguments?
Is it possible to parse command line arguments with the help of flex and
bison? If so, how is it done? I suspect that it may be simply a matter of
tweaking flex into processing arrays of null-terminated strings instead
of stdin but I can't find a single reference.
So, can anyone help?
Thanks in advance,
Rui Maciel
-
Re: flex & bison: parse command line arguments?
On Aug 26, 1:14 pm, Rui Maciel wrote:
> Is it possible to parse command line arguments with the help of flex and
> bison? If so, how is it done? I suspect that it may be simply a matter of
> tweaking flex into processing arrays of null-terminated strings instead
> of stdin but I can't find a single reference.
Define an appropriate YY_INPUT macro for flex. Yours will probably be
based on strcpy(). Note that since flex expects its input in a single
stream, you'll have to concatenate the arguments together, and invent
some way of marking the boundaries between arguments.
-
Re: flex & bison: parse command line arguments?
On Tue, 26 Aug 2008 17:26:47 -0700, fjblurt wrote:
> Define an appropriate YY_INPUT macro for flex. Yours will probably be
> based on strcpy(). Note that since flex expects its input in a single
> stream, you'll have to concatenate the arguments together, and invent
> some way of marking the boundaries between arguments.
Isn't it possible to simply redirect the buffer from a stream to a bunch
of null-terminated strings? The manual mentions a yy_scan_string()
routine which may be exactly what I'm looking for. Unfortunately I can't
find a single example that uses it.
So, can anyone help?
Rui Maciel
-
Re: flex & bison: parse command line arguments?
On Wed, 27 Aug 2008 17:07:41 +0000, Rui Maciel wrote:
> Isn't it possible to simply redirect the buffer from a stream to a bunch
> of null-terminated strings? The manual mentions a yy_scan_string()
> routine which may be exactly what I'm looking for. Unfortunately I can't
> find a single example that uses it.
I've manage to put together some flex code that manages to parse the char
**argv tokens. It's a bit shoddy and it has a memory leak somewhere. Any
fixes, suggestions or tips are more than welcomed.
The code is as follows:
---scanner.l---
%option nounput
%{
#include
#include
void yyerror(const char *);
int yywrap(void);
void print_help_message(void);
int current_arg = 1;
int max_arg;
char ***arguments;
%}
%%
-h |
"--help" {print_help_message();}
-v |
"--version" {printf("test version 0.0\n");}
.. {yyerror("invalid argument");}
%%
void yyerror(const char *message)
{
printf("error: %s\n", message);
}
int yywrap(void)
{
yy_delete_buffer( YY_CURRENT_BUFFER );
if(current_arg < max_arg)
{
current_arg++;
yy_scan_string((*arguments)[current_arg]);
return 0;
}
else
{
return 1;
}
}
void print_help_message(void)
{
printf("usage: program \n");
}
void process_arguments(int argc, char ***argv)
{
max_arg = argc-1;
arguments = argv;
if(argc == 1)
{
print_help_message();
}
else
{
yy_delete_buffer( YY_CURRENT_BUFFER );
yy_scan_string((*arguments)[1]);
yylex();
}
}
int main(int argc, char **argv)
{
process_arguments(argc, &argv);
return 0;
}
-
Re: flex & bison: parse command line arguments?
It *is* possible, but there is no point in doing it.
Have you considered using getopt_long or getopt ?
They were both created specifically to do that.
B§elow is a code of mine that uses getopt_long, it should be quite
obvious how it works.
static void
magt_config_parse_command_line_args(MagtConfig *mconfig, int argc,
char **argv)
{
extern char *optarg;
extern int optind;
extern int optopt;
extern int opterr;
extern int optreset;
int ch;
bool vflag = FALSE;
struct option longopts[] = {
{ "verbose", required_argument, NULL, 'v'},
{ "version", no_argument, NULL, 'V'},
{ "debug", no_argument, NULL, 'd'},
{ "user", required_argument, NULL, 'u'},
{ "group", required_argument, NULL, 'g'},
{ "port", required_argument, NULL, 'p'},
{ "listen", required_argument, NULL, 'l'},
{ "help", no_argument, NULL, 'h'},
{ "silent", no_argument, NULL, 's'},
{ "configfile", required_argument, NULL, 'f'},
{ "pidfile", required_argument, NULL, 'P'}
};
while((ch = getopt_long(argc, argv, "Vhsdr
f:v:P:u:g
:l:",
longopts, NULL)) != -1)
{
switch(ch)
{
case 'h':
#ifdef MAGT_DEBUG_CONFIG
magt_print("got option 'h'");
#endif
magt_print( "%s %s", PACKAGE, VERSION);
magt_print( "Usage: magt [OPTIONS]...\n");
magt_print( " -d, --debug\tactivate debug messages, same as -
v4");
magt_print( " -D, --daemon\tmakes the process a daemon");
magt_print( " -f, --file\tspecify another configuration
file");
magt_print( " -g, --group\tgroup to run as");
magt_print( " -h, --help\tthis help message");
magt_print( " -l, --listen\thost to listen, can be \"all\"
for wildcard");
magt_print( " -p, --port\tport to listen");
magt_print( " -s, --silent\tsupress all output, same as -
v0");
magt_print( " -u, --user\tuser to run as");
magt_print( " -v, --verbose\tverbose level");
magt_print( " -V, --version\tdisplay name and version");
exit(0);
break;
case 'd':
#ifdef MAGT_DEBUG_CONFIG
magt_print( "got option 'd'");
#endif
if(vflag)
{
magt_print( "Can't mix -v/--version with -d/--debug or -
s/--silent");
exit(1);
}
vflag = TRUE;
magt_config_set_verbose(mconfig, MAGT_LOG_LEVEL_DEBUG);
#define MAGT_DEBUG
break;
case 'D':
#ifdef MAGT_DEBUG_CONFIG
magt_print( "got option 'D'");
#endif
magt_config_set_daemonize(mconfig, TRUE);
break;
case 'v':
#ifdef MAGT_DEBUG_CONFIG
magt_print( "got option 'v' argument: %s", optarg);
#endif
if(vflag)
{
magt_print( "Fatal: Can't mix -v/--version with -d/--debug
or -s/--silent");
exit(1);
}
vflag = TRUE;
magt_config_set_verbose(mconfig, atoi(optarg));
break;
case 's':
#ifdef MAGT_DEBUG_CONFIG
magt_print( "got option 's'");
#endif
if(vflag)
{
magt_print( "Fatal: Can't mix -v/--version with -d/--debug
or -s/--silent");
exit(1);
}
vflag = TRUE;
magt_config_set_verbose(mconfig, MAGT_LOG_LEVEL_SILENT);
break;
case 'f':
#ifdef MAGT_DEBUG_CONFIG
magt_print( "got option 'f' argument: %s", optarg);
#endif
magt_config_set_config_file(mconfig, optarg);
break;
case 'V':
#ifdef MAGT_DEBUG_CONFIG
magt_print( "got option 'V'");
#endif
magt_print( "%s %s", PACKAGE, VERSION);
exit(0);
break;
case 'P':
#ifdef MAGT_DEBUG_CONFIG
magt_print( "got option 'P'");
#endif
magt_config_set_pid_file(mconfig, optarg);
break;
case 'u':
#ifdef MAGT_DEBUG_CONFIG
magt_print( "got option 'u' argument: %s", optarg);
#endif
magt_config_set_user(mconfig, optarg);
break;
case 'g':
#ifdef MAGT_DEBUG_CONFIG
magt_print( "got option 'g' argument: %s", optarg);
#endif
magt_config_set_group(mconfig, optarg);
break;
case 'p':
#ifdef MAGT_DEBUG_CONFIG
magt_print( "got option 'p' argument: %s", optarg);
#endif
magt_config_set_port(mconfig, atoi(optarg));
break;
case 'l':
#ifdef MAGT_DEBUG_CONFIG
magt_print( "got option 'l' argument: %s", optarg);
#endif
magt_config_set_listen(mconfig, optarg);
break;
}
}
}
Rui Maciel wrote:
> Is it possible to parse command line arguments with the help of flex and
> bison? If so, how is it done? I suspect that it may be simply a matter of
> tweaking flex into processing arrays of null-terminated strings instead
> of stdin but I can't find a single reference.
>
> So, can anyone help?
>
>
> Thanks in advance,
> Rui Maciel