Refactoring operators to include priority
This commit is contained in:
		
							
								
								
									
										59
									
								
								spf.lark
									
									
									
									
									
								
							
							
						
						
									
										59
									
								
								spf.lark
									
									
									
									
									
								
							| @ -6,36 +6,41 @@ instruction: declaration ";" | ||||
| 		   | ADD_KW expression "dans" VARIABLE ";" -> append | ||||
| 		   | controls | ||||
|  | ||||
| expression: expressionleft // TODO: priorité des operator certainement fausse | ||||
|           | operator | ||||
| // rule finishing by u are "UnambigiousED" | ||||
| expression: logical | ||||
|  | ||||
| expressionleft: literal  | ||||
| logical: comparison logicalu? | ||||
| logicalu: AND_OP logical | ||||
|         | OR_OP logical | ||||
|  | ||||
| comparison: sumterm comparisonu? | ||||
| comparisonu: SAME_OP comparison | ||||
|            | DIFF_OP comparison | ||||
|            | LT_OP comparison | ||||
|            | LE_OP comparison | ||||
|            | GT_OP comparison | ||||
|            | GE_OP comparison | ||||
|  | ||||
| sumterm: multterm sumtermu? | ||||
| sumtermu: PLUS_OP sumterm | ||||
|         | MINUS_OP sumterm | ||||
|  | ||||
| multterm: priority multtermu? | ||||
| multtermu: TIMES_OP multterm | ||||
|          | DIVIDE_OP multterm | ||||
|  | ||||
| priority: finalterm  | ||||
|         | finalterm "[" expression "]" -> list_get | ||||
|         | SIZE_OP finalterm | ||||
| 		| NEG_OP finalterm | ||||
| 		| NOT_OP finalterm | ||||
|  | ||||
|  | ||||
| finalterm: "(" expression ")" | ||||
|          | literal | ||||
|          | list | ||||
|          | range | ||||
|          | VARIABLE -> variable | ||||
| 			  | "(" expression ")" | ||||
|  | ||||
| //any -> bool | ||||
| operator: expressionleft SAME_OP expression -> equal | ||||
|   | expressionleft DIFF_OP expression -> unequal | ||||
| //bool -> bool | ||||
|   | expressionleft AND_OP expression -> and_op | ||||
|   | expressionleft OR_OP expression -> or_op | ||||
|   | NOT_OP expression -> not_op | ||||
| //int -> bool | ||||
|   | expressionleft LT_OP expression -> lt | ||||
|   | expressionleft LE_OP expression -> le | ||||
|   | expressionleft GT_OP expression -> gt | ||||
|   | expressionleft GE_OP expression -> ge | ||||
| //int -> int | ||||
|   | expressionleft PLUS_OP expression -> plus | ||||
|   | expressionleft MINUS_OP expression -> minus | ||||
|   | expressionleft TIMES_OP expression -> time | ||||
|   | expressionleft DIVIDE_OP expression -> divide | ||||
|   | NEG_OP expression -> neg | ||||
| // string/list -> string/list | ||||
|   | SIZE_OP expression -> sizeof | ||||
|   | expressionleft "[" expression "]" -> list_get | ||||
|  | ||||
| ?type: BOOL_TYPE | ||||
|      | INT_TYPE  | ||||
| @ -101,6 +106,8 @@ GE_OP: ">=" | ||||
|  | ||||
| CONC_OP: "+" | ||||
| SIZE_OP: "taille" | ||||
| LBRAC: "[" | ||||
| RBRAC: "]" | ||||
|  | ||||
| ADD_KW: "ajouter" | ||||
| 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] | ||||
|         self.variables.assign(name, value) | ||||
|  | ||||
|     def equal(self, el): | ||||
|         (left, sign, right) = self.visit_children(el) | ||||
|         return left == right | ||||
|  | ||||
|     def unequal(self, el): | ||||
|         (left, sign, right) = self.visit_children(el) | ||||
|         return left != right | ||||
|  | ||||
|     def and_op(self, el): | ||||
|         (left, sign, right) = self.visit_children(el) | ||||
|         return left and right | ||||
|  | ||||
|     def or_op(self, el): | ||||
|         (left, sign, right) = self.visit_children(el) | ||||
|         return left or right | ||||
|  | ||||
|     def not_op(self, el): | ||||
|         (sign, right) = self.visit_children(el) | ||||
|         return not right | ||||
|  | ||||
|     def lt(self, el): | ||||
|         (left, sign, right) = self.visit_children(el) | ||||
|         return left < right | ||||
|  | ||||
|     def le(self, el): | ||||
|         (left, sign, right) = self.visit_children(el) | ||||
|         return left <= right | ||||
|  | ||||
|     def gt(self, el): | ||||
|         (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 minus(self, el): | ||||
|         (left, sign, right) = self.visit_children(el) | ||||
|         return left - right | ||||
|  | ||||
|     def time(self, el): | ||||
|         (left, sign, right) = self.visit_children(el) | ||||
|         return left * right | ||||
|  | ||||
|     def divide(self, el): | ||||
|         (left, sign, right) = self.visit_children(el) | ||||
|         return left / right | ||||
|  | ||||
|     neg = lambda self, el:-self.visit_children(el)[1] | ||||
|  | ||||
|     sizeof = lambda self, el:len(self.visit_children(el)[1]) | ||||
|  | ||||
|     def list_get(self, el): | ||||
|         (left, right) = self.visit_children(el) | ||||
|         return left[right-1] | ||||
|  | ||||
|     # def and_op(self, el): | ||||
|     #     (left, sign, right) = self.visit_children(el) | ||||
|     #     return left and right | ||||
|     # | ||||
|     # def or_op(self, el): | ||||
|     #     (left, sign, right) = self.visit_children(el) | ||||
|     #     return left or right | ||||
|     # | ||||
|     # | ||||
|     # def equal(self, el): | ||||
|     #     (left, sign, right) = self.visit_children(el) | ||||
|     #     return left == right | ||||
|     # | ||||
|     # def unequal(self, el): | ||||
|     #     (left, sign, right) = self.visit_children(el) | ||||
|     #     return left != right | ||||
|     # | ||||
|     # def lt(self, el): | ||||
|     #     (left, sign, right) = self.visit_children(el) | ||||
|     #     return left < right | ||||
|     # | ||||
|     # def le(self, el): | ||||
|     #     (left, sign, right) = self.visit_children(el) | ||||
|     #     return left <= right | ||||
|     # | ||||
|     # def gt(self, el): | ||||
|     #     (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 minus(self, el): | ||||
|     #     (left, sign, right) = self.visit_children(el) | ||||
|     #     return left - right | ||||
|     # | ||||
|     # def time(self, el): | ||||
|     #     (left, sign, right) = self.visit_children(el) | ||||
|     #     return left * right | ||||
|     # | ||||
|     # def divide(self, el): | ||||
|     #     (left, sign, right) = self.visit_children(el) | ||||
|     #     return left / right | ||||
|     # | ||||
|     # sizeof = lambda self, el:len(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) | ||||
|     #     return not right | ||||
|     # | ||||
|     # | ||||
|     # def list_get(self, el): | ||||
|     #     (left, right) = self.visit_children(el) | ||||
|     #     return left[right-1] | ||||
|  | ||||
|     def expression(self, el): | ||||
|         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] | ||||
|  | ||||
|     def variable(self, el): | ||||
|  | ||||
		Reference in New Issue
	
	Block a user