Déclaration et affichage
This commit is contained in:
		@ -1,8 +1,13 @@
 | 
				
			|||||||
entier pi = 314;
 | 
					texte nom = "anthony";
 | 
				
			||||||
entier pi2 = 3;
 | 
					entier age = 23;
 | 
				
			||||||
 | 
					booléen majeur = vrai;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pi = 3;
 | 
					majeur = faux;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
tant que pi vaut pi2 faire {
 | 
					afficher nom, age, majeur;
 | 
				
			||||||
	afficher "bonjour";
 | 
					
 | 
				
			||||||
}
 | 
					
 | 
				
			||||||
 | 
					#TODO: Ces lignes devraient donner une erreur
 | 
				
			||||||
 | 
					majeur = 42;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					afficher majeur;
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										56
									
								
								spf.lark
									
									
									
									
									
								
							
							
						
						
									
										56
									
								
								spf.lark
									
									
									
									
									
								
							@ -1,50 +1,57 @@
 | 
				
			|||||||
start: (instruction)*
 | 
					start: (instruction)*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
instruction: type declaration TERMINAL
 | 
					instruction: declaration ";"
 | 
				
			||||||
		   | assignation TERMINAL
 | 
							   | assignation ";"
 | 
				
			||||||
 | 
							   | SHOW_KW expression ("," expression)* ";" -> afficher
 | 
				
			||||||
 | 
							   | ADD_KW expression "dans" VARIABLE ";"
 | 
				
			||||||
		   | controls
 | 
							   | controls
 | 
				
			||||||
		   | SHOW_KW expression ("," expression)* TERMINAL
 | 
					 | 
				
			||||||
		   | ADD_KW expression "dans" VARIABLE TERMINAL
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
expression: expressionleft // TODO: priorité des op certainement fausse
 | 
					expression: expressionleft // TODO: priorité des operator certainement fausse
 | 
				
			||||||
          | op
 | 
					          | operator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
expressionleft: literal 
 | 
					expressionleft: literal 
 | 
				
			||||||
              | list
 | 
					              | list
 | 
				
			||||||
              | range
 | 
					              | range
 | 
				
			||||||
			  | VARIABLE
 | 
								  | VARIABLE -> variable
 | 
				
			||||||
 | 
								  | "(" expression ")"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
op: expressionleft SAME_OP expression
 | 
					//any -> bool
 | 
				
			||||||
 | 
					operator: expressionleft SAME_OP expression
 | 
				
			||||||
  | expressionleft DIFF_OP expression
 | 
					  | expressionleft DIFF_OP expression
 | 
				
			||||||
 | 
					//bool -> bool
 | 
				
			||||||
  | expressionleft AND_OP expression
 | 
					  | expressionleft AND_OP expression
 | 
				
			||||||
  | expressionleft OR_OP expression
 | 
					  | expressionleft OR_OP expression
 | 
				
			||||||
  | NOT_OP expression
 | 
					  | NOT_OP expression
 | 
				
			||||||
 | 
					//int -> bool
 | 
				
			||||||
  | expressionleft LT_OP expression
 | 
					  | expressionleft LT_OP expression
 | 
				
			||||||
  | expressionleft LE_OP expression
 | 
					  | expressionleft LE_OP expression
 | 
				
			||||||
  | expressionleft GT_OP expression
 | 
					  | expressionleft GT_OP expression
 | 
				
			||||||
  | expressionleft GE_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
 | 
					  | NEG_OP expression
 | 
				
			||||||
 | 
					// string/list -> string/list
 | 
				
			||||||
  | expressionleft CONC_OP expression
 | 
					  | expressionleft CONC_OP expression
 | 
				
			||||||
  | expressionleft ("[" expression "]" | range)
 | 
					 | 
				
			||||||
  | SIZE_OP expression
 | 
					  | SIZE_OP expression
 | 
				
			||||||
  | "(" expression ")"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
type: BOOL_TYPE
 | 
					?type: BOOL_TYPE
 | 
				
			||||||
     | INT_TYPE 
 | 
					     | INT_TYPE 
 | 
				
			||||||
     | STR_TYPE
 | 
					     | STR_TYPE
 | 
				
			||||||
     | LIST_TYPE
 | 
					     | LIST_TYPE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
declaration: VARIABLE (EQUAL_SIGN expression)?
 | 
					declaration: type VARIABLE (EQUAL_SIGN expression)?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
assignation: VARIABLE EQUAL_SIGN expression
 | 
					assignation: VARIABLE EQUAL_SIGN expression
 | 
				
			||||||
 | 
					
 | 
				
			||||||
loop: "tant" "que" expression "faire" "{" (instruction)* "}"
 | 
					loop: /tant que/ expression "faire" "{" (instruction)* "}"
 | 
				
			||||||
    | "pour" "chaque" type VARIABLE "dans" expression "faire" "{" (instruction)* "}"
 | 
					    | /pour chaque/ type VARIABLE "dans" expression "faire" "{" (instruction)* "}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
literal: ENTIER
 | 
					?literal: ENTIER -> entier
 | 
				
			||||||
	   | booleen 
 | 
						   | booleen 
 | 
				
			||||||
	   | ESCAPED_STRING
 | 
						   | ESCAPED_STRING -> string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
list: "[" expression? ("," expression)* "]" 
 | 
					list: "[" expression? ("," expression)* "]" 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -53,14 +60,7 @@ range: "[" expression? ":" expression? "]"
 | 
				
			|||||||
controls: test
 | 
					controls: test
 | 
				
			||||||
		| loop
 | 
							| loop
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test: "si" expression "alors" "{" instruction* "}"
 | 
					test: "si" expression "alors" "{" instruction* "}" ("sinon" "{" instruction* "}")?
 | 
				
			||||||
    | "si" expression "alors" "{" instruction* "}" "sinon" "{" instruction* "}"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
operator: PLUS_OP
 | 
					 | 
				
			||||||
		| MINUS_OP
 | 
					 | 
				
			||||||
		| TIMES_OP
 | 
					 | 
				
			||||||
		| DIVIDE_OP // TODO: not complete
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
TERMINAL: ";"
 | 
					TERMINAL: ";"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -71,8 +71,8 @@ EQUAL_SIGN: "="
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
ENTIER: /0|[1-9][0-9]*/
 | 
					ENTIER: /0|[1-9][0-9]*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
booleen: TRUE_KW 
 | 
					?booleen: TRUE_KW  -> true
 | 
				
			||||||
	   | FALSE_KW
 | 
						   | FALSE_KW -> false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
BOOL_TYPE: "booléen"
 | 
					BOOL_TYPE: "booléen"
 | 
				
			||||||
INT_TYPE: "entier"
 | 
					INT_TYPE: "entier"
 | 
				
			||||||
@ -80,7 +80,7 @@ STR_TYPE: "texte"
 | 
				
			|||||||
LIST_TYPE: "liste"
 | 
					LIST_TYPE: "liste"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SAME_OP: "==" | "vaut"
 | 
					SAME_OP: "==" | "vaut"
 | 
				
			||||||
DIFF_OP: "!=" | "ne" "vaut" "pas"
 | 
					DIFF_OP: "!=" | /ne vaut pas/ 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
AND_OP: "et"
 | 
					AND_OP: "et"
 | 
				
			||||||
OR_OP: "ou"
 | 
					OR_OP: "ou"
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										72
									
								
								spf.py
									
									
									
									
									
								
							
							
						
						
									
										72
									
								
								spf.py
									
									
									
									
									
								
							@ -6,9 +6,68 @@
 | 
				
			|||||||
import argparse
 | 
					import argparse
 | 
				
			||||||
import lark
 | 
					import lark
 | 
				
			||||||
import sys
 | 
					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():
 | 
					def main():
 | 
				
			||||||
@ -22,9 +81,6 @@ def main():
 | 
				
			|||||||
                        action="store_true")
 | 
					                        action="store_true")
 | 
				
			||||||
    args = arg_parser.parse_args()
 | 
					    args = arg_parser.parse_args()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if args.dump:
 | 
					 | 
				
			||||||
        print("Dump activated (TODO)", file=sys.stderr)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if args.trace:
 | 
					    if args.trace:
 | 
				
			||||||
        print("Trace activated (TODO)", file=sys.stderr)
 | 
					        print("Trace activated (TODO)", file=sys.stderr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -35,7 +91,11 @@ def main():
 | 
				
			|||||||
        program = spf_input.read()
 | 
					        program = spf_input.read()
 | 
				
			||||||
        parsed = spf_parser.parse(program)
 | 
					        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__":
 | 
					if __name__ == "__main__":
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user