yacc, sólo se aplica la regla vez
Pregunta
Estoy tratando de escribir un shell mediante yacc y lex y estoy corriendo en algunos problemas con mis redirectores de E / S. Actualmente, puedo usar los operadores
Mi código está por debajo de la regla, ¿alguien puede darme algunos consejos sobre cómo solucionar este problema? Gracias!
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:. Después de hablar con mi TA, supe que en realidad no necesitan tener solamente 1 modificador de mi mando y que en realidad puede tener múltiples copias de la misma redirección de E / S
Solución
Hay dos enfoques:
(1) Modificar la gramática de manera que sólo se puede tener uno de cada tipo de modificador:
io_mod_opt: out_mod in_mod | in_mod out_mod | in_mod | out_mod | ;
(2) Modificar el controlador de la cláusula de contar los modificadores e informar de un error si hay más de uno:
GREAT_WORD { if (already_have_output_file()) { error("too many output files: \"%s\"\n", $2) } else { /* record output file */ } }
Opción (2) parece probable que conduzca a mejores mensajes de error y una gramática más simple.
Otros consejos
También hay un tercer enfoque - no se preocupe. Bash (bajo Cygwin) no genera un error para:
ls > x > y
Crea x y luego Y y termina escribiendo a y.
Me doy cuenta de que esto podría ser sólo un ejercicio para aprender lexx y yacc, pero por lo demás la primera pregunta es preguntar a ¿Por qué que desea utilizar lexx y yacc? Cualquier lenguaje de comandos shell habitual tiene una gramática muy simple; ¿qué estás ganando el uso de un generador de LALR?
Bueno, aparte de la complejidad, dificultad para generar buenos mensajes de error, y el volumen de código, quiero decir.