Compare commits
	
		
			2 Commits
		
	
	
		
			a22bc69491
			...
			07fa61ef6c
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 07fa61ef6c | |||
| 102f08c2cf | 
| @ -15,3 +15,11 @@ afficher l; | |||||||
| # afficher x + 3, 3 + y; | # afficher x + 3, 3 + y; | ||||||
| # x = -x; | # x = -x; | ||||||
| # afficher x; | # afficher x; | ||||||
|  |  | ||||||
|  | # entier x = 2 + 3 * 4; | ||||||
|  | # entier y = 3 * 4 + 2; | ||||||
|  |  | ||||||
|  | liste l = [1, 2, 3]; | ||||||
|  |  | ||||||
|  | afficher l[2]; | ||||||
|  |  | ||||||
|  | |||||||
| @ -3,13 +3,13 @@ entier age = 23; | |||||||
| booléen majeur = vrai; | booléen majeur = vrai; | ||||||
|  |  | ||||||
| booléen ingénieur; | booléen ingénieur; | ||||||
|  |   | ||||||
| majeur = faux; | majeur = faux; | ||||||
|  |   | ||||||
| afficher nom, age, majeur; | afficher nom, age, majeur; | ||||||
|  |  | ||||||
|  |  | ||||||
| #Ces lignes devraient donner une erreur | # Ces lignes devraient donner une erreur | ||||||
| # majeur = 42; | # majeur = 42; | ||||||
|  |  | ||||||
| # afficher majeur; | # afficher majeur; | ||||||
|  | |||||||
| @ -14,11 +14,11 @@ class Variables: | |||||||
|         def __init__(self, typ, value = None): |         def __init__(self, typ, value = None): | ||||||
|             assert typ in self.types.keys(), "Ce type de variable est inconnu" |             assert typ in self.types.keys(), "Ce type de variable est inconnu" | ||||||
|             self.type = typ |             self.type = typ | ||||||
|             assert self.checkType(value, typ), "Le type n'est pas équivalent" |             assert self.checkType(value, typ), f"Le type n'est pas équivalent: { value } n'est pas {typ}" | ||||||
|             self.value = value if (value is not None) else self.default(typ) |             self.value = value if (value is not None) else self.default(typ) | ||||||
|  |  | ||||||
|         def set(self, value): |         def set(self, value): | ||||||
|             assert self.checkType(value, self.type), "Le type n'est pas équivalent" |             assert self.checkType(value, self.type), f"Le type n'est pas équivalent: {value} n'est pas {self.type}" | ||||||
|             self.value = value |             self.value = value | ||||||
|  |  | ||||||
|         def __str__(self): |         def __str__(self): | ||||||
| @ -61,7 +61,7 @@ class Variables: | |||||||
|             print(f"{trace_format}déclare {name} = {value}{reset_format}", file=sys.stderr) |             print(f"{trace_format}déclare {name} = {value}{reset_format}", file=sys.stderr) | ||||||
|  |  | ||||||
|     def assign(self, name, value): |     def assign(self, name, value): | ||||||
|         assert name in self.variables, f"la variable n'éxiste pas" |         assert name in self.variables, f"la variable {name} n'éxiste pas" | ||||||
|         self.variables[name].set(value) |         self.variables[name].set(value) | ||||||
|         if self.trace: |         if self.trace: | ||||||
|             print(f"{trace_format}modifie {name} = {value}{reset_format}", file=sys.stderr) |             print(f"{trace_format}modifie {name} = {value}{reset_format}", file=sys.stderr) | ||||||
|  | |||||||
							
								
								
									
										65
									
								
								spf.lark
									
									
									
									
									
								
							
							
						
						
									
										65
									
								
								spf.lark
									
									
									
									
									
								
							| @ -6,36 +6,41 @@ instruction: declaration ";" | |||||||
| 		   | ADD_KW expression "dans" VARIABLE ";" -> append | 		   | ADD_KW expression "dans" VARIABLE ";" -> append | ||||||
| 		   | controls | 		   | controls | ||||||
|  |  | ||||||
| expression: expressionleft // TODO: priorité des operator certainement fausse | // rule finishing by u are "UnambigiousED" | ||||||
|           | operator | expression: logical | ||||||
|  |  | ||||||
| expressionleft: literal  | logical: comparison logicalu? | ||||||
|               | list | logicalu: AND_OP logical | ||||||
|               | range |         | OR_OP logical | ||||||
| 			  | VARIABLE -> variable |  | ||||||
| 			  | "(" expression ")" |  | ||||||
|  |  | ||||||
| //any -> bool | comparison: sumterm comparisonu? | ||||||
| operator: expressionleft SAME_OP expression -> equal | comparisonu: SAME_OP comparison | ||||||
|   | expressionleft DIFF_OP expression -> unequal |            | DIFF_OP comparison | ||||||
| //bool -> bool |            | LT_OP comparison | ||||||
|   | expressionleft AND_OP expression -> and_op |            | LE_OP comparison | ||||||
|   | expressionleft OR_OP expression -> or_op |            | GT_OP comparison | ||||||
|   | NOT_OP expression -> not_op |            | GE_OP comparison | ||||||
| //int -> bool |  | ||||||
|   | expressionleft LT_OP expression -> lt | sumterm: multterm sumtermu? | ||||||
|   | expressionleft LE_OP expression -> le | sumtermu: PLUS_OP sumterm | ||||||
|   | expressionleft GT_OP expression -> gt |         | MINUS_OP sumterm | ||||||
|   | expressionleft GE_OP expression -> ge |  | ||||||
| //int -> int | multterm: priority multtermu? | ||||||
|   | expressionleft PLUS_OP expression -> plus | multtermu: TIMES_OP multterm | ||||||
|   | expressionleft MINUS_OP expression -> minus |          | DIVIDE_OP multterm | ||||||
|   | expressionleft TIMES_OP expression -> time |  | ||||||
|   | expressionleft DIVIDE_OP expression -> divide | priority: finalterm  | ||||||
|   | NEG_OP expression -> neg |         | finalterm "[" expression "]" -> list_get | ||||||
| // string/list -> string/list |         | SIZE_OP finalterm | ||||||
|   | SIZE_OP expression -> sizeof | 		| NEG_OP finalterm | ||||||
|   | expressionleft "[" expression "]" -> list_get | 		| NOT_OP finalterm | ||||||
|  |  | ||||||
|  |  | ||||||
|  | finalterm: "(" expression ")" | ||||||
|  |          | literal | ||||||
|  |          | list | ||||||
|  |          | range | ||||||
|  |          | VARIABLE -> variable | ||||||
|  |  | ||||||
| ?type: BOOL_TYPE | ?type: BOOL_TYPE | ||||||
|      | INT_TYPE  |      | INT_TYPE  | ||||||
| @ -64,7 +69,7 @@ test: "si" expression "alors" "{" instruction_seq "}" ("sinon" "{" instruction_s | |||||||
| instruction_seq: (instruction*) | instruction_seq: (instruction*) | ||||||
|  |  | ||||||
| ?booleen: TRUE_KW  -> true | ?booleen: TRUE_KW  -> true | ||||||
| 	   | FALSE_KW -> false | 	    | FALSE_KW -> false | ||||||
|  |  | ||||||
| TERMINAL: ";" | TERMINAL: ";" | ||||||
|  |  | ||||||
| @ -101,6 +106,8 @@ GE_OP: ">=" | |||||||
|  |  | ||||||
| CONC_OP: "+" | CONC_OP: "+" | ||||||
| SIZE_OP: "taille" | SIZE_OP: "taille" | ||||||
|  | LBRAC: "[" | ||||||
|  | RBRAC: "]" | ||||||
|  |  | ||||||
| ADD_KW: "ajouter" | ADD_KW: "ajouter" | ||||||
| SHOW_KW: "afficher" | SHOW_KW: "afficher" | ||||||
|  | |||||||
							
								
								
									
										188
									
								
								spf.py
									
									
									
									
									
								
							
							
						
						
									
										188
									
								
								spf.py
									
									
									
									
									
								
							| @ -52,72 +52,136 @@ class SPFInterpreter(lark.visitors.Interpreter): | |||||||
|         value = self.visit_children(el.children[2])[0] |         value = self.visit_children(el.children[2])[0] | ||||||
|         self.variables.assign(name, value) |         self.variables.assign(name, value) | ||||||
|  |  | ||||||
|     def equal(self, el): |     # def and_op(self, el): | ||||||
|         (left, sign, right) = self.visit_children(el) |     #     (left, sign, right) = self.visit_children(el) | ||||||
|         return left == right |     #     return left and right | ||||||
|  |     # | ||||||
|     def unequal(self, el): |     # def or_op(self, el): | ||||||
|         (left, sign, right) = self.visit_children(el) |     #     (left, sign, right) = self.visit_children(el) | ||||||
|         return left != right |     #     return left or right | ||||||
|  |     # | ||||||
|     def and_op(self, el): |     # | ||||||
|         (left, sign, right) = self.visit_children(el) |     # def equal(self, el): | ||||||
|         return left and right |     #     (left, sign, right) = self.visit_children(el) | ||||||
|  |     #     return left == right | ||||||
|     def or_op(self, el): |     # | ||||||
|         (left, sign, right) = self.visit_children(el) |     # def unequal(self, el): | ||||||
|         return left or right |     #     (left, sign, right) = self.visit_children(el) | ||||||
|  |     #     return left != right | ||||||
|     def not_op(self, el): |     # | ||||||
|         (sign, right) = self.visit_children(el) |     # def lt(self, el): | ||||||
|         return not right |     #     (left, sign, right) = self.visit_children(el) | ||||||
|  |     #     return left < right | ||||||
|     def lt(self, el): |     # | ||||||
|         (left, sign, right) = self.visit_children(el) |     # def le(self, el): | ||||||
|         return left < right |     #     (left, sign, right) = self.visit_children(el) | ||||||
|  |     #     return left <= right | ||||||
|     def le(self, el): |     # | ||||||
|         (left, sign, right) = self.visit_children(el) |     # def gt(self, el): | ||||||
|         return left <= right |     #     (left, sign, right) = self.visit_children(el) | ||||||
|  |     #     return left > right | ||||||
|     def gt(self, el): |     # | ||||||
|         (left, sign, right) = self.visit_children(el) |     # def ge(self, el): | ||||||
|         return left > right |     #     (left, sign, right) = self.visit_children(el) | ||||||
|  |     #     return left >= right | ||||||
|     def ge(self, el): |     # | ||||||
|         (left, sign, right) = self.visit_children(el) |     # | ||||||
|         return left >= right |     # def plus(self, el): | ||||||
|  |     #     (left, sign, right) = self.visit_children(el) | ||||||
|  |     #     return left + right # Cool ça fonctionne pour les str | ||||||
|     def plus(self, el): |     # | ||||||
|         (left, sign, right) = self.visit_children(el) |     # def minus(self, el): | ||||||
|         return left + right # Cool ça fonctionne pour les str |     #     (left, sign, right) = self.visit_children(el) | ||||||
|  |     #     return left - right | ||||||
|     def minus(self, el): |     # | ||||||
|         (left, sign, right) = self.visit_children(el) |     # def time(self, el): | ||||||
|         return left - right |     #     (left, sign, right) = self.visit_children(el) | ||||||
|  |     #     return left * right | ||||||
|     def time(self, el): |     # | ||||||
|         (left, sign, right) = self.visit_children(el) |     # def divide(self, el): | ||||||
|         return left * right |     #     (left, sign, right) = self.visit_children(el) | ||||||
|  |     #     return left / right | ||||||
|     def divide(self, el): |     # | ||||||
|         (left, sign, right) = self.visit_children(el) |     # sizeof = lambda self, el:len(self.visit_children(el)[1]) | ||||||
|         return left / right |     # neg = lambda self, el:-self.visit_children(el)[1] | ||||||
|  |     # | ||||||
|     neg = lambda self, el:-self.visit_children(el)[1] |     # def not_op(self, el): | ||||||
|  |     #     (sign, right) = self.visit_children(el) | ||||||
|     sizeof = lambda self, el:len(self.visit_children(el)[1]) |     #     return not right | ||||||
|  |     # | ||||||
|     def list_get(self, el): |     # | ||||||
|         (left, right) = self.visit_children(el) |     # def list_get(self, el): | ||||||
|         return left[right-1] |     #     (left, right) = self.visit_children(el) | ||||||
|  |     #     return left[right-1] | ||||||
|  |  | ||||||
|     def expression(self, el): |     def expression(self, el): | ||||||
|         return self.visit_children(el)[0] |         return self.visit_children(el)[0] | ||||||
|  |  | ||||||
|     def expressionleft(self, el): |     def logical(self, el): | ||||||
|  |         result = self.visit_children(el) | ||||||
|  |         if len(result) < 2: | ||||||
|  |             return result[0] | ||||||
|  |         if result[1][0].type == "AND_OP": | ||||||
|  |             return result[0] and result[1][1] | ||||||
|  |         elif result[1][0].type == "OR_OP": | ||||||
|  |             return result[0] or result[1][1] | ||||||
|  |         assert "Unreachable" | ||||||
|  |  | ||||||
|  |     def comparison(self, el): | ||||||
|  |         result = self.visit_children(el) | ||||||
|  |         if len(result) < 2: | ||||||
|  |             return result[0] | ||||||
|  |         if result[1][0].type == "SAME_OP": | ||||||
|  |             return result[0] == result[1][1] | ||||||
|  |         elif result[1][0].type == "DIFF_OP": | ||||||
|  |             return result[0] != result[1][1] | ||||||
|  |         elif result[1][0].type == "LT_OP": | ||||||
|  |             return result[0] < result[1][1] | ||||||
|  |         elif result[1][0].type == "LE_OP": | ||||||
|  |             return result[0] <= result[1][1] | ||||||
|  |         elif result[1][0].type == "GT_OP": | ||||||
|  |             return result[0] > result[1][1] | ||||||
|  |         elif result[1][0].type == "GE_OP": | ||||||
|  |             return result[0] >= result[1][1] | ||||||
|  |         assert "Unreachable" | ||||||
|  |  | ||||||
|  |     def sumterm(self, el): | ||||||
|  |         result = self.visit_children(el) | ||||||
|  |         if len(result) < 2: | ||||||
|  |             return result[0] | ||||||
|  |         if result[1][0].type == "PLUS_OP": | ||||||
|  |             return result[0] + result[1][1] | ||||||
|  |         elif result[1][0].type == "MINUS_OP": | ||||||
|  |             return result[0] - result[1][1] | ||||||
|  |         assert "Unreachable" | ||||||
|  |  | ||||||
|  |     def multterm(self, el): | ||||||
|  |         result = self.visit_children(el) | ||||||
|  |         if len(result) < 2: | ||||||
|  |             return result[0] | ||||||
|  |         if result[1][0].type == "TIMES_OP": | ||||||
|  |             return result[0] * result[1][1] | ||||||
|  |         elif result[1][0].type == "DIVIDE_OP": | ||||||
|  |             return result[0] / result[1][1] | ||||||
|  |         assert "Unreachable" | ||||||
|  |  | ||||||
|  |     def priority(self, el): | ||||||
|  |         result = self.visit_children(el) | ||||||
|  |         print(result) | ||||||
|  |         if len(result) < 2: | ||||||
|  |             return result[0] | ||||||
|  |         elif result[0].type == "SIZE_OP": | ||||||
|  |             return len(result[1]) | ||||||
|  |         elif result[0].type == "NEG_OP": | ||||||
|  |             return -result[1] | ||||||
|  |         elif result[0].type == "NOT_OP": | ||||||
|  |             return not result[1] | ||||||
|  |  | ||||||
|  |     def list_get(self, el): | ||||||
|  |         result = self.visit_children(el) | ||||||
|  |         return result[0][result[1] - 1] # Index start at 1 (like lua) | ||||||
|  |  | ||||||
|  |     def finalterm(self, el): | ||||||
|         return self.visit_children(el)[0] |         return self.visit_children(el)[0] | ||||||
|  |  | ||||||
|     def variable(self, el): |     def variable(self, el): | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	