Fin du readme
This commit is contained in:
		
							
								
								
									
										49
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										49
									
								
								README.md
									
									
									
									
									
								
							@@ -12,7 +12,7 @@ geometry:
 | 
			
		||||
 | 
			
		||||
# Analyse lexicale
 | 
			
		||||
 | 
			
		||||
Le fichier `example.l` peut se compiler en un analyseur lexical `example` en appelant simplement la commande `make`. Il permet à partir d'une entrée textuelle (un fichier, le TTY ou l'entrée standard suivie d'un Ctrl+D) de filter les nombres et de les afficher, sous forme décimale ou hexadécimale. De plus, les mots clés `if`, `then` et `else` sont réécrits en majsucule. Tout le reste est ignoré.
 | 
			
		||||
Le fichier `example.l` peut se compiler en un analyseur lexical `example` en appelant simplement la commande `make example`. Il permet à partir d'une entrée textuelle (un fichier, le TTY ou l'entrée standard suivie d'un Ctrl+D) de filter les nombres et de les afficher, sous forme décimale ou hexadécimale. De plus, les mots clés `if`, `then` et `else` sont réécrits en majsucule. Tout le reste est ignoré.
 | 
			
		||||
 | 
			
		||||
Un entier `n` affichera sur la sortie `int(n)`, un entier `0xh` écrit en hexadécimal affichera dans la sortie `hex(n)` où `n` est la représentation décimale de `0xh`.
 | 
			
		||||
 | 
			
		||||
@@ -34,6 +34,51 @@ else
 | 
			
		||||
Le programme va renvoyer la sortie suivante :
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
int(1)IFTHENint(1)int(20)int(20)int(100)int(3)ELSEhex(16777215)int(10)int(12)int(42)int(13)int(7832)
 | 
			
		||||
int(1)IFTHENint(1)int(20)int(20)int(100)int(3)ELSEhex(16777215)int(10)int(12)int(42)int(14)int(7832)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Analyse syntaxique
 | 
			
		||||
 | 
			
		||||
Le programme `lang`, après compilation en appelant successivement `make langlex.c` et `make lang`, se comporte comme un interpréteur d'un langage de programmation fait à la main. L'extension attribuée est le `*.my`, même si cela n'est pas obligatoire.
 | 
			
		||||
 | 
			
		||||
Un programme est composé de trois parties :
 | 
			
		||||
 | 
			
		||||
* La déclaration des variables booléennes (faculatif). Cela se fait en écrivant `bool` suivi de la liste des variables booléennes à déclarer séparées par des virgules. La déclaration doit se finir par un point-virgule. Par exemple, on notera `bool x, y, z;` pour déclarer les variables booléenes `x`, `y` et `z`.
 | 
			
		||||
 | 
			
		||||
* De la même manière, on notera `int a, b, c;` pour déclarer les variables entières `a`, `b` et `c` (facultatif). La déclaration des variables entières doit se faire après la déclaration des variables booléennes s'il y en a.
 | 
			
		||||
 | 
			
		||||
* Enfin, le code. Le code est une succession d'instructions séparées par des point-virgules. Il existe 4 types d'instructions :
 | 
			
		||||
	* L'affectation, de la forme `x := expr` où `x` est une variable déclarée et `expr` une expression du même type que `x`.
 | 
			
		||||
	* Un test conditionnel, de la forme `if cond then stmt1 else stmt2` où `cond` est une expression booléenne et `stmt1` et `stmt2` deux blocs d'instructions. L'interprétation est naturelle : si la condition `cond` vaut `true`, on exécute le bloc `stmt1`, sinon on évalue le bloc `stmt2`. La partie `else stmt2` est facultative. Le problème du `dangling else` est résolu de la même manière qu'en C : le premier `else` porte sur le premier `if`.
 | 
			
		||||
	* Une boucle de la forme `while cond do stmt od` où `cond` est une expression booléenne et `stmt` une suite d'instructions. L'expression `cond` sera évaluée à chaque passage de boucle, et on reste dans la boucle tant que que la condition vaut `true`.
 | 
			
		||||
	* Un affichage des variables. Le code doit être de la forme `print list` où `list` est la liste des variables à afficher, séparées par des virgules. La fonction fonctionne à la fois avec des variables booléennes et des variables entières.
 | 
			
		||||
 | 
			
		||||
Une expression peut être de différentes formes. Chaque type d'expression est associée à une "classe" : booléen ou entier, ou les deux.
 | 
			
		||||
 | 
			
		||||
* La valeur d'une variable (du type de la variable)
 | 
			
		||||
* Un ou exclusif de deux expressions booléennes (renvoie un booléen)
 | 
			
		||||
* La disjonction de deux expressions booléennes (renvoie un booléen)
 | 
			
		||||
* La conjection de deux expressions booléennes (renvoie un booléen)
 | 
			
		||||
* L'équivalence deux expressions booléennes (renvoie un booléen)
 | 
			
		||||
* Une négation d'une expression booléenne (renvoie un booléen)
 | 
			
		||||
* `true` (booléen pour dire vrai)
 | 
			
		||||
* `false` (booléen pour dire faux)
 | 
			
		||||
* Une expression entre parenthèse (du type de ce qui est entre parenthèses)
 | 
			
		||||
* La somme de deux expressions entières (renvoie un entier)
 | 
			
		||||
* Le produit de deux expressions entières (renvoie un entier)
 | 
			
		||||
* La comparaison par inégalité stricte entre deux expression entières (renvoie un booléen)
 | 
			
		||||
* L'égalité entre deux expressions entières (renvoie un booléen)
 | 
			
		||||
 | 
			
		||||
Les priorités opérations sont les mêmes qu'en C :
 | 
			
		||||
 | 
			
		||||
1. La négation booléenne
 | 
			
		||||
2. La mutliplication entière
 | 
			
		||||
3. L'addition entière
 | 
			
		||||
4. L'inégalité stricte entre entiers
 | 
			
		||||
5. L'égalité entière
 | 
			
		||||
6. L'équivalence booléenne
 | 
			
		||||
7. La conjonction
 | 
			
		||||
8. La disjonction (éventuellement exclusive)
 | 
			
		||||
 | 
			
		||||
Lors de l'évaluation des expressions, les types sont correctement vérifiés.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								README.pdf
									
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								README.pdf
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							@@ -108,6 +108,8 @@ expr* make_expr (int type, int class, var *var, expr *left, expr *right)
 | 
			
		||||
	expr *e = malloc(sizeof(expr));
 | 
			
		||||
	e->type = type;
 | 
			
		||||
	e->class = class;
 | 
			
		||||
	if (var != NULL)
 | 
			
		||||
		e->class = var->class;
 | 
			
		||||
	e->var = var;
 | 
			
		||||
	e->left = left;
 | 
			
		||||
	e->right = right;
 | 
			
		||||
@@ -230,28 +232,28 @@ int eval (expr *e)
 | 
			
		||||
		case FALSE: return 0;
 | 
			
		||||
		case XOR: {
 | 
			
		||||
			if (e->left->class != 0 || e->right->class != 0) {
 | 
			
		||||
				yyerror("An expression has wrong types");
 | 
			
		||||
				yyerror("A xor expression has wrong types");
 | 
			
		||||
				exit(-1);
 | 
			
		||||
			}
 | 
			
		||||
			return eval(e->left) ^ eval(e->right);
 | 
			
		||||
		}
 | 
			
		||||
		case OR: {
 | 
			
		||||
			if (e->left->class != 0 || e->right != NULL && e->right->class != 0) {
 | 
			
		||||
				yyerror("An expression has wrong types");
 | 
			
		||||
				yyerror("An or expression has wrong types");
 | 
			
		||||
				exit(-1);
 | 
			
		||||
			}
 | 
			
		||||
			return eval(e->left) || eval(e->right);
 | 
			
		||||
		}
 | 
			
		||||
		case AND: {
 | 
			
		||||
			if (e->left->class != 0 || e->right->class != 0) {
 | 
			
		||||
				yyerror("An expression has wrong types");
 | 
			
		||||
				yyerror("An and expression has wrong types");
 | 
			
		||||
				exit(-1);
 | 
			
		||||
			}
 | 
			
		||||
			return eval(e->left) && eval(e->right);
 | 
			
		||||
		}
 | 
			
		||||
		case EQUIV: {
 | 
			
		||||
			if (e->left->class != 0 || e->right->class != 0) {
 | 
			
		||||
				yyerror("An expression has wrong types");
 | 
			
		||||
				yyerror("An equivalence expression has wrong types");
 | 
			
		||||
				exit(-1);
 | 
			
		||||
			}
 | 
			
		||||
			int right = eval(e->right);
 | 
			
		||||
@@ -261,28 +263,28 @@ int eval (expr *e)
 | 
			
		||||
		}
 | 
			
		||||
		case NOT: {
 | 
			
		||||
			if (e->left->class != 0) {
 | 
			
		||||
				yyerror("An expression has wrong types");
 | 
			
		||||
				yyerror("A not expression has wrong types");
 | 
			
		||||
				exit(-1);
 | 
			
		||||
			}
 | 
			
		||||
			return !eval(e->left);
 | 
			
		||||
		}
 | 
			
		||||
		case PLUS: {
 | 
			
		||||
			if (e->left->class != 1 || e->right->class != 1) {
 | 
			
		||||
				yyerror("An expression has wrong types");
 | 
			
		||||
				yyerror("A plus expression has wrong types");
 | 
			
		||||
				exit(-1);
 | 
			
		||||
			}
 | 
			
		||||
			return eval(e->left) + eval(e->right);
 | 
			
		||||
		}
 | 
			
		||||
		case TIMES: {
 | 
			
		||||
			if (e->left->class != 1 || e->right->class != 1) {
 | 
			
		||||
				yyerror("An expression has wrong types");
 | 
			
		||||
				yyerror("A times expression has wrong types");
 | 
			
		||||
				exit(-1);
 | 
			
		||||
			}
 | 
			
		||||
			return eval(e->left) * eval(e->right);
 | 
			
		||||
		}
 | 
			
		||||
		case EQUALS: {
 | 
			
		||||
			if (e->left->class != 1 || e->right->class != 1) {
 | 
			
		||||
				yyerror("An expression has wrong types");
 | 
			
		||||
				yyerror("An equality expression has wrong types");
 | 
			
		||||
				exit(-1);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
@@ -291,7 +293,7 @@ int eval (expr *e)
 | 
			
		||||
		}
 | 
			
		||||
		case LT: {
 | 
			
		||||
			if (e->left->class != 1 || e->right->class != 1) {
 | 
			
		||||
				yyerror("An expression has wrong types");
 | 
			
		||||
				yyerror("A comparison expression has wrong types");
 | 
			
		||||
				exit(-1);
 | 
			
		||||
			}
 | 
			
		||||
			return eval(e->left) < eval(e->right) ? 1 : 0;
 | 
			
		||||
@@ -332,15 +334,26 @@ void execute (stmt *s)
 | 
			
		||||
			execute(s->left);
 | 
			
		||||
			execute(s->right);
 | 
			
		||||
			break;
 | 
			
		||||
		case WHILE:
 | 
			
		||||
		case WHILE: {
 | 
			
		||||
			if (s->expr->class != 0 && s->expr->class != 2) {
 | 
			
		||||
				yyerror("A while condition must be a boolean expression");
 | 
			
		||||
				exit(-1);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			while (eval(s->expr)) execute(s->left);
 | 
			
		||||
			break;
 | 
			
		||||
		case IF:
 | 
			
		||||
		}
 | 
			
		||||
		case IF: {
 | 
			
		||||
			if (s->expr->class != 0 && s->expr->class != 2) {
 | 
			
		||||
				yyerror("An if condition must be a boolean expression");
 | 
			
		||||
				exit(-1);
 | 
			
		||||
			}
 | 
			
		||||
			if (eval(s->expr))
 | 
			
		||||
				execute(s->left);
 | 
			
		||||
			else if (s->right != NULL)
 | 
			
		||||
				execute(s->right);
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		case PRINT: 
 | 
			
		||||
			print_vars(s->list);
 | 
			
		||||
			puts("");
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user