tags:

views:

160

answers:

3

Hi guys, I'm trying to write a shell using yacc and lex and I'm running into some problems with my I/O redirectors. Currently, I can use the < and > operators fine and in any order, but my problem is I can redirect twice with no error, such as "ls > log > log2"

My rule code is below, can anyone give me some tips on how to fix this? Thanks!

 io_mod:
    iomodifier_opt io_mod
    |
    ;

 iomodifier_opt:
    GREAT WORD {
        printf("   Yacc: insert output \"%s\"\n", $2);
        Command::_currentCommand._outFile = $2;
    }
    |
    LESS WORD {
       printf("   Yacc: insert input \"%s\"\n", $2);
       Command::_currentCommand._inputFile = $2;
    }
    | /* can be empty */
    ;

EDIT: After talking to my TA, I learned that I did not actually need to have only 1 modifier for my command and that I actually can have multiple copies of the same I/O redirection.

+3  A: 

There are two approaches:

(1) Modify the grammar so that you can only have one of each kind of modifier:

io_mod_opt: out_mod in_mod | in_mod out_mod | in_mod | out_mod | ;

(2) Modify the clause handler to count the modifiers and report an error if there's more than one:

GREAT_WORD {
    if (already_have_output_file()) {
        error("too many output files: \"%s\"\n", $2)
    } else {
        /* record output file */
    }
}

Option (2) seems likely to lead to better error messages and a simpler grammar.

Gareth Rees
A: 

I realize this might be just an exercise to learn lexx and yacc, but otherwise the first question is to ask why you want to use lexx and yacc? Any usual shell command language has a pretty simple grammar; what are you gaining from using an LALR generator?

Well, other than complexity, difficulty generating good error messages, and code bulk, I mean.

Charlie Martin
It's for a class, so I'm gaining points toward my grade ;)
samoz
okay, so it's an exercise.
Charlie Martin
+1  A: 

There's also a third approach - don't fret. Bash (under Cygwin) does not generate an error for:

ls > x > y

It creates x and then y and ends up writing to y.

Jonathan Leffler