Commit 404fe621 authored by bbguimaraes's avatar bbguimaraes
Browse files

flex & bison: chapter 1

parent df4b05f7
SUBDIRS = calc0 calc1 calc2 calc3 calc4 ex1 ex2 ex3 ex4 ex6 wc
.PHONY: all clean
all:
for x in $(SUBDIRS); do $(MAKE) -C "$$x"; done
clean:
for x in $(SUBDIRS); do $(MAKE) -C "$$x" clean; done
BIN = calc
LDLIBS = -lfl
.PHONY: all clean
all: $(BIN)
clean:
rm -f $(BIN)
%%
"+" { puts("PLUS"); }
"-" { puts("MINUS"); }
"*" { puts("TIMES"); }
"/" { puts("DIVIDE"); }
"|" { puts("ABS"); }
[0-9]+ { printf("NUMBER %s\n", yytext); }
\n { puts("NEWLINE"); }
[ \t] {}
. { printf("Mystery character %c\n", *yytext); }
%%
../calc0/Makefile
\ No newline at end of file
%{
enum yytokentype {
NUMBER = 258,
ADD = 259,
SUB = 260,
MUL = 261,
DIV = 262,
ABS = 263,
EOL = 264,
};
int yylval;
%}
%%
"+" { return ADD; }
"-" { return SUB; }
"*" { return MUL; }
"/" { return DIV; }
"|" { return ABS; }
[0-9]+ { yylval = atoi(yytext); return NUMBER; }
\n { return EOL; }
[ \t] {}
. { printf("Mystery character %c\n", *yytext); }
%%
int main(void) {
int tok;
while(tok = yylex()) {
printf("%d", tok);
if(tok == NUMBER)
printf(" = %d\n", yylval);
else
putchar('\n');
}
}
BIN = calc
LDLIBS = -lfl
%.tab.c %.tab.h: %.y
bison -d $<
.PHONY: all clean
all: $(BIN)
lex.c: calc.tab.h
calc: lex.c
clean:
rm -f $(BIN) calc.tab.[hc] lex.c
%{
#include <stdio.h>
%}
%token NUMBER
%token ADD SUB MUL DIV ABS
%token EOL
%%
calclist:
| calclist exp EOL { printf("= %d\n", $2); }
;
exp: factor
| exp ADD factor { $$ = $1 + $3; }
| exp SUB factor { $$ = $1 - $3; }
;
factor: term
| factor MUL term { $$ = $1 * $3; }
| factor DIV term { $$ = $1 / $3; }
;
term: NUMBER
| ABS term { $$ = $2 >= 0 ? $2 : -$2; }
;
%%
int main(void) {
yyparse();
}
int yyerror(char *s) {
fprintf(stderr, "%s: %s\n", __func__, s);
}
%{
#include "calc.tab.h"
%}
%%
"+" { return ADD; }
"-" { return SUB; }
"*" { return MUL; }
"/" { return DIV; }
"|" { return ABS; }
[0-9]+ { yylval = atoi(yytext); return NUMBER; }
\n { return EOL; }
[ \t] {}
. { printf("Mystery character %c\n", *yytext); }
%%
../calc2/Makefile
\ No newline at end of file
%{
#include <stdio.h>
%}
%token NUMBER
%token ADD SUB MUL DIV ABS
%token OP CP
%token EOL
%%
calclist:
| calclist exp EOL { printf("= %d\n", $2); }
;
exp: factor
| exp ADD factor { $$ = $1 + $3; }
| exp SUB factor { $$ = $1 - $3; }
;
factor: term
| factor MUL term { $$ = $1 * $3; }
| factor DIV term { $$ = $1 / $3; }
;
term: NUMBER
| ABS term { $$ = $2 >= 0 ? $2 : -$2; }
| OP exp CP { $$ = $2; }
;
%%
int main(void) {
yyparse();
}
int yyerror(char *s) {
fprintf(stderr, "%s: %s\n", __func__, s);
}
%{
#include "calc.tab.h"
%}
%%
"+" { return ADD; }
"-" { return SUB; }
"*" { return MUL; }
"/" { return DIV; }
"|" { return ABS; }
"(" { return OP; }
")" { return CP; }
[0-9]+ { yylval = atoi(yytext); return NUMBER; }
"//".*
\n { return EOL; }
[ \t] {}
. { printf("Mystery character %c\n", *yytext); }
%%
BIN = calc
LDLIBS = -lfl
%.tab.c %.tab.h: %.y
bison -d $<
.PHONY: all clean
all: $(BIN)
lex.c: calc.tab.h
calc: lex.c
clean:
rm -f $(BIN) calc.tab.[hc]
../calc3/calc.y
\ No newline at end of file
#include <ctype.h>
#include <stdio.h>
#include "calc.tab.h"
FILE *yyin;
static int seen_eof = 0;
int yylex(void) {
if(!yyin)
yyin = stdin;
if(seen_eof)
return 0;
for(;;) {
int c = getc(yyin);
if(isdigit(c)) {
int i = c - '0';
while(isdigit(c = getc(yyin)))
i = (10 * i) + c - '0';
yylval = i;
if(c == EOF)
seen_eof = 1;
else
ungetc(c, yyin);
return NUMBER;
}
switch(c) {
case '+': return ADD;
case '-': return SUB;
case '*': return MUL;
case '|': return ABS;
case '(': return OP;
case ')': return CP;
case '\n': return EOL;
case ' ':
case '\t': break;
case EOF: return 0;
case '/':
if((c = getc(yyin)) == '/') {
while((c = getc(yyin)) != '\n')
if(c == EOF)
return 0;
break;
}
if(c == EOF)
seen_eof = 1;
else
ungetc(c, yyin);
return DIV;
default: {
char s[] = "Mystery character x\n";
sprintf(s + sizeof("Mystery character"), "%c", c);
yyerror(s);
break;
}
}
}
}
../calc2/Makefile
\ No newline at end of file
%{
#include <stdio.h>
%}
%token NUMBER
%token ADD SUB MUL DIV ABS
%token OP CP
%token EOL
%%
calclist:
| calclist exp EOL { printf("= %d\n", $2); }
| EOL
;
exp: factor
| exp ADD factor { $$ = $1 + $3; }
| exp SUB factor { $$ = $1 - $3; }
;
factor: term
| factor MUL term { $$ = $1 * $3; }
| factor DIV term { $$ = $1 / $3; }
;
term: NUMBER
| ABS term { $$ = $2 >= 0 ? $2 : -$2; }
| OP exp CP { $$ = $2; }
;
%%
int main(void) {
yyparse();
}
int yyerror(char *s) {
fprintf(stderr, "%s: %s\n", __func__, s);
}
../calc3/lex.l
\ No newline at end of file
../calc2/Makefile
\ No newline at end of file
%{
#include <stdio.h>
%}
%token NUMBER
%token ADD SUB MUL DIV ABS
%token OP CP
%token EOL
%%
calclist:
| calclist exp EOL { printf("= %1$d 0x%1$x\n", $2); }
| EOL
;
exp: factor
| exp ADD factor { $$ = $1 + $3; }
| exp SUB factor { $$ = $1 - $3; }
;
factor: term
| factor MUL term { $$ = $1 * $3; }
| factor DIV term { $$ = $1 / $3; }
;
term: NUMBER
| ABS term { $$ = $2 >= 0 ? $2 : -$2; }
| OP exp CP { $$ = $2; }
;
%%
int main(void) {
yyparse();
}
int yyerror(char *s) {
fprintf(stderr, "%s: %s\n", __func__, s);
}
%{
#include "calc.tab.h"
%}
%%
"+" { return ADD; }
"-" { return SUB; }
"*" { return MUL; }
"/" { return DIV; }
"|" { return ABS; }
"(" { return OP; }
")" { return CP; }
[0-9]+ { yylval = atoi(yytext); return NUMBER; }
0x[0-9]+ { yylval = strtol(yytext, NULL, 16); return NUMBER; }
"//".*
\n { return EOL; }
[ \t] {}
. { printf("Mystery character %c\n", *yytext); }
%%
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment