Search code examples
bisonyacclex

Basic Lex file for Hoc1 in book "Unix Programming Environment"


In the book "Unix Programming Environment" the book relies on writing its own lexer for all but one of the examples in the chapter on writing "hoc".

I would really like to see the use of lex for the first example hoc1. When I try to write my own using lex, the program doesn't output a response until I come up with a syntax error.

The code could be seen at the Unix Programming Environment website — now via the Wayback Machine: The UNIX Programming Environment


Solution

  • This seems to work for me:

    hoc1lex.l

    $ cat hoc1lex.l
    %{
    extern int lineno;
    #define YYSTYPE double
    #include "y.tab.h"
    %}
    
    %%
    
    [ \t]
    \n                                   { lineno++; return('\n'); }
    [0-9]*\.[0-9]+([eE][-+]?[0-9]+)?    { yylval = atof(yytext); return NUMBER; }
    [0-9]+(\.[0-9]*)?([eE][-+]?[0-9]+)? { yylval = atof(yytext); return NUMBER; }
    .                                    { return *yytext; }
    
    %%
    

    Context diff for hoc.y to hoc1.y

    $ diff -u hoc.y hoc1.y
    --- hoc.y   1995-06-12 16:30:21.000000000 -0700
    +++ hoc1.y  2011-09-18 18:59:02.000000000 -0700
    @@ -1,4 +1,5 @@
     %{
    +#include <stdio.h>
     #define    YYSTYPE double  /* data type of yacc stack */
     %}
     %token NUMBER
    @@ -19,7 +20,6 @@
     %%
        /* end of grammar */
     
    -#include <stdio.h>
     #include <ctype.h>
     char   *progname;  /* for error messages */
     int    lineno = 1;
    @@ -31,6 +31,7 @@
        yyparse();
     }
     
    +#if 0
     yylex()        /* hoc1 */
     {
        int c;
    @@ -48,6 +49,7 @@
            lineno++;
        return c;
     }
    +#endif /* 0 */
     
     yyerror(s) /* called for yacc syntax error */
        char *s;
    

    hoc1.mk makefile

    $ cat hoc1.mk
    YFLAGS = -d
    
    hoc1:   hoc1.o hoc1lex.o
        cc hoc1.o hoc1lex.o -o hoc1 -lfl
    
    hoc1lex.o:  y.tab.h
    

    Build and test

    $ make -f hoc1.mk
    yacc -d hoc1.y 
    mv -f y.tab.c hoc1.c
    cc    -c -o hoc1.o hoc1.c
    lex  -t hoc1lex.l > hoc1lex.c
    cc    -c -o hoc1lex.o hoc1lex.c
    cc hoc1.o hoc1lex.o -o hoc1 -lfl
    rm hoc1lex.c hoc1.c
    $ ./hoc1
    1.2 + 2.3
        3.5
    2.3/1.2
        1.9166667
    $