Exemplo de programa bison

Compiladores I 2005.1

Este e' um exemplo de um programa bison e seu arquivo "header"
"calc.h" que implementam uma calculadora. 
(Copiado de /usr/local/bin/bison)

========================================
	 arquivo calc.h
========================================

/* Data type for links in the chain of symbols.  */
struct symrec
{
  char *name;  /* name of symbol              */
  int type;    /* type of symbol: either VAR or FNCT */
  union {
    double var;           /* value of a VAR  */
    double (*fnctptr)();  /* value of a FNCT */
  } value;
  struct symrec *next;    /* link field    */
};

typedef struct symrec symrec;

/* The symbol table: a chain of `struct symrec'.  */
extern symrec *sym_table;

symrec *putsym ();
symrec *getsym ();




========================================
	 arquivo bison calc.y
========================================


/* Infix notation calculator--calc */

%{
#define YYSTYPE double
#include <math.h>
#include <malloc.h>
#include <alloca.h>
%}

%token NUM
%left '-' '+'
%left '*' '/'
%left NEG     /* negation--unary minus */
%right '^'    /* exponentiation        */

/* Grammar follows */
%%
input:    /* empty string */
        | input line
;

line:     '\n'
        | exp '\n'  { printf("\t%.10g\n", $1); }
;

exp:      NUM                { $$ = $1;         }
        | exp '+' exp        { $$ = $1 + $3;    }
        | exp '-' exp        { $$ = $1 - $3;    }
        | exp '*' exp        { $$ = $1 * $3;    }
        | exp '/' exp        { $$ = $1 / $3;    }
        | '-' exp  %prec NEG { $$ = -$2;        }
        | exp '^' exp        { $$ = pow ($1, $3); }
        | '(' exp ')'        { $$ = $2;         }
;
%%

/* Lexical analyzer returns a double floating point number on the
   stack and the token NUM, or the ASCII character read if not a
   number.  Skips all blanks and tabs, returns 0 for EOF. */

#include <ctype.h>

yylex ()
{
  int c;

  while ((c = getchar ()) == ' ' || c == '\t')  /* skip white space  */
    ;
  if (c == '.' || isdigit (c))                /* process numbers   */
    {
      ungetc (c, stdin);
      scanf ("%lf", &yylval);
      return NUM;
    }
  if (c == EOF)                            /* return end-of-file  */
    return 0;
  return c;                                /* return single chars */
}

#include <stdio.h>

main ()
{
  yyparse ();
}

yyerror (s)  /* Called by yyparse on error */
     char *s;
{
  printf ("%s\n", s);
}


Generated by GNU enscript 1.6.4.