yacc, seule application de la règle une fois
Question
Je suis en train d'écrire un shell en utilisant yacc et lex et je suis en cours d'exécution en quelques problèmes avec mes redirecteurs E / S. À l'heure actuelle, je peux utiliser les opérateurs
Mon code de règle est ci-dessous, quelqu'un peut me donner 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 I / O
La solution
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.
Autres conseils
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.
Je sais que cela pourrait être juste un exercice pour apprendre lexx et yacc, mais sinon la première question est de demander pourquoi que vous souhaitez utiliser lexx et yacc? Toute langue habituelle de commande shell a une grammaire assez simple; qu'est-ce que vous gagnez d'utiliser un générateur de LALR?
Eh bien, autre que la complexité, la difficulté à générer de bons messages d'erreur, et en vrac de code, je veux dire.