Redirect stdin ?

L

Lothar Behrens

Hi,

I have a c application (Lex&Yacc based) that parses from stdin. I want
to rewrite the code
a bit to allow reading the source from a char array instead from stdin
without touching the
lex and yacc generated source code.

How could I do that ?

What is about the problem when the buffer is too big to feed the
source to the parser at once ?

Any ideas ?

Thanks, Lothar
 
W

William Pursell

I have a c application (Lex&Yacc based) that parses from stdin. I want
to rewrite the code
a bit to allow reading the source from a char array instead from stdin
without touching the
lex and yacc generated source code.

How could I do that ?

What is about the problem when the buffer is too big to feed the
source to the parser at once ?

Any ideas ?

If you are okay with using gcc extensions, here's a section
from the glibc info pages you might find interesting:

Here is an example of using `fmemopen' to create a stream for
reading from a string:

#include <stdio.h>

static char buffer[] = "foobar";

int
main (void)
{
int ch;
FILE *stream;

stream = fmemopen (buffer, strlen (buffer), "r");
while ((ch = fgetc (stream)) != EOF)
printf ("Got %c\n", ch);
fclose (stream);

return 0;
}

This program produces the following output:

Got f
Got o
Got o
Got b
Got a
Got r
 
H

Harald van Dijk

If you are okay with using gcc extensions, here's a section from the
glibc info pages you might find interesting:

<OT> gcc is not glibc, and glibc is not gcc. If it's documented in the
glibc info pages, you can assume it's a glibc extension rather than a gcc
one. Except for those that have been part of POSIX or similar standards
for a while, glibc extensions are less portable / more unportable than
gcc extensions. </OT>
 
J

jameskuyper

Lothar said:
Hi,

I have a c application (Lex&Yacc based) that parses from stdin. I want
to rewrite the code
a bit to allow reading the source from a char array instead from stdin
without touching the
lex and yacc generated source code.

How could I do that ?

lex uses three macros that can be #defined by the user named 'input',
'unput' and 'output'. It is designed with the intention that you can
override those macros as needed to define different input sources. I
don't know if that meets your needs; it requires a change in the
source code you give to lex, which means that lex will generate
different output code, which is technically a violation of your
requirements. Depending upon the reasons for your requirements, it
might be better to modify your requirements than to use the more
complicated approaches needed to conform to those requirements.
What is about the problem when the buffer is too big to feed the
source to the parser at once ?

Your 'input' macro could refer to a function that stores only as much
of the file as can actually fit into your buffer at any given time. As
long as your buffer is a least big enough to hold the longest look-
ahead required by your grammar, that shouldn't be a problem.
 
L

Lothar Behrens

<OT> gcc is not glibc, and glibc is not gcc. If it's documented in the
glibc info pages, you can assume it's a glibc extension rather than a gcc
one. Except for those that have been part of POSIX or similar standards
for a while, glibc extensions are less portable / more unportable than
gcc extensions. </OT>

Yes,

I didn't find the fmemopen in my "Linux Unix Systemprogramming" book.
And I'll also implement the code for Windows using Open Watcom.

The Open Watcom documentation also does not contain this function.

On Mac OS X I currently did not know, if it is available too.

A short question: Is fmemopen based on memory mapped files ?

Lothar
 
L

Lothar Behrens

lex uses three macros that can be #defined by the user named 'input',
'unput' and 'output'. It is designed with the intention that you can
override those macros as needed to define different input sources. I
don't know if that meets your needs; it requires a change in the
source code you give to lex, which means that lex will generate
different output code, which is technically a violation of your
requirements. Depending upon the reasons for your requirements, it
might be better to modify your requirements than to use the more
complicated approaches needed to conform to those requirements.

I do understand these macros as callbacks where I could do the
feeding.

My requirements were not to modify the generated code from lex and
yacc to
get a workaround (as of I wouldn't be aware of Lex & Yacc a bit)

Currently I have changed the grammar. There was a problem with the
supported
syntax of my SQL code. So I tend to change it as you supposed.
Your 'input' macro could refer to a function that stores only as much
of the file as can actually fit into your buffer at any given time. As
long as your buffer is a least big enough to hold the longest look-
ahead required by your grammar, that shouldn't be a problem.

As of the case I handle SQL statements, the lookahead buffer may be
big enough,
when I allocate 100 bytes. That will be enough for a small query.

In case not, where do I see the size of this buffer ?

Thank you,

Lothar
 
W

Walter Roberson

Lothar Behrens said:
My requirements were not to modify the generated code from lex and
yacc to
get a workaround (as of I wouldn't be aware of Lex & Yacc a bit)

There are two different interpretations to "not to modify the
generated code from lex and yacc".

One interpretation is that you do not want to hand-modify the C code
that lex and yacc generate: if that is the interpretation, then you can
solve the problem along the lines James gave, by altering the input
macros (or, alternately, by supplying your own yyin() routine).
You supply lex and yacc with an input routine and the code lex and
yacc would generate would take the supplied input routine into account.
This is the interpretation of your requirements if the emphasis
in your requirement is on "modify".

The second possible interpretation of your requirement is that
for some reason or other you require that whatever solution is
arrived at must have the lex and yacc sections compile to exactly
the same object code as would be the case if you were working with
a regular file instead of a string. This is the interpretation of
your requirements if the emphasis in your requirements is on
"generated" -- that the *generated* code must be exactly the same.
This might be the case if, for example, you intended to call the same
lex and yacc routines, sometimes supplying input from a string
and sometimes providing input from a file. James noted that
his suggestion did not technically meet your requirements because
if you modify the input macros then even though the C source output
by lex and yacc might look the same (except perhaps a line or two),
when the compiler got through with it, the object code generated
would be different, in violation of your constraint to not modify
the *generated* code: modifying the macros before running lex and
yacc would result in different code being generated. Anyhow, if this
is your requirement, then I believe you could meet the those
terms by supplying your own yyin() function; if I recall, yyin()
is function which is linked against, so the object code would not
change.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top