Re: Lex/Yacc error reporting

quanstro@stolaf.edu (Erik Quanstrom)
Fri, 29 May 1992 18:53:37 GMT

          From comp.compilers

Related articles
LEX/YACC - grammar problems and printing error messages nett@technix.mn.org (1992-05-28)
Re: Lex/Yacc error reporting quanstro@stolaf.edu (1992-05-29)
| List of all articles for this month |
Newsgroups: comp.compilers
From: quanstro@stolaf.edu (Erik Quanstrom)
Keywords: lex, errors, code
Organization: Compilers Central
References: 92-05-148
Date: Fri, 29 May 1992 18:53:37 GMT

I usually hand-code lexers, so getting the entire line of input is usually
not a problem but when that fails, it is not difficult to code one's own
versions of getc() and putc() so that they save the entire line of input
in a buffer. Writeing one's own input functions is not really as great a
requirement as it sounds since for many languages specalized input
functions must be written because input may be from a string as well as a
file (consider "eval" or the -c option in /bin/sh).


Following is a some code which I use for input. It's slightly tuned
for the shell that I am working on (it's slightly further out than
rc and an alpha version is availaible for anonomous ftp from
ftp.stolaf.edu:/pub/quanstro/goosh-0.2.5.tar.Z) It has a few features
that are beyond the call of duty, like allowing one to "push" the
input stream and then later "pop" it, going back to the previous
input stream but it still remains much faster than the stdio library.
[Have you benchmarked a lexer using this against one from flex? I expect
flex would win, it's really fast. -John]


/************************************************************************
  * file: input.c *
  * *
  * object: i/o *
  * *
  * Copyright (C) 1992 Erik Quanstrom *
  * *
  * terms: Don't sell this code and don't remove my name and other *
  * than that I don't care. *
  * *
  * 1. M"arz 1992 *
  ************************************************************************/
#include <fcntl.h>
#include "goosh.h"
#include "trap.h"
#include "lex.h"
#include "walk.h"
#include "redir.h"
#include "status.h"


#ifdef BUFSIZE
#undef BUFSIZE
#endif
#define BUFSIZE 1000 /* maximum line size */


extern int yyparse(void); /* function declarations */
void input_fd(int fd);
void input_str(char *s);


int gchar_str(void);
void ugchar_str(int c);
int gchar_push(void);


int gchar_fd(void);
void ugchar_fd(int c);
int gchar_fd_push(void);


char *gbuf(void); /*
* get whole buffer (for error
* messages
*/


STATIC char *input_strp;
static char input_ugetb[100];
static char *input_ugetbp;


struct _io_stak_
{
    int Ibuf_fd;
    boolean Ieof;


    char *Ibuf,
              *Ibufp,
              *Ibufe;


    int (*gchar)(void);
    void (*ugchar)(int i);


    struct _io_stak_ *p;
};


typedef struct _io_stak_ io_stack;
io_stack *io_top = NULL;


static char *Ibuf = NULL;
static char *Ibufp = NULL;
static char *Ibufe;
static boolean Ieof;
static int Ibuf_fd;


int (*gchar)(void) = gchar_fd;
void (*ugchar)(int i) = ugchar_fd;


/************************************************************************
  * function: flush() *
  * *
  * object: delete input up to end of line *
  * *
  * 6. M"arz 1992 *
  ************************************************************************/
  void flush(void)
{
    Ibufe = Ibuf; /* pretend we read the whole buffer */
}


/************************************************************************
  * function: at_eof() *
  * *
  * object: input-device independent test for eof *
  * *
  * 6. M"arz 1992 *
  ************************************************************************/
boolean at_eof(void)
{
    if ((gchar == gchar_fd) || gchar == gchar_fd_push) /* hack */
        return Ieof;


    return (!*input_strp && (input_ugetb == input_ugetbp));
}


void input_fd(int fd)
{
    if (!Ibuf)
        Ibuf = (char *)gmalloc(BUFSIZE);


    Ibuf_fd = fd;
    Ieof = false;
    Ibufp = NULL;
    Ibufe = NULL;


    input_ugetbp = input_ugetb;
    gchar = gchar_fd;
    ugchar = ugchar_fd;
}


void input_str(char *s)
{
    gchar = gchar_str;
    ugchar = ugchar_str;
    input_strp = s;
    input_ugetbp = input_ugetb;
}


void input_push(void)
{
    io_stack *S = (io_stack *)gmalloc(sizeof(io_stack));


    S->Ibuf_fd = Ibuf_fd;


    S->Ieof = Ieof;
    S->Ibuf = Ibuf;
    S->Ibufp = Ibufp;
    S->Ibufe = Ibufe;
    S->gchar = gchar;
    S->ugchar = ugchar;
    S->p = io_top;
    io_top = S;


    Ibuf = Ibufp = NULL;
}


void input_pop(void)
{
    io_stack *S = io_top;


    Ibuf_fd = io_top->Ibuf_fd;
    Ieof = io_top->Ieof;
    Ibuf = io_top->Ibuf;
    Ibufp = io_top->Ibufp;
    Ibufe = io_top->Ibufe;
    gchar = io_top->gchar;
    ugchar = io_top->ugchar;
    io_top = io_top->p; /* Assume that things are working !! */


    if (S)
        {
            if (S->Ibuf)
free((void *)S->Ibuf);
            free((void *)S);
        }
}


/************************************************************************
  * functions: gchar_str(), ugchar_str(), gchar_push() *
  * *
  * object: make a string act like a file as far as yylex *
  * is conserned *
  * *
  * 6. M"arz 1992 *
  ************************************************************************/
int gchar_str(void)
{
    if (!*input_strp)
        return EOF;


    return *input_strp++;
}


void ugchar_str(int c)
{
    *input_ugetbp++ = c;
    gchar = gchar_push;
}


int gchar_push(void)
{
    if (input_ugetbp == input_ugetb)
        {
            gchar = gchar_str;
            return gchar();
        }


    return *--input_ugetbp;
}


/************************************************************************
  * functions: gchar_fd(), ugchar_fd(), *
  * *
  * object: buffer a fd *
  * *
  * 6. M"arz 1992 *
  ************************************************************************/
int gchar_fd(void)
{
    size_t size;


    if (Ieof)
        return EOF;


    if (Ibufp && (Ibufp < Ibufe))
        {
        in:
            Ibufp++;
            return *(Ibufp - 1);
        }


    switch (size = read(Ibuf_fd, Ibuf, BUFSIZE))
        {
        case 0:
            Ieof = true;
            return EOF;
        case -1:
            panic(NULL);
        default:
            Ibufp = Ibuf;
            Ibufe = Ibuf + size;
            goto in;
        }
}


void ugchar_fd(int c)
{
    *input_ugetbp++ = c;
    gchar = gchar_fd_push;
    Ieof = false;
}


int gchar_fd_push(void)
{
    if (input_ugetbp == input_ugetb)
        {
            gchar = gchar_fd;
            return gchar();
        }


    return *--input_ugetbp;
}


char *gbuf(void)
{
    return Ibuf;
}
--


Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.