(gile) Posté(e) le 5 novembre 2016 Posté(e) le 5 novembre 2016 Salut, En me penchant de plus près sur l'utilisation des expressions régulières (ou rationnelles), j'ai pensé qu'il pourrait être amusant de les utiliser dans l'élaboration d'un petit programme qui pourrait évaluer une chaîne de caractères représentant une expression LISP. J'ai fait un premier prototype en F#, visible et testable sur Try F#. Ce prototype ne fonctionne qu'avec les opérateurs +, -, * et / pour des nombres entiers (la rigueur de F# concernant le typage rend complexe l'utilisation de différents types de nombres.Try F# permet d'écrire et d'évaluer du code F# "à la volée". Il suffit de sélectionner le code et de clique sur "run" pour voir le résultat de l'évaluation dans la fenêtre de sortie (Output window). J'ai ensuite voulu traduire ça dans un langage moins confidentiel (C#) et un peu plus souple pour gérer les nombres entiers et réels à la manière du LISP. L'interface est sommaire (Console) mais ce n'était pas l'objectif.L'intérêt à l'usage est plus que limité, néanmoins je trouve ça intéressant d'un point de vue didactique. using System; using System.Linq; using System.Text.RegularExpressions; namespace ConsoleLISP { class Program { // // @"(?>\((?<depth>)\s*[\+\-\*/]\s+((\-)?\d+\s*)+\)(?<-depth>))(?(depth)(?!))" // retourne l'appel de fonction le plus imbriqué static Regex regex = new Regex(@" (?> # début de la recherche non rétroactive \( # parenthèse ouvrante (?<depth>) # incrémente le nombre de parenthèses \s* # zéro ou plusieurs espaces [\+\-\*/] # l'opérateur : caractère '+', '-', '*' ou '/' (\s+ # un ou plusieurs espaces (\-)?\d+ # suivi de un ou plusieurs chiffres éventuellement précédé du signe '-' (.\d*)? # éventuellement suivi d'un point et zéro ou plusieurs chiffres )+ # le tout une ou plusieurs fois \s* # zéro ou plusieurs espaces \) # parenthèse fermante (?<-depth>) # décrémente le nombre de parenthèses ) # fin de la recherche (?(depth)(?!)) # vérifie l’appariement des parenthèses ", RegexOptions.IgnorePatternWhitespace); static string Apply(string function, string[] args) { if (args.Any(s => s.Contains('.'))) { var values = args.Select(s => double.Parse(s)); switch (function) { case "+": return values.Aggregate((a, B) => a + B).ToString(); case "-": return (values.Count() == 1 ? -values.First() : values.Aggregate((a, B) => a - B)).ToString(); case "*": return values.Aggregate((a, B) => a * B).ToString(); case "/": return values.Aggregate((a, B) => a / B).ToString(); default: throw new Exception("Opérateur non valide."); } } else { var values = args.Select(s => int.Parse(s)); switch (function) { case "+": return values.Aggregate((a, B) => a + B).ToString(); case "-": return (values.Count() == 1 ? -values.First() : values.Aggregate((a, B) => a - B)).ToString(); case "*": return values.Aggregate((a, B) => a * B).ToString(); case "/": return values.Aggregate((a, B) => a / B).ToString(); default: throw new Exception("Opérateur non valide."); } } } static string Eval(string input) { var match = regex.Match(input); if (!match.Success) throw new Exception("\nExpression LISP non valide."); string expression = match.Value; string function = Regex.Match(expression, @"[\+\-\*/]").Value; var args = Regex.Split(Regex.Replace(expression, @"[\(\)\+\-\*/]", "").Trim(), @"\s+"); if (expression == input) return Apply(function, args); else return Eval(Regex.Replace(input, Regex.Escape(expression), Apply(function, args))); } static void Main() { while (true) { Console.WriteLine("\nEntrez une expression arithmétique LISP (ou Entrée pour quitter) :"); string input = Console.ReadLine(); if (input == "") return; try { Console.WriteLine(Eval(input)); } catch (Exception ex) { Console.WriteLine(ex.Message); } } } } } Pour tester :Télécharger ConsoleLISP.zipDébloquer ConsoleLISP.zipExtraire et lancer ConsoleLISP.exe Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Messages recommandés
Créer un compte ou se connecter pour commenter
Vous devez être membre afin de pouvoir déposer un commentaire
Créer un compte
Créez un compte sur notre communauté. C’est facile !
Créer un nouveau compteSe connecter
Vous avez déjà un compte ? Connectez-vous ici.
Connectez-vous maintenant