Compare commits
2 Commits
a22bc69491
...
07fa61ef6c
Author | SHA1 | Date | |
---|---|---|---|
|
07fa61ef6c | ||
|
102f08c2cf |
@ -15,3 +15,11 @@ 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];
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ 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;
|
||||||
|
@ -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), "Le type n'est pas équivalent"
|
assert self.checkType(value, typ), f"Le type n'est pas équivalent: { value } n'est pas {typ}"
|
||||||
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), "Le type n'est pas équivalent"
|
assert self.checkType(value, self.type), f"Le type n'est pas équivalent: {value} n'est pas {self.type}"
|
||||||
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 n'éxiste pas"
|
assert name in self.variables, f"la variable {name} 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)
|
||||||
|
59
spf.lark
59
spf.lark
@ -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?
|
||||||
|
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
|
| list
|
||||||
| range
|
| range
|
||||||
| VARIABLE -> variable
|
| 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
|
?type: BOOL_TYPE
|
||||||
| INT_TYPE
|
| INT_TYPE
|
||||||
@ -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
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):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user