argv --> stdin IN LEX
mcvoy at uwvax.UUCP
mcvoy at uwvax.UUCP
Thu Dec 11 12:32:13 AEST 1986
In article <1367 at brl-adm.ARPA> rbbb at 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 <stdio.h>
# 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<argc; i++)
for (s=argv[i]; *s; *ptr++ = *s++)
;
ptr = buf;
printf("Sending %s to lex\n", buf);
# ifdef TESTLEX
/* this works like a charm */
while (i = yylex())
printf("Lex returns %d\n", i);
# else
/* this bombs */
yyparse();
# endif
}
yyerror(s)
char* s;
{
fprintf(stderr, "%s\n");
}
---------------------- t.l ---------------------------
%{
#include <stdio.h>
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
<val> 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 at rsch.wisc.edu,
{seismo, topaz, harvard, ihnp4, etc}!uwvax!mcvoy
"They're coming soon! Quad-stated guru-gates!"
More information about the Comp.unix.wizards
mailing list