%{
typedef char * text;
#define YYSTYPE text
char	in[]="in", out[]="out", 
	pipe[]="PIPE", tty[] = "TTY", 
	buf[2][16], *fd[2] = {tty, tty}, argc;
%}
%token TOKEN APPEND
%%
input	: prompt 
	| input line '\n' prompt
	| input error '\n' prompt { yyerrok;  }
prompt	: { printf ("%% "); }
line	: job 
	| line sep job
sep	: '&' | ';'
arrow	: '<'	{ $$ = in; }
	| outr 	{ $$ = out; }
outr	: '>' | APPEND
job	: pipe		{ if (showio ()) YYERROR; }	
pipe	: argv
	| pipe bar argv
bar	: '|' { if (redir(out,pipe) || showio() || redir(in,pipe)) YYERROR; }
argv	: 		{ argc = 0; }
| argv TOKEN		{ ++ argc; printf ("%s ", $2); }
| argv arrow TOKEN	{ if (redir ($2, $3)) YYERROR; }
| argv arrow error	{ printf("\nMissing name for %sput!\n", $2); YYERROR;}
%%
#include "lexer.c"
yywrap ()  {printf ("\n"); exit (0); }
yyerror () {}
int redir (end, file) text end, file; {
    int dir = end == in ? 0 : 1;
    if (fd [dir] != tty) 
      { printf ("\nAmbiguous %sput redirect!\n", end); return 1; }
    fd [dir] = (char *) strncpy (buf [dir], file, 15); return 0;
}
int showio () {
    argc ? printf ("\n\t\tInput: %-15.15s Output: %-15.15s\n", fd[0], fd[1])
    : fd [0] != tty || fd [1] != tty ? argc = - 1: 0;
    fd [0] = fd [1] = tty;
    if (argc < 0) printf ("\nInvalid null comand!\n");
    return (argc < 0);
}
