[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Flex-Bison track sample
From: |
Hans Aberg |
Subject: |
Re: Flex-Bison track sample |
Date: |
Sun, 3 Dec 2000 12:17:36 +0100 |
At 17:23 +0300 0-12-02, Vladimir Rykov wrote:
>So - how [might] all the commands for Flex - Bison - GCC (I mean their
>command >line options) to start them and get together the results will
>look for a simple
>case?
A simple example for use with C is given in the book by Aho, Sethi & Ullman
"Compilers...". I will give my version of it (below).
-- I cannot be positively sure you get a working version as it stands, but
it should be possible to make it working.
There are two styles of using Flex & Bison together, one (traditional)
where the Flex .c output file is included in the Bison .c output file, and
one (better C style), where they share a common header. The version below
is the latter form, even though it has a "#if .." directive which could be
used if one wants to use the traditional style.
I also have a simple examples that I made for Flex and Bison output
compiled using C++ (Both without and with Bison source code tweaks). --
Perhaps another post, if somebody is interested.
-- File LexCalc.h -----------------------------------------------------
#ifndef LexCalc_h
#define LexCalc_h
#include <math.h>
typedef union calc_type {
double value;
char* name;
int length;
} calc_type;
#define YYSTYPE calc_type
#endif
-- File LexCalc.l, Compile using flex -Pcalc_ -a ---------------------------
#include "LexCalc.h"
#define yylval calc_lval
#include "LexCalc.tab.h"
%}
%option noyywrap
digit [0-9]
number {digit}+\.?|{digit}*\.{digit}+
identifier [a-zA-Z]+
%%
[ ] { /* Skip blanks. */ }
{number} { sscanf(yytext, "%lf", &yylval.value);
return NUMBER; }
"exit" { return EXIT; }
{identifier} { yylval.name = yytext; yylval.length = yyleng; return
IDENTIFIER; }
\n|. { return yytext[0]; }
%%
-- File LexCalc.y, Compile using bison --defines --name-prefix=calc_ --------
%{
/* From Aho, Seti, Ullman, fig. 4.59, p. 266. */
#include "LexCalc.h"
%}
%token NUMBER
%token IDENTIFIER
%token EXIT
%left '+' '-'
%left '*' '/'
%right '^'
%right IDENTIFIER
%right UMINUS
%%
lines: lines expr '\n' { printf("%.12g\n", $2.value) }
| lines '\n'
| lines EXIT '\n' { return EXIT_SUCCESS; }
| /* empty */
| error '\n' { printf("Please re-enter last
line: ");
yyerrok; }
;
expr: expr '+' expr { $$.value = $1.value + $3.value }
| expr '-' expr { $$.value = $1.value - $3.value }
| expr '*' expr { $$.value = $1.value * $3.value }
| expr '/' expr { $$.value = $1.value / $3.value }
| expr '^' expr { $$.value = pow($1.value, $3.value) }
| '(' expr ')' { $$.value = $2.value }
| '-' expr %prec UMINUS { $$.value = -$2.value }
| IDENTIFIER expr { $$.value = sqrt($2.value) }
| NUMBER
;
%%
#include <ctype.h>
#include <stdio.h>
#if 0
#include "lex.calc_.c"
#endif
#if __MWERKS__ && macintosh
#include <SIOUX.h>
#endif
int main() {
#if __MWERKS__ && macintosh
SIOUXSettings.asktosaveonclose = 0;
SIOUXSettings.autocloseonquit = 1;
#endif
return yyparse();
}
int yyerror(char* errstr) {
printf("Error: %s\n", errstr);
return EXIT_FAILURE;
}
-- File MoreAdvancedCalc.y, Compile using bison --defines --name-prefix=calc_
%{
/* From Aho, Seti, Ullman, fig. 4.56, p. 259. */
#include <math.h>
#define YYSTYPE double
%}
%token NUMBER
%left '+' '-'
%left '*' '/'
%right '^'
%right UMINUS
%%
lines: lines expr '\n' { printf("%.12g\n", $2) }
| lines '\n'
| /* empty */
;
expr: expr '+' expr { $$ = $1 + $3 }
| expr '-' expr { $$ = $1 - $3 }
| expr '*' expr { $$ = $1 * $3 }
| expr '/' expr { $$ = $1 / $3 }
| expr '^' expr { $$ = pow($1, $3) }
| '(' expr ')' { $$ = $2 }
| '-' expr %prec UMINUS { $$ = -$2 }
| NUMBER
;
%%
#include <ctype.h>
#include <stdio.h>
yylex() {
int c;
while ((c = getc(stdin)) == ' ')
;
if ((c == '.') || isdigit(c)) {
ungetc(c, stdin);
scanf("%lf", &yylval);
return NUMBER;
}
return c;
}
#if __MWERKS__ && macintosh
#include <SIOUX.h>
#endif
int main() {
#if __MWERKS__ && macintosh
SIOUXSettings.asktosaveonclose = 0;
SIOUXSettings.autocloseonquit = 0;
#endif
return yyparse();
}
int yyerror(char* errstr) {
printf("Error: %s\n", errstr);
printf("(Exit)\n");
exit(EXIT_FAILURE);
return EXIT_SUCCESS;
}
--------------------------------------------------------------------------