argv ==> stdin, got it

Chris Torek chris at mimsy.UUCP
Sat Nov 22 04:03:22 AEST 1986


In article <2976 at rsch.WISC.EDU> mcvoy at rsch.WISC.EDU (Lawrence W. McVoy) writes:
>/*
> * code to fork a child and have control of the child's stdin/out
> * from usenet.  Works.  Fast, too.  The idea is that the command line
> * is fed to the stdin of the child.  This is so that you don't have
> * to f*ck with the stupid code in y.tab.c or lex.yy.c.  It should work
> * for anything that wants stdin.
> */

So what is so hard about making lex read argv rather than stdin?
Here is a trivial parser that accepts only `foo bar;'.  Note that
the semicolon must be quoted to protect it from the shell.

: Run this shell script with "sh" not "csh"
PATH=/bin:/usr/bin:/usr/ucb:/etc:$PATH
export PATH
all=FALSE
if [ x$1 = x-a ]; then
	all=TRUE
fi
echo Extracting Makefile
sed 's/^X//' <<'//go.sysin dd *' >Makefile
a.out: main.o y.o
	cc main.o y.o
y.o: y.c l.c

clean:
	rm -f a.out core *.o l.c y.c
//go.sysin dd *
if [ `wc -c < Makefile` != 84 ]; then
	made=FALSE
	echo error transmitting Makefile --
	echo length should be 84, not `wc -c < Makefile`
else
	made=TRUE
fi
if [ $made = TRUE ]; then
	chmod 644 Makefile
	echo -n '	'; ls -ld Makefile
fi
echo Extracting l.l
sed 's/^X//' <<'//go.sysin dd *' >l.l
%{
#undef input
#undef unput
%}

%%
foo		{ return (FOO); }
bar		{ return (BAR); }
[ \t\n]		;
X.		{ return (yytext[0]); }
%%
//go.sysin dd *
if [ `wc -c < l.l` != 123 ]; then
	made=FALSE
	echo error transmitting l.l --
	echo length should be 123, not `wc -c < l.l`
else
	made=TRUE
fi
if [ $made = TRUE ]; then
	chmod 644 l.l
	echo -n '	'; ls -ld l.l
fi
echo Extracting main.c
sed 's/^X//' <<'//go.sysin dd *' >main.c
int	argc;
char	**argv;
char	unbuf[512];
int	unc;

main(ac, av)
	int ac;
	char **av;
{

	argc = ac - 1;
	argv = av + 1;
	exit(yyparse());
}

yyerror()
{

	write(2, "syntax error\n", 13);
	exit(1);
}

unput(c)
	int c;
{

	unbuf[unc++] = c;
}

input()
{

	if (unc)
		return (unbuf[--unc]);
	if (argc <= 0)
		return (0);
	if (**argv == 0) {
		argc--;
		argv++;
		return (' ');
	}
	return (*(*argv)++);
}
//go.sysin dd *
if [ `wc -c < main.c` != 400 ]; then
	made=FALSE
	echo error transmitting main.c --
	echo length should be 400, not `wc -c < main.c`
else
	made=TRUE
fi
if [ $made = TRUE ]; then
	chmod 644 main.c
	echo -n '	'; ls -ld main.c
fi
echo Extracting y.y
sed 's/^X//' <<'//go.sysin dd *' >y.y
%token	FOO BAR

%%
prog:	FOO BAR ';'	;
%%
#include "l.c"

yywrap()
{
	return (1);
}
//go.sysin dd *
if [ `wc -c < y.y` != 84 ]; then
	made=FALSE
	echo error transmitting y.y --
	echo length should be 84, not `wc -c < y.y`
else
	made=TRUE
fi
if [ $made = TRUE ]; then
	chmod 644 y.y
	echo -n '	'; ls -ld y.y
fi
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690)
UUCP:	seismo!mimsy!chris	ARPA/CSNet:	chris at mimsy.umd.edu



More information about the Comp.unix.questions mailing list