Skip to Content

Lex & Yacc

Posted in
lex-exp1.l:
%{
/* C code section */
#include <stdio.h>
#include "y.tab.h"    /* Include tokens generated by Yacc */
%}

num     [0-9]+

%%
{num}   { printf("Number: %s\t token: %d\n", yytext, NUMBER) ;
          return NUMBER ;
        }

[a-z]+  { printf("Text: ") ;
          ECHO ; /* Macro to print the current matching text. */
          printf("\n") ;
          return TEXT ;
        }
\n      return '\n' ;
.       ;
%%

/* A routine that will be called at end of file reading. */
int yywrap()
{       /* return 1: No more input files.
           return 0: More input files. */
        return 1 ;
}
yacc-exp1.y:
%{
#include <stdio.h>
%}
%token NUMBER TEXT
%%
phonebook:      TEXT NUMBER '\n'                { printf("Basic phone book\n") ; }
        |       phonebook TEXT NUMBER '\n'      { printf("Extended phone book\n") ; }
        ;
%%
int main()
{       yyparse() ;
}

yyerror(char* s)
{       fprintf(stderr, "%s\n", s) ;
}
lex-exp2.l:
%{
#include <stdio.h>
%}

%s START END

%%
default\n       BEGIN 0 ; /* Default state */
start\n         BEGIN START ;
end\n           BEGIN END ;
<START>[a-z]+   {       /* Execute only in state START */
                        printf("Text: %s", yytext) ;
                }
%%

int yywrap()
{       return 1 ;
}
lex-exp3.l:
%{
#include <stdio.h>
#include <stdlib.h>
#include "y.tab.h"
/* Variable to store value of a token. */
/* extern int yylval ; Not needed because we have %union in the .y,
                       the token type is included in y.tab.h. */
%}

%%

[0-9]+  { yylval.ival = atoi(yytext) ; return NUMBER ; }
[ \t]   ;
.       return yytext[0] ;
\n      return '\n' ;

%%

int yywrap()
{       return 1 ;
}
yacc-exp3.y:
%{
#include <stdio.h>
%}

%union {
        double dval ;
        int ival ;
}

%token <ival> NUMBER
%left '+' '-'    /* Low precedence */
%left '*' '/'    /* Medium precedence */
%nonassoc UMINUS /* High precedence */
%start exprs

%type <ival> expr 

%%

exprs:          expr '\n'               { printf("Answer: %d\n", $1) ; }
        |       exprs expr '\n'         { printf("Answer: %d\n", $2) ; }
        ;
expr:           expr '+' expr   { $$ = $1 + $3 ; }
        |       expr '-' expr   { $$ = $1 - $3 ; }
        |       expr '*' expr   { $$ = $1 * $3 ; }
        |       expr '/' expr   { $$ = $1 / $3 ; }
        |       '-' expr %prec UMINUS  { $$ = -$2 ; }
        |       NUMBER          { $$ = $1 ; }
        ;

%%

int main()
{       yyparse() ;
}

yyerror(char* s)
{       fprintf(stderr, "%s\n", s) ;
}

Others for Lex:
input(): Get next character from the input stream.
unput(): Put a character back to input stream.
FILE* yyin: File pointer to current input stream. Default to stdin.
FILE* yyout: File pointer to current output stream. Default to stdout.
yylex(): Call the lexer.
yyleng: Length of the yytext.
REJECT: Macro to put back the text.
yyinput(), yyoutput(), yyunput()
yyless(), yymore()

Others for Yacc:
%right: To define a right associative operator.
$1, $$, $-1
YYABORT, YYACCEPT, YYBACKUP
yyclearin, yydebug, YYDEBUG, yyerrok, YYERROR, YYRECOVERING()

Reference: UNIX Programming Tools: lex & yacc by John R. Levine, Tony Mason & Dough Brown