%token  STRING
%token  RIGHT_APPEND
%%
cmd:    fg_cmd
   |    bg_cmd
   ;
bg_cmd: fg_cmd '&'
      ;
fg_cmd:    simple_cmd
      |    pipe_cmd
      ;
simple_cmd:     /* empty command */
          |     executable
          |     executable input_redirection
          |     input_redirection executable
          |     executable output_redirection
          |     output_redirection executable
          |     executable input_redirection   output_redirection
          |     input_redirection   executable  output_redirection
          |     input_redirection   output_redirection  executable
          |     executable  output_redirection   input_redirection
          |     output_redirection   executable  input_redirection
          |     output_redirection   input_redirection  executable
          ;
executable: STRING
          | STRING executable;
input_redirection:  '<' STRING;
output_redirection:     overwrite_output_redirection
                  |     append_output_redirection
                  ;
overwrite_output_redirection:   '>'  STRING ;
append_output_redirection:      RIGHT_APPEND STRING ;
pipe_cmd:   left_cmd '|' right_cmd
        |   left_cmd '|' middle_cmd right_cmd
        ;
left_cmd:   executable
        |   executable input_redirection
        |   input_redirection executable 
        ;
middle_cmd: executable '|'
          | middle_cmd executable '|'
          ;
right_cmd:  executable  
         |  executable output_redirection
         |  output_redirection executable 
         ;
%%
int main(int argc, char *argv[])
{
    yyparse();
    return 0;
}
int yywrap()
{
    return 1;
}
int yyerror(char *msg)
{
    printf("Error encountered: %s\n", msg);
}