Compilation
Corrigé du TP 1
# Le Makefile de la mini-cal
# Variables
CC = gcc
CFLAGS = -Wall -ansi -pedantic
# But principal
world : stack.o lex.yy.c cal.h
$(CC) $(OFLAGS) stack.o lex.yy.c -o mini-cal
# De '.lex' a '.c'
lex.yy.c : stack.h cal.h cal.lex
lex cal.lex
# Le menage
clean :
rm -f *.o *~
- Le module de gestion des piles
/* =========================================== */
/* MST 1, 98/99 -- Compilation */
/* Un module pour les piles d'entiers */
/* ------------------------------------------ */
/* Fichier : stack.h */
/* =========================================== */
#ifndef STACK_H
#define STACK_H
#define STACKSIZE 30
#define EMPTY_STACK_ERROR 10
typedef
struct stack_pair
{
int *sp;
int *sb;
}* stack;
stack new_stack();
void push(int, stack);
int top(stack);
void pop(stack);
#endif
/* =========================================== */
/* MST 1, 98/99 -- Compilation */
/* Un module pour les piles d'entiers */
/* ------------------------------------------ */
/* Fichier : stack.c */
/* =========================================== */
#include
#include
#include "stack.h"
stack new_stack()
{
stack s;
s = (stack)malloc(sizeof(struct stack_pair));
if (s==NULL)
{
perror("new_stack : out of memory");
return NULL;
}
/*printf("new s : %p\n", s);*/
s->sb = (int *)malloc(STACKSIZE*sizeof(int));
/*printf("new s->sb : %p\n", s->sb);*/
if (s->sb==NULL)
{
perror("new_stack : out of memory");
return NULL;
}
else
{
s->sp = s->sb;
/*printf("new : (s=%p), (s->sb=%p), (s->sp=%p)\n", s, s->sb, s->sp);*/
return s;
}
}
void push(int n, stack s)
{
/*printf("push s->sp : %p\n", s->sp);*/
*(++s->sp) = n;
/*printf("push s->sp : %p, *(s->sp) : %d \n", s->sp, *(s->sp));*/
}
int top(stack s)
{
if (s->sp>s->sb) return *(s->sp);
else
{
perror("Empty stack\n");
exit(EMPTY_STACK_ERROR);
}
}
void pop(stack s)
{
if (s->sp>s->sb) s->sp--;
else
{
perror("Empty stack\n");
exit(EMPTY_STACK_ERROR);
}
}
void print_stack(stack s)
{
int *p = s->sp;
while(p!=s->sb)
{
printf("(%d)", *(p--));
}
printf("\n");
}
/* =========================================== */
/* MST 1, 98/99 -- Compilation */
/* Une calculette a memoire */
/* ------------------------------------------ */
/* Fichier : cal.h */
/* =========================================== */
#include
/* Unites syntaxiques */
enum token
{ DOLLAR, DOT, EXMARK, NUM, OP, QMARK, VAR };
typedef enum token token;
/* Valeurs associees aux lexemes OP, NUM et VAR */
union lexical_values
{
char op;
int num;
char *var;
};
typedef union lexical_values lexical_values;
/* Etats de la calculettes */
enum states { EVALCMD, DISCMD, SKIP, STOCMD, WAIT };
typedef enum states states;
/* Les ressources */
#define MEMSIZE 10
states q;
int mem[MEMSIZE];
stack s;
/* =========================================== */
/* MST 1, 98/99 -- Compilation */
/* Une calculette a memoire */
/* ------------------------------------------ */
/* Fichier : cal.lex */
/* =========================================== */
%{
#include
#include "stack.h"
#include "cal.h"
void reduce(char op, stack s) {
int r1, r2;
r2 = top(s); pop(s);
r1 = top(s); pop(s);
switch(op) {
case '+' : push(r1+r2, s); break;
case '-' : push(r1-r2, s); break;
case '*' : push(r1*r2, s); break;
case '/' : push(r1/r2, s); break;
}
}
int var_index(char *v) {
return v[1]-'0';
}
%}
%option noyywrap
%%
[ \n\t] { ; }
"." { switch (q) {
case WAIT : exit(0);
case EVALCMD : mem[0] = top(s); printf("= %d\n", mem[0]);
default : q = WAIT; printf("# ");
}
}
"?" { switch(q) {
case WAIT : q=EVALCMD; break;
case SKIP : break;
default : perror("Illegal input\n"); q=SKIP;
}
}
"!" { switch(q) {
case WAIT : q=STOCMD; break;
case SKIP : break;
default : perror("Illegal input\n"); q=SKIP;
}
}
"$" { switch(q) {
case WAIT : q=DISCMD; break;
case SKIP : break;
default : perror("Illegal input\n"); q=SKIP;
}
}
[\+\*\-\/] { switch(q) {
case EVALCMD : reduce(yytext[0], s); break;
case SKIP : break;
default : perror("Illegal input\n"); q=SKIP;
}
}
[0-9]+ { switch(q) {
case EVALCMD : push(atoi(yytext),s); break;
case SKIP : break;
default : perror("Illegal input\n"); q=SKIP;
}
}
v[1-9] { switch(q) {
case DISCMD : printf("= %d\n", mem[var_index(yytext)]); break;
case EVALCMD : push(mem[var_index(yytext)], s); break;
case STOCMD :
printf("%s <- %d\n", yytext, mem[0]);
mem[var_index(yytext)] = mem[0]; break;
case WAIT : perror("Illegal input\n"); q=SKIP; break;
}
}
. { if (q!=SKIP) {
perror("Illegal input\n"); q = SKIP;
}
else printf("");
}
%%
void main()
{
s = new_stack();
q = WAIT;
yyin = stdin;
printf(" -- Welcome to the mini-cal\n");
printf(" Type in either :\n");
printf(" - a display command : $.\n");
printf(" - a store command : !.\n");
printf(" - a compute command : ?.\n");
printf(" - a quit command : .\n");
printf("# ");
yylex();
}