Refactoring operators to include priority

This commit is contained in:
Anthony Debucquoy 2025-03-22 23:07:00 +01:00
parent 102f08c2cf
commit 07fa61ef6c
Signed by: tonitch
GPG Key ID: A78D6421F083D42E
2 changed files with 162 additions and 91 deletions

@ -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

@ -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):