Déclaration et affichage
This commit is contained in:
		| @ -1,8 +1,13 @@ | ||||
| entier pi = 314; | ||||
| entier pi2 = 3; | ||||
| texte nom = "anthony"; | ||||
| entier age = 23; | ||||
| booléen majeur = vrai; | ||||
|  | ||||
| pi = 3; | ||||
| majeur = faux; | ||||
|  | ||||
| tant que pi vaut pi2 faire { | ||||
| 	afficher "bonjour"; | ||||
| } | ||||
| afficher nom, age, majeur; | ||||
|  | ||||
|  | ||||
| #TODO: Ces lignes devraient donner une erreur | ||||
| majeur = 42; | ||||
|  | ||||
| afficher majeur; | ||||
|  | ||||
							
								
								
									
										64
									
								
								spf.lark
									
									
									
									
									
								
							
							
						
						
									
										64
									
								
								spf.lark
									
									
									
									
									
								
							| @ -1,66 +1,66 @@ | ||||
| start: (instruction)* | ||||
|  | ||||
| instruction: type declaration TERMINAL | ||||
| 		   | assignation TERMINAL | ||||
| instruction: declaration ";" | ||||
| 		   | assignation ";" | ||||
| 		   | SHOW_KW expression ("," expression)* ";" -> afficher | ||||
| 		   | ADD_KW expression "dans" VARIABLE ";" | ||||
| 		   | controls | ||||
| 		   | SHOW_KW expression ("," expression)* TERMINAL | ||||
| 		   | ADD_KW expression "dans" VARIABLE TERMINAL | ||||
|  | ||||
| expression: expressionleft // TODO: priorité des op certainement fausse | ||||
|           | op | ||||
| expression: expressionleft // TODO: priorité des operator certainement fausse | ||||
|           | operator | ||||
|  | ||||
| expressionleft: literal  | ||||
|               | list | ||||
|               | range | ||||
| 			  | VARIABLE | ||||
| 			  | VARIABLE -> variable | ||||
| 			  | "(" expression ")" | ||||
|  | ||||
| op: expressionleft SAME_OP expression | ||||
| //any -> bool | ||||
| operator: expressionleft SAME_OP expression | ||||
|   | expressionleft DIFF_OP expression | ||||
| //bool -> bool | ||||
|   | expressionleft AND_OP expression | ||||
|   | expressionleft OR_OP expression | ||||
|   | NOT_OP expression | ||||
| //int -> bool | ||||
|   | expressionleft LT_OP expression | ||||
|   | expressionleft LE_OP expression | ||||
|   | expressionleft GT_OP expression | ||||
|   | expressionleft GE_OP expression | ||||
|   | expressionleft operator expression | ||||
| //int -> int | ||||
|   | expressionleft PLUS_OP expression | ||||
|   | expressionleft MINUS_OP expression | ||||
|   | expressionleft TIMES_OP expression | ||||
|   | expressionleft DIVIDE_OP expression | ||||
|   | NEG_OP expression | ||||
| // string/list -> string/list | ||||
|   | expressionleft CONC_OP expression | ||||
|   | expressionleft ("[" expression "]" | range) | ||||
|   | SIZE_OP expression | ||||
|   | "(" expression ")" | ||||
|  | ||||
| type: BOOL_TYPE | ||||
| 	| INT_TYPE  | ||||
| 	| STR_TYPE | ||||
| 	| LIST_TYPE | ||||
| ?type: BOOL_TYPE | ||||
|      | INT_TYPE  | ||||
|      | STR_TYPE | ||||
|      | LIST_TYPE | ||||
|  | ||||
| declaration: VARIABLE (EQUAL_SIGN expression)? | ||||
| declaration: type VARIABLE (EQUAL_SIGN expression)? | ||||
|  | ||||
| assignation: VARIABLE EQUAL_SIGN expression | ||||
|  | ||||
| loop: "tant" "que" expression "faire" "{" (instruction)* "}" | ||||
|     | "pour" "chaque" type VARIABLE "dans" expression "faire" "{" (instruction)* "}" | ||||
| loop: /tant que/ expression "faire" "{" (instruction)* "}" | ||||
|     | /pour chaque/ type VARIABLE "dans" expression "faire" "{" (instruction)* "}" | ||||
|  | ||||
| literal: ENTIER | ||||
| ?literal: ENTIER -> entier | ||||
| 	   | booleen  | ||||
| 	   | ESCAPED_STRING | ||||
| 	   | ESCAPED_STRING -> string | ||||
|  | ||||
| list: "[" expression? ("," expression)* "]" | ||||
| list: "[" expression? ("," expression)* "]"  | ||||
|  | ||||
| range: "[" expression? ":" expression? "]" | ||||
|  | ||||
| controls: test | ||||
| 		| loop | ||||
|  | ||||
| test: "si" expression "alors" "{" instruction* "}" | ||||
|     | "si" expression "alors" "{" instruction* "}" "sinon" "{" instruction* "}" | ||||
|  | ||||
|  | ||||
| operator: PLUS_OP | ||||
| 		| MINUS_OP | ||||
| 		| TIMES_OP | ||||
| 		| DIVIDE_OP // TODO: not complete | ||||
| test: "si" expression "alors" "{" instruction* "}" ("sinon" "{" instruction* "}")? | ||||
|  | ||||
| TERMINAL: ";" | ||||
|  | ||||
| @ -71,8 +71,8 @@ EQUAL_SIGN: "=" | ||||
|  | ||||
| ENTIER: /0|[1-9][0-9]*/ | ||||
|  | ||||
| booleen: TRUE_KW  | ||||
| 	   | FALSE_KW | ||||
| ?booleen: TRUE_KW  -> true | ||||
| 	   | FALSE_KW -> false | ||||
|  | ||||
| BOOL_TYPE: "booléen" | ||||
| INT_TYPE: "entier" | ||||
| @ -80,7 +80,7 @@ STR_TYPE: "texte" | ||||
| LIST_TYPE: "liste" | ||||
|  | ||||
| SAME_OP: "==" | "vaut" | ||||
| DIFF_OP: "!=" | "ne" "vaut" "pas" | ||||
| DIFF_OP: "!=" | /ne vaut pas/  | ||||
|  | ||||
| AND_OP: "et" | ||||
| OR_OP: "ou" | ||||
|  | ||||
							
								
								
									
										72
									
								
								spf.py
									
									
									
									
									
								
							
							
						
						
									
										72
									
								
								spf.py
									
									
									
									
									
								
							| @ -6,9 +6,68 @@ | ||||
| import argparse | ||||
| import lark | ||||
| import sys | ||||
| from enum import Enum | ||||
|  | ||||
| variables = {} | ||||
|  | ||||
| class VariableType(Enum): | ||||
|     boolean     = 1 | ||||
|     integer     = 2 | ||||
|     string      = 3 | ||||
|     list        = 4 | ||||
|  | ||||
|  | ||||
| class Variable(): | ||||
|     def __init__(self, type, value): | ||||
|         self.type = type | ||||
|         self.value = value | ||||
|  | ||||
|     def __str__(self): | ||||
|         if self.type == "booléen": | ||||
|             return "Vrai" if self.value else "Faux" | ||||
|         return f"{self.value}" | ||||
|  | ||||
|     def __repr__(self): | ||||
|         if self.type == "texte": | ||||
|             return f"\"{self.value}\"" | ||||
|         return f"{self.value}" | ||||
|  | ||||
| class SPFInterpreter(lark.visitors.Interpreter): | ||||
|     def afficher(self, el): | ||||
|         for toprint in el.children[1:]: | ||||
|             print(self.visit_children(toprint)[0]) | ||||
|         return | ||||
|  | ||||
|     def declaration(self, el): | ||||
|         type = el.children[0].value | ||||
|         name = el.children[1].value | ||||
|         assert el.children[2].value == "=", "Unexpected" | ||||
|         assert el.children[3].data == "expression", "Unexpected" | ||||
|         value = self.visit_children(el.children[3])[0] | ||||
|         variables[name] = Variable(type, value) | ||||
|  | ||||
|     def assignation(self, el): | ||||
|         name = el.children[0].value | ||||
|         assert name in variables, f"Unknown variable : {el.children[0].value} not in {variables}" | ||||
|         assert el.children[1].value == "=", "Unexpected" | ||||
|         assert el.children[2].data == "expression", "Unexpected" | ||||
|         value = self.visit_children(el.children[2])[0] | ||||
|         variables[name] = value #TODO: vérifier type | ||||
|  | ||||
|     def expressionleft(self, el): | ||||
|         return self.visit_children(el)[0] | ||||
|  | ||||
|  | ||||
|     def variable(self, el): | ||||
|         assert el.children[0].value in variables, f"Unknown variable : {el.children[0].value} not in {variables}" | ||||
|         return variables[el.children[0].value] | ||||
|  | ||||
|     # Literals | ||||
|     string = lambda self, el: el.children[0][1:-1] | ||||
|     entier = lambda self, el: int(el.children[0]) | ||||
|     true = lambda self, _: True | ||||
|     false = lambda self, _: False | ||||
|  | ||||
| class SPFTransformer(lark.Transformer): | ||||
|     pass | ||||
|  | ||||
|  | ||||
| def main(): | ||||
| @ -22,9 +81,6 @@ def main(): | ||||
|                         action="store_true") | ||||
|     args = arg_parser.parse_args() | ||||
|  | ||||
|     if args.dump: | ||||
|         print("Dump activated (TODO)", file=sys.stderr) | ||||
|  | ||||
|     if args.trace: | ||||
|         print("Trace activated (TODO)", file=sys.stderr) | ||||
|  | ||||
| @ -35,7 +91,11 @@ def main(): | ||||
|         program = spf_input.read() | ||||
|         parsed = spf_parser.parse(program) | ||||
|  | ||||
|     print(parsed.pretty()) | ||||
|     interpreter = SPFInterpreter() | ||||
|     interpreted = interpreter.visit(parsed) | ||||
|  | ||||
|     if args.dump: | ||||
|         print(variables, file=sys.stderr) | ||||
|  | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|  | ||||
		Reference in New Issue
	
	Block a user