Premier exercice
This commit is contained in:
commit
2f18fb4e70
|
@ -0,0 +1,5 @@
|
||||||
|
exclude-executables.sh
|
||||||
|
lexical/example
|
||||||
|
lexical/flux
|
||||||
|
lexical/string
|
||||||
|
*.c
|
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/sh
|
||||||
|
find . -perm /111 -type f | sed 's#^./##' | sort > .gitignore
|
||||||
|
echo "*.c" >> .gitignore
|
|
@ -0,0 +1,29 @@
|
||||||
|
%option noyywrap
|
||||||
|
|
||||||
|
%{
|
||||||
|
int lines = 1; // On compte la première ligne
|
||||||
|
%}
|
||||||
|
|
||||||
|
DIG [0-9]
|
||||||
|
HEX 0x[0-9A-Fa-f]+
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
{HEX} { printf("hex(%d)", strtol(yytext, NULL, 16)); }
|
||||||
|
{DIG}+ { printf("int(%d)", atoi(yytext)); }
|
||||||
|
"if" { printf("IF"); }
|
||||||
|
"then" { printf("THEN"); }
|
||||||
|
"else" { printf("ELSE"); }
|
||||||
|
\n { lines++; }
|
||||||
|
. { /* Pour tous les autres caractères, on ne fait rien */ }
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
int main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
if (argc > 1) yyin = fopen(argv[1], "r");
|
||||||
|
yylex();
|
||||||
|
puts("");
|
||||||
|
printf("%d lignes\n", lines);
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
%option noyywrap
|
||||||
|
|
||||||
|
%{
|
||||||
|
enum { T_INT = 1, T_CHAR = 2 };
|
||||||
|
union {
|
||||||
|
int i;
|
||||||
|
char c;
|
||||||
|
} data;
|
||||||
|
%}
|
||||||
|
|
||||||
|
DIG [0-9]
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
{DIG}+ { data.i = atoi(yytext); return T_INT; }
|
||||||
|
[+*()] { data.c = *yytext; return T_CHAR; }
|
||||||
|
[ \n] { /* ignore */ }
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
int main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
int token;
|
||||||
|
if (argc > 1) yyin = fopen(argv[1],"r");
|
||||||
|
while (token = yylex())
|
||||||
|
{
|
||||||
|
switch(token)
|
||||||
|
{
|
||||||
|
case T_INT: printf("int(%d) ",data.i); break;
|
||||||
|
case T_CHAR: printf("'%c' ",data.c); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
puts("");
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
%option noyywrap
|
||||||
|
|
||||||
|
DIG [0-9]
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
{DIG}+ { printf("int(%d) ",atoi(yytext)); }
|
||||||
|
[+*()] { printf("'%c' ",*yytext); }
|
||||||
|
[ \n] { /* ignore */ }
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
int main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
YY_BUFFER_STATE buffer;
|
||||||
|
|
||||||
|
buffer = yy_scan_string("100+5*2");
|
||||||
|
yylex();
|
||||||
|
yy_delete_buffer(buffer);
|
||||||
|
|
||||||
|
buffer = yy_scan_string("20+30");
|
||||||
|
yylex();
|
||||||
|
yy_delete_buffer(buffer);
|
||||||
|
|
||||||
|
puts("");
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
bool x,y,z;
|
||||||
|
|
||||||
|
while !(x && y && z) do
|
||||||
|
print x,y,z;
|
||||||
|
x := x ^ (y && z);
|
||||||
|
y := y ^ z;
|
||||||
|
z := !z
|
||||||
|
od
|
|
@ -0,0 +1,39 @@
|
||||||
|
%{
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int yylex();
|
||||||
|
|
||||||
|
void yyerror(char *s)
|
||||||
|
{
|
||||||
|
fflush(stdout);
|
||||||
|
fprintf(stderr, "%s\n", s);
|
||||||
|
}
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
%union {
|
||||||
|
int i;
|
||||||
|
}
|
||||||
|
|
||||||
|
%token <i> INT
|
||||||
|
%type <i> E
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
S : E { printf("result=%d\n",$1); }
|
||||||
|
|
||||||
|
E : E '*' E { $$ = $1*$3; }
|
||||||
|
| E '+' E { $$ = $1+$3; }
|
||||||
|
| '(' E ')' { $$ = $2; }
|
||||||
|
| INT
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
#include "exprlex.c"
|
||||||
|
|
||||||
|
int main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
if (argc > 1) yyin = fopen(argv[1],"r");
|
||||||
|
yyparse();
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
%option noyywrap
|
||||||
|
|
||||||
|
DIG [0-9]
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
{DIG}+ { yylval.i = atoi(yytext); return INT; }
|
||||||
|
[+*()] { return *yytext; }
|
||||||
|
[ \n] { /* ignore */ }
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
|
@ -0,0 +1,225 @@
|
||||||
|
%{
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
int yylex();
|
||||||
|
|
||||||
|
void yyerror(char *s)
|
||||||
|
{
|
||||||
|
fflush(stdout);
|
||||||
|
fprintf(stderr, "%s\n", s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* Data structures for storing a programme. */
|
||||||
|
|
||||||
|
typedef struct var // a variable
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
int value;
|
||||||
|
struct var *next;
|
||||||
|
} var;
|
||||||
|
|
||||||
|
typedef struct varlist // variable reference (used for print statement)
|
||||||
|
{
|
||||||
|
struct var *var;
|
||||||
|
struct varlist *next;
|
||||||
|
} varlist;
|
||||||
|
|
||||||
|
typedef struct expr // boolean expression
|
||||||
|
{
|
||||||
|
int type; // TRUE, FALSE, OR, AND, NOT, 0 (variable)
|
||||||
|
var *var;
|
||||||
|
struct expr *left, *right;
|
||||||
|
} expr;
|
||||||
|
|
||||||
|
typedef struct stmt // command
|
||||||
|
{
|
||||||
|
int type; // ASSIGN, ';', WHILE, PRINT
|
||||||
|
var *var;
|
||||||
|
expr *expr;
|
||||||
|
struct stmt *left, *right;
|
||||||
|
varlist *list;
|
||||||
|
} stmt;
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* All data pertaining to the programme are accessible from these two vars. */
|
||||||
|
|
||||||
|
var *program_vars;
|
||||||
|
stmt *program_stmts;
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* Functions for settting up data structures at parse time. */
|
||||||
|
|
||||||
|
var* make_ident (char *s)
|
||||||
|
{
|
||||||
|
var *v = malloc(sizeof(var));
|
||||||
|
v->name = s;
|
||||||
|
v->value = 0; // make variable false initially
|
||||||
|
v->next = NULL;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
var* find_ident (char *s)
|
||||||
|
{
|
||||||
|
var *v = program_vars;
|
||||||
|
while (v && strcmp(v->name,s)) v = v->next;
|
||||||
|
if (!v) { yyerror("undeclared variable"); exit(1); }
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
varlist* make_varlist (char *s)
|
||||||
|
{
|
||||||
|
var *v = find_ident(s);
|
||||||
|
varlist *l = malloc(sizeof(varlist));
|
||||||
|
l->var = v;
|
||||||
|
l->next = NULL;
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
expr* make_expr (int type, var *var, expr *left, expr *right)
|
||||||
|
{
|
||||||
|
expr *e = malloc(sizeof(expr));
|
||||||
|
e->type = type;
|
||||||
|
e->var = var;
|
||||||
|
e->left = left;
|
||||||
|
e->right = right;
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
stmt* make_stmt (int type, var *var, expr *expr,
|
||||||
|
stmt *left, stmt *right, varlist *list)
|
||||||
|
{
|
||||||
|
stmt *s = malloc(sizeof(stmt));
|
||||||
|
s->type = type;
|
||||||
|
s->var = var;
|
||||||
|
s->expr = expr;
|
||||||
|
s->left = left;
|
||||||
|
s->right = right;
|
||||||
|
s->list = list;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
/* types used by terminals and non-terminals */
|
||||||
|
|
||||||
|
%union {
|
||||||
|
char *i;
|
||||||
|
var *v;
|
||||||
|
varlist *l;
|
||||||
|
expr *e;
|
||||||
|
stmt *s;
|
||||||
|
}
|
||||||
|
|
||||||
|
%type <v> declist
|
||||||
|
%type <l> varlist
|
||||||
|
%type <e> expr
|
||||||
|
%type <s> stmt assign
|
||||||
|
|
||||||
|
%token BOOL WHILE DO OD ASSIGN PRINT OR AND XOR NOT TRUE FALSE
|
||||||
|
%token <i> IDENT
|
||||||
|
|
||||||
|
%left ';'
|
||||||
|
|
||||||
|
%left OR XOR
|
||||||
|
%left AND
|
||||||
|
%right NOT
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
prog : bools stmt { program_stmts = $2; }
|
||||||
|
|
||||||
|
bools : BOOL declist ';' { program_vars = $2; }
|
||||||
|
|
||||||
|
declist : IDENT { $$ = make_ident($1); }
|
||||||
|
| declist ',' IDENT { ($$ = make_ident($3))->next = $1; }
|
||||||
|
|
||||||
|
stmt : assign
|
||||||
|
| stmt ';' stmt
|
||||||
|
{ $$ = make_stmt(';',NULL,NULL,$1,$3,NULL); }
|
||||||
|
| WHILE expr DO stmt OD
|
||||||
|
{ $$ = make_stmt(WHILE,NULL,$2,$4,NULL,NULL); }
|
||||||
|
| PRINT varlist
|
||||||
|
{ $$ = make_stmt(PRINT,NULL,NULL,NULL,NULL,$2); }
|
||||||
|
|
||||||
|
assign : IDENT ASSIGN expr
|
||||||
|
{ $$ = make_stmt(ASSIGN,find_ident($1),$3,NULL,NULL,NULL); }
|
||||||
|
|
||||||
|
varlist : IDENT { $$ = make_varlist($1); }
|
||||||
|
| varlist ',' IDENT { ($$ = make_varlist($3))->next = $1; }
|
||||||
|
|
||||||
|
expr : IDENT { $$ = make_expr(0,find_ident($1),NULL,NULL); }
|
||||||
|
| expr XOR expr { $$ = make_expr(XOR,NULL,$1,$3); }
|
||||||
|
| expr OR expr { $$ = make_expr(OR,NULL,$1,$3); }
|
||||||
|
| expr AND expr { $$ = make_expr(AND,NULL,$1,$3); }
|
||||||
|
| NOT expr { $$ = make_expr(NOT,NULL,$2,NULL); }
|
||||||
|
| TRUE { $$ = make_expr(TRUE,NULL,NULL,NULL); }
|
||||||
|
| FALSE { $$ = make_expr(FALSE,NULL,NULL,NULL); }
|
||||||
|
| '(' expr ')' { $$ = $2; }
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
#include "langlex.c"
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* programme interpreter : */
|
||||||
|
|
||||||
|
int eval (expr *e)
|
||||||
|
{
|
||||||
|
switch (e->type)
|
||||||
|
{
|
||||||
|
case TRUE: return 1;
|
||||||
|
case FALSE: return 0;
|
||||||
|
case XOR: return eval(e->left) ^ eval(e->right);
|
||||||
|
case OR: return eval(e->left) || eval(e->right);
|
||||||
|
case AND: return eval(e->left) && eval(e->right);
|
||||||
|
case NOT: return !eval(e->left);
|
||||||
|
case 0: return e->var->value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_vars (varlist *l)
|
||||||
|
{
|
||||||
|
// Attention, varlist is in reverse order (this was easier to set up
|
||||||
|
// at parse time, see the code for varlist in the grammar).
|
||||||
|
|
||||||
|
if (!l) return;
|
||||||
|
print_vars(l->next);
|
||||||
|
printf("%s = %c ", l->var->name, l->var->value? 'T' : 'F');
|
||||||
|
}
|
||||||
|
|
||||||
|
void execute (stmt *s)
|
||||||
|
{
|
||||||
|
switch(s->type)
|
||||||
|
{
|
||||||
|
case ASSIGN:
|
||||||
|
s->var->value = eval(s->expr);
|
||||||
|
break;
|
||||||
|
case ';':
|
||||||
|
execute(s->left);
|
||||||
|
execute(s->right);
|
||||||
|
break;
|
||||||
|
case WHILE:
|
||||||
|
while (eval(s->expr)) execute(s->left);
|
||||||
|
break;
|
||||||
|
case PRINT:
|
||||||
|
print_vars(s->list);
|
||||||
|
puts("");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
int main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
if (argc <= 1) { yyerror("no file specified"); exit(1); }
|
||||||
|
yyin = fopen(argv[1],"r");
|
||||||
|
if (!yyparse()) execute(program_stmts);
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
%option noyywrap
|
||||||
|
|
||||||
|
DIG [0-9]
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
"bool" { return BOOL; }
|
||||||
|
"while" { return WHILE; }
|
||||||
|
"do" { return DO; }
|
||||||
|
"od" { return OD; }
|
||||||
|
"print" { return PRINT; }
|
||||||
|
"true" { return TRUE; }
|
||||||
|
"false" { return FALSE; }
|
||||||
|
|
||||||
|
":=" { return ASSIGN; }
|
||||||
|
"^" { return XOR; }
|
||||||
|
"||" { return OR; }
|
||||||
|
"&&" { return AND; }
|
||||||
|
"!" { return NOT; }
|
||||||
|
|
||||||
|
[a-z_][a-z0-9_]* { yylval.i = strdup(yytext); return IDENT; }
|
||||||
|
|
||||||
|
[ \n] { /* ignore */ }
|
||||||
|
|
||||||
|
. { return *yytext; }
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
Loading…
Reference in New Issue