Compare commits

..

No commits in common. "07fa61ef6c2afd007df7eeedd3c236e52f7ef94e" and "a22bc69491fe060bedfb048d72aec891c10ccc6d" have entirely different histories.

5 changed files with 97 additions and 176 deletions

View File

@ -15,11 +15,3 @@ 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];

View File

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

View File

@ -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), f"Le type n'est pas équivalent: { value } n'est pas {typ}" assert self.checkType(value, typ), "Le type n'est pas équivalent"
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), f"Le type n'est pas équivalent: {value} n'est pas {self.type}" assert self.checkType(value, self.type), "Le type n'est pas équivalent"
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 {name} n'éxiste pas" assert name in self.variables, f"la variable 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)

View File

@ -6,41 +6,36 @@ instruction: declaration ";"
| ADD_KW expression "dans" VARIABLE ";" -> append | ADD_KW expression "dans" VARIABLE ";" -> append
| controls | controls
// rule finishing by u are "UnambigiousED" expression: expressionleft // TODO: priorité des operator certainement fausse
expression: logical | operator
logical: comparison logicalu? expressionleft: literal
logicalu: AND_OP logical | list
| OR_OP logical | range
| VARIABLE -> variable
| "(" expression ")"
comparison: sumterm comparisonu? //any -> bool
comparisonu: SAME_OP comparison operator: expressionleft SAME_OP expression -> equal
| DIFF_OP comparison | expressionleft DIFF_OP expression -> unequal
| LT_OP comparison //bool -> bool
| LE_OP comparison | expressionleft AND_OP expression -> and_op
| GT_OP comparison | expressionleft OR_OP expression -> or_op
| GE_OP comparison | NOT_OP expression -> not_op
//int -> bool
sumterm: multterm sumtermu? | expressionleft LT_OP expression -> lt
sumtermu: PLUS_OP sumterm | expressionleft LE_OP expression -> le
| MINUS_OP sumterm | expressionleft GT_OP expression -> gt
| expressionleft GE_OP expression -> ge
multterm: priority multtermu? //int -> int
multtermu: TIMES_OP multterm | expressionleft PLUS_OP expression -> plus
| DIVIDE_OP multterm | expressionleft MINUS_OP expression -> minus
| expressionleft TIMES_OP expression -> time
priority: finalterm | expressionleft DIVIDE_OP expression -> divide
| finalterm "[" expression "]" -> list_get | NEG_OP expression -> neg
| SIZE_OP finalterm // string/list -> string/list
| NEG_OP finalterm | SIZE_OP expression -> sizeof
| NOT_OP finalterm | expressionleft "[" expression "]" -> list_get
finalterm: "(" expression ")"
| literal
| list
| range
| VARIABLE -> variable
?type: BOOL_TYPE ?type: BOOL_TYPE
| INT_TYPE | INT_TYPE
@ -69,7 +64,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: ";"
@ -106,8 +101,6 @@ 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
View File

@ -52,136 +52,72 @@ 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 and_op(self, el): def equal(self, el):
# (left, sign, right) = self.visit_children(el) (left, sign, right) = self.visit_children(el)
# return left and right return left == right
#
# def or_op(self, el): def unequal(self, el):
# (left, sign, right) = self.visit_children(el) (left, sign, right) = self.visit_children(el)
# return left or right return left != right
#
# def and_op(self, el):
# def equal(self, el): (left, sign, right) = self.visit_children(el)
# (left, sign, right) = self.visit_children(el) return left and right
# return left == right
# def or_op(self, el):
# def unequal(self, el): (left, sign, right) = self.visit_children(el)
# (left, sign, right) = self.visit_children(el) return left or right
# return left != right
# def not_op(self, el):
# def lt(self, el): (sign, right) = self.visit_children(el)
# (left, sign, right) = self.visit_children(el) return not right
# return left < right
# def lt(self, el):
# def le(self, el): (left, sign, right) = self.visit_children(el)
# (left, sign, right) = self.visit_children(el) return left < right
# return left <= right
# def le(self, el):
# def gt(self, el): (left, sign, right) = self.visit_children(el)
# (left, sign, right) = self.visit_children(el) return left <= right
# return left > right
# def gt(self, el):
# def ge(self, el): (left, sign, right) = self.visit_children(el)
# (left, sign, right) = self.visit_children(el) return left > right
# return left >= right
# def ge(self, el):
# (left, sign, right) = self.visit_children(el)
# def plus(self, el): return left >= right
# (left, sign, right) = self.visit_children(el)
# return left + right # Cool ça fonctionne pour les str
# def plus(self, el):
# def minus(self, el): (left, sign, right) = self.visit_children(el)
# (left, sign, right) = self.visit_children(el) return left + right # Cool ça fonctionne pour les str
# return left - right
# def minus(self, el):
# def time(self, el): (left, sign, right) = self.visit_children(el)
# (left, sign, right) = self.visit_children(el) return left - right
# return left * right
# def time(self, el):
# def divide(self, el): (left, sign, right) = self.visit_children(el)
# (left, sign, right) = self.visit_children(el) return left * right
# return left / right
# def divide(self, el):
# sizeof = lambda self, el:len(self.visit_children(el)[1]) (left, sign, right) = self.visit_children(el)
# neg = lambda self, el:-self.visit_children(el)[1] return left / right
#
# def not_op(self, el): neg = lambda self, el:-self.visit_children(el)[1]
# (sign, right) = self.visit_children(el)
# return not right sizeof = lambda self, el:len(self.visit_children(el)[1])
#
# def list_get(self, el):
# def list_get(self, el): (left, right) = self.visit_children(el)
# (left, right) = self.visit_children(el) return left[right-1]
# 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 logical(self, el): def expressionleft(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):