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 ...

+ Reply to Thread
Results 1 to 5 of 5

Thread: flex & bison: parse command line arguments?

  1. 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

  2. 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.

  3. 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

  4. 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;
    }

  5. 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, "Vhsdrf: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


+ Reply to Thread