#!/usr/bin/env python # Projet de compilation Umons 2025 # Par Debucquoy Anthony (231687) import argparse import lark import sys from enum import Enum from modules.Variables import Variables class SPFInterpreter(lark.visitors.Interpreter): def __init__(self, trace=False): super().__init__() self.variables = Variables(trace) def while_loop(self, el): print("TODO: while") cond = el.children[0] instr = el.children[1:] print(cond.pretty()) def for_loop(self, el): print("TODO: for") def afficher(self, el): ligne = "" for toprint in el.children[1:]: ligne += str(self.visit_children(toprint)[0]) + " " print(ligne) def append(self, el): (_, toadd, var) = self.visit_children(el); var_val = self.variables.get(var.value) var_val.append(toadd) def declaration(self, el): type = el.children[0].value name = el.children[1].value value = self.visit_children(el.children[3])[0] if len(el.children) >= 3 else None self.variables.declare(type, name, value) def assignation(self, el): name = el.children[0].value assert el.children[1].value == "=" and el.children[2].data == "expression", "Unexpected" value = self.visit_children(el.children[2])[0] self.variables.assign(name, value) def equal(self, el): (left, sign, right) = self.visit_children(el) return left == right def unequal(self, el): (left, sign, right) = self.visit_children(el) return left != right def and_op(self, el): (left, sign, right) = self.visit_children(el) return left and right def or_op(self, el): (left, sign, right) = self.visit_children(el) return left or right def not_op(self, el): (sign, right) = self.visit_children(el) return not right def lt(self, el): (left, sign, right) = self.visit_children(el) return left < right def le(self, el): (left, sign, right) = self.visit_children(el) return left <= right def gt(self, el): (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 minus(self, el): (left, sign, right) = self.visit_children(el) return left - right def time(self, el): (left, sign, right) = self.visit_children(el) return left * right def divide(self, el): (left, sign, right) = self.visit_children(el) return left / right neg = lambda self, el:-self.visit_children(el)[1] sizeof = lambda self, el:len(self.visit_children(el)[1]) def expression(self, el): return self.visit_children(el)[0] def expressionleft(self, el): return self.visit_children(el)[0] def variable(self, el): return self.variables.get(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 def dump(self): self.variables.dump() def main(): arg_parser = argparse.ArgumentParser() arg_parser.add_argument("spf_file", help="Fichier source à interpréter") arg_parser.add_argument("-d", "--dump", help="affichage de la mémoire du programme", action="store_true") arg_parser.add_argument("-t", "--trace", help="affichage de la mémoire au cours du programme", action="store_true") arg_parser.add_argument("-p", "--pretty", help="affichage de l'arbre et quite", action="store_true") args = arg_parser.parse_args() with open("spf.lark") as grammar: spf_parser = lark.Lark(grammar, parser="lalr", strict=True, debug=True) with open(args.spf_file) as spf_input: program = spf_input.read() parsed = spf_parser.parse(program) if args.pretty: print(parsed.pretty()) return interpreter = SPFInterpreter(args.trace) interpreted = interpreter.visit(parsed) if args.dump: interpreter.dump() if __name__ == "__main__": main()