3 pièce(s) jointe(s)
[source] Evaluation d'expressions "infixées"
Bonjour,
J'ai écrit un (cross) assembleur pour les microprocesseurs de la famille 6800 il y a déjà quelques années, et ai voulu modifier la routine d'évaluation des opérandes (liés aux instructions ou aux directives). J'ai trouvé une bibliothèque sympa (tinyexpr-master), mais qui aurait nécessité trop de temps à l'adapter. Toutes les pages trouvées sur le net sont similaires, mais je me suis inspiré de celle-ci. C'est très didactique, mais un peu court, en particulier parce que des opérateurs unaires ne sont pas pris en compte.
Voici un bout de code qui m'aura permis de tester. Il est suis prêt à l'intégration dans le code de l'assembleur existant, et accessoirement, à être placer dans le domaine public. On a donc un truc qui permet d'évaluer une expression infixée, mais pas strictement (de ce que j'ai compris de la définition de “infixée”) puisqu'au final, un simple opérande devait pouvoir être évalué. La forme de l'expression en entrée a été forcée en la "plaçant" entre parenthèses et à la suite de 0+, c'est-à-dire que dans l'exemple ci-dessous, l'expression saisie est A+(B*C-(D/E)*G)*H et celle passée à la fonction est 0+(A+(B*C-(D/E)*G)*H).
Comme la plupart des humains, je suis très sensible au feed-back, et attends donc vos remarques. J'espère cependant que la forme d'écriture ne choquera pas suffisamment pour avoir trop de "retours" à ce sujet. Je n'ai pas respecté les 80 colonnes de largeur (mais 96) et les quatre espaces d'indentation (mais 2). J'ai utilisé à outrance la coloration syntaxique pour me repérer dans ce long fichier source (~800 lignes). Les identifiants sont aussi humainement significatifs que possible, mais je ne raconte pas leur vie. Une des difficultés de lecture du C, selon moi, est la localisation des fonctions. J'ai résolu le problème en ayant un arrière-plan gris et en plaçant les commentaires Doxygen sur fond blanc. La déclaration d'une fonction est suivie d'une ligne remplie d'astérisques. Ça prend de la place mais ça saute aux yeux. Pièce jointe 484139
Pour information, j'utilise Linux OpenSUSE Leap 42.3 avec KDE3 pour gestionnaire de fenêtres, et Kate comme éditeur. À toutes fins utiles, je signale que l'embelliseur (beautifier) nommé "astyle" a bien muri et est exploitable. À noter également que je m'interdis du code colonne 1, sauf provisoirement pour débugging, et des commentaires. Vous noterez que j'ai beaucoup commenté. C'est dû à mon âge ! J'oublie tout trop vite, alors mes commentaires sont censés me faire gagner du temps. Enfin, j'évite au maximum les déclarations en avant. La conséquence est que les fonctions de plus bas "niveau" se trouve en tête du fichier, et main() est la dernière fonction déclarée. Cela vient probablement de mon histoire liée à l'écriture de logiciels pour les micros 8 bits. Vous verrez pourtant une contradiction ici: Nemiver se sort mal de session enregistrée sur disque quand main() est à la fin du fichier.
Pour essayer, vous n'avez qu'à placer le fichier source nommé "Evaluate_in.c" dans un répertoire nommé "AssEval" (par exemple) dans votre répertoire personnel, puis saisissez dans une fenêtre terminal, les commandes:
Code:
1 2
| export C8_DEV=' -O0 -D_GNU_SOURCE -std=c99 -fstrict-aliasing -fwrapv -Wall -Wextra -g -iquote ./ -fmax-errors=10 '
cd ~/AssEval/ ; gcc $C8_DEV -Werror -g Evaluate_in.c && ./a.out 'A+(B*C-(D/E)*G)*H' |
Pour quelques tests suivant:
Code:
./a.out '!A+(!B*!C-(!D/!E)*!G)*!H'
Ce dernier exemple affichera (ici dans Konsole):
Pièce jointe 484135
Notez que l'affichage dépend de certaines macro-instructions définies au début du fichier (DEVEL_INFIX, DEBUGTORSTACK et DEVEL_PARENTHESIZED)
Si vous saisissez une lettre comme opérande (comme dans les exemples ci-dessus), la valeur du code ASCII de la lettre sera prise en compte pour les calculs. Vous pouvez cependant saisir des nombres entiers (uniquement) sous la base de votre choix parmi décimale, octale, binaire et hexadécimale. Exemple: 0, 0123, 0o7307, @7307, 0B01001111, %1001111, 0xfC96, $Fc96. Notez que la casse des caractères alphabétiques n'importe pas. Dans la version embarquée dans l'assembleur, les opérandes commençant par les caractères autorisés seront recherchés par un gestionnaire d'identifiants (identificateurs, généralement appelés symboles, pour les assembleurs) qui retournera la valeur qui a été affectée à l’identifiant trouvé.
L'objectif est l'intégration dans un assembleur pour microprocesseur 8 bits: les résultats sont limités aux entiers de 16 bits.
Le fichier est ici:Pièce jointe 484142
Le fichier des couleurs !
Le fichier manquant, nommé Vt-200.color.h :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
| /// Définition de couleurs
#if !defined COLOR_TERM_H
# define COLOR_TERM_H
#define _0_ "\x1b[0m" /* Normal */
#define _v_ "\x1b[1m" /* Bright / bold */
#define _p_ "\x1b[2m" /* Faint (Pale) */
#define _u_ "\x1b[4m" /* Italic / underlined */
#define _b_ "\x1b[5m" /* Blinking */
#define _i_ "\x1b[7m" /* Inverted */
#define _h_ "\x1b[8m" /* Invisible / hidden */
#define _s_ "\x1b[9m" /* Streched / Crossed-out */
#define C_ "\x1B[0m" /* Termine un changement de couleur "\x1B[0m" is sufficient */
// TODO Check if "\x1B[0;0m" is correct (Set foreground and background color to default.)...
// NOTE Should'nt be "\x1B[0;32;40m" For screen default color green on black
// Ci-dessous: les initiales d'un changement de couleur
#define _N0 "\x1B[0;30m" /* Couleurs normales */
#define _R0 "\x1B[0;31m"
#define _V0 "\x1B[0;32m"
#define _J0 "\x1B[0;33m"
#define _B0 "\x1B[0;34m"
#define _M0 "\x1B[0;35m"
#define _C0 "\x1B[0;36m"
#define _G0 "\x1B[0;37m"
#define _nv "\x1B[1;30m" /* Couleurs vives */
#define _rv "\x1B[1;31m"
#define _vv "\x1B[1;32m"
#define _jv "\x1B[1;33m"
#define _bv "\x1B[1;34m"
#define _mv "\x1B[1;35m"
#define _cv "\x1B[1;36m"
#define _gv "\x1B[1;37m"
#define _n "\x1B[2;30m" /* Couleurs pâles */
#define _r "\x1B[2;31m"
#define _v "\x1B[2;32m"
#define _j "\x1B[2;33m"
#define _b "\x1B[2;34m"
#define _m "\x1B[2;35m"
#define _c "\x1B[2;36m"
#define _g "\x1B[2;37m"
#define _nu "\x1B[4;30m" /* Soulignées */
#define _ru "\x1B[4;31m"
#define _vu "\x1B[4;32m"
#define _ju "\x1B[4;33m"
#define _bu "\x1B[4;34m"
#define _mu "\x1B[4;35m"
#define _cu "\x1B[4;36m"
#define _gu "\x1B[4;37m"
#define _nb "\x1B[5;30m" /* Blinking */
#define _rb "\x1B[5;31m"
#define _vb "\x1B[5;32m"
#define _jb "\x1B[5;33m"
#define _bb "\x1B[5;34m"
#define _mb "\x1B[5;35m"
#define _cb "\x1B[5;36m"
#define _gb "\x1B[5;37m"
#define _ni "\x1B[7;30m" /* Couleurs inversées */
#define _ri "\x1B[7;31m"
#define _vi "\x1B[7;32m"
#define _ji "\x1B[7;33m"
#define _bi "\x1B[7;34m"
#define _mi "\x1B[7;35m"
#define _ci "\x1B[7;36m"
#define _gi "\x1B[7;37m"
#define _ns "\x1B[9;30m" /* Caractères barrés */
#define _rs "\x1B[9;31m"
#define _vs "\x1B[9;32m"
#define _js "\x1B[9;33m"
#define _bs "\x1B[9;34m"
#define _ms "\x1B[9;35m"
#define _cs "\x1B[9;36m"
#define _gs "\x1B[9;37m"
/** NOTE : _Ro(" rouge "_Bl(" bleu ")" rouge ") DOES NOT WORK !
Do so : _Ro(" rouge ")_Bl(" bleu ")_Ro(" rouge ")
. +------------+---- "normal":0, "vif"(gras):1, "pâle":2,
. | | "souligné":4, "cligno/gras":5, "vidéo inverse":7, "caché":8,
. | +-------------- 30:Noir, 31:Rouge, 32:Vert, 33:Jaune
. | | | 34:Bleu, 35:Magenta, 36:Cyan, 37:Gris */
#if 0 /* OK for Xterm */
#define _No(s) "\x1B[0;30m"s"\x1B[0;0m"
#define _Ro(s) "\x1B[0;31m"s"\x1B[0;0m"
#define _Ve(s) "\x1B[0;32m"s"\x1B[0;0m"
#define _Ja(s) "\x1B[0;33m"s"\x1B[0;0m"
#define _Bl(s) "\x1B[0;34m"s"\x1B[0;0m"
#define _Ma(s) "\x1B[0;35m"s"\x1B[0;0m"
#define _Cy(s) "\x1B[0;36m"s"\x1B[0;0m" /* ~bleu */
#define _Gr(s) "\x1B[0;37m"s"\x1B[0;0m" /* ~rouge */
// The above colors are well for XTerm but hugly in Konsol
#else /* Beter for Konsol */
#define _No(s) _nv""s""C_
#define _Ro(s) _rv""s""C_
#define _Ve(s) _vv""s""C_
#define _Ja(s) _jv""s""C_
#define _Bl(s) _bv""s""C_
#define _Ma(s) _mv""s""C_ /* ~ fuchia */
#define _Cy(s) _cv""s""C_ /* ~ bleu ciel */
// #define _Gr(s) _gv""s""C_
#define _Gr(s) _G0""s""C_
#endif
#endif /* !defined COLOR_TERM_H */ |
Personne ne s'est plein : j'en conclue que personne n'a essayé :(