Déclaration et affichage

This commit is contained in:
tonitch 2025-03-19 16:29:54 +01:00
parent ce99fbb71a
commit 0e11654fd2
Signed by: tonitch
GPG Key ID: A78D6421F083D42E
3 changed files with 109 additions and 44 deletions

View File

@ -1,8 +1,13 @@
entier pi = 314;
entier pi2 = 3;
texte nom = "anthony";
entier age = 23;
booléen majeur = vrai;
pi = 3;
majeur = faux;
tant que pi vaut pi2 faire {
afficher "bonjour";
}
afficher nom, age, majeur;
#TODO: Ces lignes devraient donner une erreur
majeur = 42;
afficher majeur;

View File

@ -1,66 +1,66 @@
start: (instruction)*
instruction: type declaration TERMINAL
| assignation TERMINAL
instruction: declaration ";"
| assignation ";"
| SHOW_KW expression ("," expression)* ";" -> afficher
| ADD_KW expression "dans" VARIABLE ";"
| controls
| SHOW_KW expression ("," expression)* TERMINAL
| ADD_KW expression "dans" VARIABLE TERMINAL
expression: expressionleft // TODO: priorité des op certainement fausse
| op
expression: expressionleft // TODO: priorité des operator certainement fausse
| operator
expressionleft: literal
| list
| range
| VARIABLE
| VARIABLE -> variable
| "(" expression ")"
op: expressionleft SAME_OP expression
//any -> bool
operator: expressionleft SAME_OP expression
| expressionleft DIFF_OP expression
//bool -> bool
| expressionleft AND_OP expression
| expressionleft OR_OP expression
| NOT_OP expression
//int -> bool
| expressionleft LT_OP expression
| expressionleft LE_OP expression
| expressionleft GT_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
// string/list -> string/list
| expressionleft CONC_OP expression
| expressionleft ("[" expression "]" | range)
| SIZE_OP expression
| "(" expression ")"
type: BOOL_TYPE
| INT_TYPE
| STR_TYPE
| LIST_TYPE
?type: BOOL_TYPE
| INT_TYPE
| STR_TYPE
| LIST_TYPE
declaration: VARIABLE (EQUAL_SIGN expression)?
declaration: type VARIABLE (EQUAL_SIGN expression)?
assignation: VARIABLE EQUAL_SIGN expression
loop: "tant" "que" expression "faire" "{" (instruction)* "}"
| "pour" "chaque" type VARIABLE "dans" expression "faire" "{" (instruction)* "}"
loop: /tant que/ expression "faire" "{" (instruction)* "}"
| /pour chaque/ type VARIABLE "dans" expression "faire" "{" (instruction)* "}"
literal: ENTIER
?literal: ENTIER -> entier
| booleen
| ESCAPED_STRING
| ESCAPED_STRING -> string
list: "[" expression? ("," expression)* "]"
list: "[" expression? ("," expression)* "]"
range: "[" expression? ":" expression? "]"
controls: test
| loop
test: "si" expression "alors" "{" instruction* "}"
| "si" expression "alors" "{" instruction* "}" "sinon" "{" instruction* "}"
operator: PLUS_OP
| MINUS_OP
| TIMES_OP
| DIVIDE_OP // TODO: not complete
test: "si" expression "alors" "{" instruction* "}" ("sinon" "{" instruction* "}")?
TERMINAL: ";"
@ -71,8 +71,8 @@ EQUAL_SIGN: "="
ENTIER: /0|[1-9][0-9]*/
booleen: TRUE_KW
| FALSE_KW
?booleen: TRUE_KW -> true
| FALSE_KW -> false
BOOL_TYPE: "booléen"
INT_TYPE: "entier"
@ -80,7 +80,7 @@ STR_TYPE: "texte"
LIST_TYPE: "liste"
SAME_OP: "==" | "vaut"
DIFF_OP: "!=" | "ne" "vaut" "pas"
DIFF_OP: "!=" | /ne vaut pas/
AND_OP: "et"
OR_OP: "ou"

72
spf.py
View File

@ -6,9 +6,68 @@
import argparse
import lark
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():
@ -22,9 +81,6 @@ def main():
action="store_true")
args = arg_parser.parse_args()
if args.dump:
print("Dump activated (TODO)", file=sys.stderr)
if args.trace:
print("Trace activated (TODO)", file=sys.stderr)
@ -35,7 +91,11 @@ def main():
program = spf_input.read()
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__":