2009-02-23 13 views
1

J'essaie d'écrire un shell en utilisant yacc et lex et je rencontre des problèmes avec mes redirecteurs d'E/S. Actuellement, je peux utiliser le < et> opérateurs bien et dans n'importe quel ordre, mais mon problème est que je peux rediriger deux fois sans erreur, comme "ls> log> log2"yacc, appliquer une seule fois la règle

Mon code de règle est ci-dessous, quelqu'un peut-il donner moi quelques conseils sur la façon de résoudre ce problème? Merci!

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: Après avoir parlé à mon TA, j'ai appris que je ne l'ai pas vraiment besoin d'avoir seulement 1 modificateur pour ma commande et que je peux effectivement avoir plusieurs copies de la même redirection E/S.

+0

Est-ce une exigence pour une affectation? Le shell standard vous permet de rediriger plusieurs fois sans erreur, la sortie va juste dans le dernier fichier. Je ne suis pas sûr de la façon dont vous voulez que ce soit réaliste, mais il vous manque >> et <<. – CTT

+0

En fait, ce n'est pas mentionné pour le travail que je fais, je pensais juste qu'il serait plus logique de ne pouvoir rediriger qu'une seule fois. Je suis d'accord la liste ci-dessus est incomplète, je vais ajouter l'autre redirection d'E/S plus tard. – samoz

Répondre

4

Il existe deux approches:

(1) Modifier la grammaire de sorte que vous ne pouvez avoir un de chaque type de modification:

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

(2) Modifier le gestionnaire de clause pour compter les modificateurs et signaler une erreur s'il y a plus d'un:

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

Option (2) semble susceptible de conduire à de meilleurs messages d'erreur et une grammaire simple.

-1

Je réalise que cela pourrait être juste un exercice pour apprendre lexx et yacc, mais sinon la première question est de demander pourquoi vous voulez utiliser lexx et yacc? Tout langage de commande shell habituel a une grammaire assez simple; que gagnez-vous en utilisant un générateur LALR?

Eh bien, en dehors de la complexité, de la difficulté à générer de bons messages d'erreur, et de l'encombrement du code, je veux dire.

+0

C'est pour une classe, donc je gagne des points en direction de ma classe;) – samoz

+0

ok, donc c'est un exercice. –

1

Il y a aussi une troisième approche - ne vous inquiétez pas. Bash (sous Cygwin) ne génère pas d'erreur pour:

ls > x > y 

Il crée x et y et finit par écrire à y.