Déclaration et affichage
This commit is contained in:
		| @ -1,8 +1,13 @@ | |||||||
| entier pi = 314; | texte nom = "anthony"; | ||||||
| entier pi2 = 3; | entier age = 23; | ||||||
|  | booléen majeur = vrai; | ||||||
|  |  | ||||||
| pi = 3; | majeur = faux; | ||||||
|  |  | ||||||
| tant que pi vaut pi2 faire { | afficher nom, age, majeur; | ||||||
| 	afficher "bonjour"; |  | ||||||
| } |  | ||||||
|  | #TODO: Ces lignes devraient donner une erreur | ||||||
|  | majeur = 42; | ||||||
|  |  | ||||||
|  | afficher majeur; | ||||||
|  | |||||||
							
								
								
									
										64
									
								
								spf.lark
									
									
									
									
									
								
							
							
						
						
									
										64
									
								
								spf.lark
									
									
									
									
									
								
							| @ -1,66 +1,66 @@ | |||||||
| start: (instruction)* | start: (instruction)* | ||||||
|  |  | ||||||
| instruction: type declaration TERMINAL | instruction: declaration ";" | ||||||
| 		   | assignation TERMINAL | 		   | assignation ";" | ||||||
|  | 		   | SHOW_KW expression ("," expression)* ";" -> afficher | ||||||
|  | 		   | ADD_KW expression "dans" VARIABLE ";" | ||||||
| 		   | controls | 		   | controls | ||||||
| 		   | SHOW_KW expression ("," expression)* TERMINAL |  | ||||||
| 		   | ADD_KW expression "dans" VARIABLE TERMINAL |  | ||||||
|  |  | ||||||
| expression: expressionleft // TODO: priorité des op certainement fausse | expression: expressionleft // TODO: priorité des operator certainement fausse | ||||||
|           | op |           | operator | ||||||
|  |  | ||||||
| expressionleft: literal  | expressionleft: literal  | ||||||
|               | list |               | list | ||||||
|               | range |               | range | ||||||
| 			  | VARIABLE | 			  | VARIABLE -> variable | ||||||
|  | 			  | "(" expression ")" | ||||||
|  |  | ||||||
| op: expressionleft SAME_OP expression | //any -> bool | ||||||
|  | operator: expressionleft SAME_OP expression | ||||||
|   | expressionleft DIFF_OP expression |   | expressionleft DIFF_OP expression | ||||||
|  | //bool -> bool | ||||||
|   | expressionleft AND_OP expression |   | expressionleft AND_OP expression | ||||||
|   | expressionleft OR_OP expression |   | expressionleft OR_OP expression | ||||||
|   | NOT_OP expression |   | NOT_OP expression | ||||||
|  | //int -> bool | ||||||
|   | expressionleft LT_OP expression |   | expressionleft LT_OP expression | ||||||
|   | expressionleft LE_OP expression |   | expressionleft LE_OP expression | ||||||
|   | expressionleft GT_OP expression |   | expressionleft GT_OP expression | ||||||
|   | expressionleft GE_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 |   | NEG_OP expression | ||||||
|  | // string/list -> string/list | ||||||
|   | expressionleft CONC_OP expression |   | expressionleft CONC_OP expression | ||||||
|   | expressionleft ("[" expression "]" | range) |  | ||||||
|   | SIZE_OP expression |   | SIZE_OP expression | ||||||
|   | "(" expression ")" |  | ||||||
|  |  | ||||||
| type: BOOL_TYPE | ?type: BOOL_TYPE | ||||||
| 	| INT_TYPE  |      | INT_TYPE  | ||||||
| 	| STR_TYPE |      | STR_TYPE | ||||||
| 	| LIST_TYPE |      | LIST_TYPE | ||||||
|  |  | ||||||
| declaration: VARIABLE (EQUAL_SIGN expression)? | declaration: type VARIABLE (EQUAL_SIGN expression)? | ||||||
|  |  | ||||||
| assignation: VARIABLE EQUAL_SIGN expression | assignation: VARIABLE EQUAL_SIGN expression | ||||||
|  |  | ||||||
| loop: "tant" "que" expression "faire" "{" (instruction)* "}" | loop: /tant que/ expression "faire" "{" (instruction)* "}" | ||||||
|     | "pour" "chaque" type VARIABLE "dans" expression "faire" "{" (instruction)* "}" |     | /pour chaque/ type VARIABLE "dans" expression "faire" "{" (instruction)* "}" | ||||||
|  |  | ||||||
| literal: ENTIER | ?literal: ENTIER -> entier | ||||||
| 	   | booleen  | 	   | booleen  | ||||||
| 	   | ESCAPED_STRING | 	   | ESCAPED_STRING -> string | ||||||
|  |  | ||||||
| list: "[" expression? ("," expression)* "]" | list: "[" expression? ("," expression)* "]"  | ||||||
|  |  | ||||||
| range: "[" expression? ":" expression? "]" | range: "[" expression? ":" expression? "]" | ||||||
|  |  | ||||||
| controls: test | controls: test | ||||||
| 		| loop | 		| loop | ||||||
|  |  | ||||||
| test: "si" expression "alors" "{" instruction* "}" | test: "si" expression "alors" "{" instruction* "}" ("sinon" "{" instruction* "}")? | ||||||
|     | "si" expression "alors" "{" instruction* "}" "sinon" "{" instruction* "}" |  | ||||||
|  |  | ||||||
|  |  | ||||||
| operator: PLUS_OP |  | ||||||
| 		| MINUS_OP |  | ||||||
| 		| TIMES_OP |  | ||||||
| 		| DIVIDE_OP // TODO: not complete |  | ||||||
|  |  | ||||||
| TERMINAL: ";" | TERMINAL: ";" | ||||||
|  |  | ||||||
| @ -71,8 +71,8 @@ EQUAL_SIGN: "=" | |||||||
|  |  | ||||||
| ENTIER: /0|[1-9][0-9]*/ | ENTIER: /0|[1-9][0-9]*/ | ||||||
|  |  | ||||||
| booleen: TRUE_KW  | ?booleen: TRUE_KW  -> true | ||||||
| 	   | FALSE_KW | 	   | FALSE_KW -> false | ||||||
|  |  | ||||||
| BOOL_TYPE: "booléen" | BOOL_TYPE: "booléen" | ||||||
| INT_TYPE: "entier" | INT_TYPE: "entier" | ||||||
| @ -80,7 +80,7 @@ STR_TYPE: "texte" | |||||||
| LIST_TYPE: "liste" | LIST_TYPE: "liste" | ||||||
|  |  | ||||||
| SAME_OP: "==" | "vaut" | SAME_OP: "==" | "vaut" | ||||||
| DIFF_OP: "!=" | "ne" "vaut" "pas" | DIFF_OP: "!=" | /ne vaut pas/  | ||||||
|  |  | ||||||
| AND_OP: "et" | AND_OP: "et" | ||||||
| OR_OP: "ou" | OR_OP: "ou" | ||||||
|  | |||||||
							
								
								
									
										72
									
								
								spf.py
									
									
									
									
									
								
							
							
						
						
									
										72
									
								
								spf.py
									
									
									
									
									
								
							| @ -6,9 +6,68 @@ | |||||||
| import argparse | import argparse | ||||||
| import lark | import lark | ||||||
| import sys | 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(): | def main(): | ||||||
| @ -22,9 +81,6 @@ def main(): | |||||||
|                         action="store_true") |                         action="store_true") | ||||||
|     args = arg_parser.parse_args() |     args = arg_parser.parse_args() | ||||||
|  |  | ||||||
|     if args.dump: |  | ||||||
|         print("Dump activated (TODO)", file=sys.stderr) |  | ||||||
|  |  | ||||||
|     if args.trace: |     if args.trace: | ||||||
|         print("Trace activated (TODO)", file=sys.stderr) |         print("Trace activated (TODO)", file=sys.stderr) | ||||||
|  |  | ||||||
| @ -35,7 +91,11 @@ def main(): | |||||||
|         program = spf_input.read() |         program = spf_input.read() | ||||||
|         parsed = spf_parser.parse(program) |         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__": | if __name__ == "__main__": | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user