Une raison pour laquelle je ne pouvais pas créer un langage prenant en charge les fonctions infixe, postfixe et préfixe, et plus encore?

StackOverflow https://stackoverflow.com/questions/427040

Question

Je réfléchis à la création d'un langage qui conviendrait parfaitement à la création de DSL, en permettant la définition de fonctions infixées, postfixées, préfixées, voire composées de plusieurs mots. Par exemple, vous pouvez définir un opérateur de multiplication infixe comme suit (où multiplier (X, Y) est déjà défini):

a * b => multiply(a,b)

Ou un suffixe "carré" opérateur:

a squared => a * a

Ou un opérateur ternaire de style C ou Java, qui implique deux mots clés entrecoupés de variables:

a ? b : c => if a==true then b else c

Il est clair que les ambiguïtés dans un tel langage sont nombreuses, mais s’il est typé de manière statique (avec inférence de type), la plupart des ambiguïtés pourraient alors être éliminées et celles qui subsisteraient pourraient être considérées comme une erreur de syntaxe (à corriger par ajouter des crochets, le cas échéant).

Existe-t-il une raison qui, selon moi, ne rendrait pas cela extrêmement difficile, impossible ou simplement une mauvaise idée?

Éditer: Un certain nombre de personnes m'ont indiqué des langues pouvant faire ceci ou quelque chose du genre, mais je suis vraiment intéressé par des indications sur la manière dont je pourrais implémenter mon propre analyseur, ou problèmes que je pourrais rencontrer si je le faisais.

Était-ce utile?

La solution

Ce n’est pas trop difficile à faire. Vous voudrez affecter à chaque opérateur une fixité (infixe, préfixe ou postfixe) et une priorité . Faites de la priorité un nombre réel; tu me remercieras plus tard. Les opérateurs de priorité supérieure se lient plus étroitement que les opérateurs de priorité inférieure; Avec la même priorité, vous pouvez exiger la désambiguïsation avec des parenthèses, mais vous préférerez probablement permettre à certains opérateurs d'être associatifs pour pouvoir écrire

.
x + y + z

sans parenthèses. Une fois que vous avez une fixité, une priorité et une associativité pour chaque opérateur, vous souhaiterez écrire un analyseur de précédence d'opérateur . Ce type d’analyseur est assez simple à écrire; il balaie les jetons de gauche à droite et utilise une pile auxiliaire. Il y a une explication dans le livre de dragon mais je ne l'ai jamais trouvée très claire, en partie parce que le livre de dragon décrit un cas très général d'analyse syntaxique de priorité des opérateurs. Mais je ne pense pas que vous trouverez cela difficile.

Vous devez également faire attention au cas où vous avez

prefix (e) postfix

préfixe et postfix ont la même priorité. Ce cas nécessite également des parenthèses pour la désambiguïsation.

Mon document Unvarsing Expressions avec les opérateurs Prefix et Postfix a un exemple d’analyseur à l’arrière et vous pouvez télécharger le code, mais il est écrit en ML et son fonctionnement peut ne pas être évident pour l’amateur. Mais toute la question de la fixité, etc., est expliquée en détail.

Autres conseils

Qu'allez-vous faire à propos de l'ordre des opérations?

a * b squared

Vous voudrez peut-être consulter Scala, qui propose une approche unique des opérateurs et des méthodes.

Haskell a exactement ce que vous recherchez.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top