Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: utzoo!watmath!clyde!rutgers!uwvax!mcvoy
From: mcvoy@uwvax.UUCP
Newsgroups: comp.unix.wizards
Subject: Re: argv --> stdin IN LEX
Message-ID: <3060@rsch.WISC.EDU>
Date: Wed, 10-Dec-86 21:32:13 EST
Article-I.D.: rsch.3060
Posted: Wed Dec 10 21:32:13 1986
Date-Received: Sun, 14-Dec-86 08:37:34 EST
References: <1367@brl-adm.ARPA>
Reply-To: mcvoy@rsch.WISC.EDU (Lawrence W. McVoy)
Followup-To: /dev/null
Organization: U of Wisconsin CS Dept
Lines: 157

In article <1367@brl-adm.ARPA> rbbb@rice.EDU (David Chase) writes:
>RTFM! RTFM! RTFM!  I QUOTE:
>	In addition to these routines, Lex also permits access to the
>    I/O routines that it uses.  They are:
>    1)	input() which returns the next input character;
>    2)	output(c) which writes the character c on the
>	output; and
>    3)	unput(c) pushes the character c back onto the
>	input stream to be read later by input().
>
>    By default these routines are provided as macros definitions,
>    but the user can override them and supply private versions.
>    ....

  After RTFM! RTFM! RTFM!-ing again and wading through lex 
output (gag):  Yup.  Works neat.  With lex.  Doesn't work at all 
with yacc.  If y'all go back and read the original posting, you 
will notice that I kinda asked for a solution that works with 
lex and yacc.  
  
  The relevant parts of the code are included below.  My guess 
is that yacc makes some assumptions about buffers, though 
I can't see where.

  I've got a fix that has nothing to do with lex & yacc and I 
like it that way.  The original problem, which might occur in 
situations that don't use lex and yacc, is how do you send 
the chars in argv[] to a process that thinks it's getting
them from stdin?  The answer:  Use a pipe.  If you know that 
you have less than 4k or so, don't even bother to fork.  

Here's the offending code, if you're interested, be warned that 
I don't vouch for this, it's a hack:

---------------------- t.l ---------------------------
%{
# undef		input()
# undef		unput()
# define	input()		myinput()
# define	unput(c)	myunput(c)
# include	
# include	"y.tab.h"
%}
DIGIT	[0-9]
DSEQ	"-"?{DIGIT}+
RSEQ	"-"?{DSEQ}"."{DSEQ}
EXPONP	("e"|"E")("-"|"+")?{DSEQ}
MULT	[xX*]
RPAR	[)rR]
LPAR	[(lL]
%%
"+"			return(PLUS);
"-"			return(MINUS);
{MULT}			return(MULTIPLY);
"/"			return(DIVIDE);
{LPAR}			return(LPAREN);
{RPAR}			return(RPAREN);
{DSEQ}			return(INT_CONST);
{RSEQ}			return(REAL_CONST);
({DSEQ}|{RSEQ}){EXPONP}	return(REAL_CONST);
\n			return(EOL);
[ \t]			;		/* white space, ignore */
.			{ printf("Scanner error: Illegal Character\n"); }
%%

char*	ptr;
char	buf[4096];

myinput()
{
    fprintf(stderr, "Input called, ptr = '%s'\n", ptr);
    return *ptr++;
}

myunput(c)
    char c;
{
    if (ptr == buf) {
	fprintf(stderr, "ERROR: tried to unput one too many (%c)\n", c);
	exit(1);
    }

    fprintf(stderr, "Unput called, ptr = '%s'\n", ptr);
    *--ptr = c;
}

main(argc, argv)
    char** argv;
{
    int 	i;
    char*	s;

    ptr = buf;
    for (i=1; i

extern char yytext[];
extern float atof();

static float result;
%}
%token
	PLUS MINUS MULTIPLY DIVIDE INT_CONST REAL_CONST LPAREN RPAREN EOL
%union
{
	float val;
}
%type
		root expr factor term
%%
root	:	expr EOL	{
				printf("%.4f\n",$1);
				exit(0);
				}
	;
expr	:	expr PLUS term	{ $$ = $1 + $3; }
	|	expr MINUS term { $$ = $1 - $3; }
	|	term
	;
term	:	term MULTIPLY factor	{ $$ = $1 * $3; }
	|	term DIVIDE factor	{ $$ = $1 / $3; }
	|	factor
	;
factor	:	INT_CONST	{ $$ = (float)atoi(yytext); }
	|	REAL_CONST	{ $$ = atof(yytext); }
	|	LPAREN expr RPAREN { $$ = $2; }
	;
-- 
Larry McVoy 	        mcvoy@rsch.wisc.edu, 
      		        {seismo, topaz, harvard, ihnp4, etc}!uwvax!mcvoy

"They're coming soon!  Quad-stated guru-gates!"