From a984cf3f28d3a5935c84f96f6da3bc7bd39a9ff1 Mon Sep 17 00:00:00 2001 From: Pixel <> Date: Fri, 13 Apr 2001 12:03:09 +0000 Subject: Assembleur. --- lib/parser.c | 151 +++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 96 insertions(+), 55 deletions(-) (limited to 'lib/parser.c') diff --git a/lib/parser.c b/lib/parser.c index ee3e64c..2a9edd1 100644 --- a/lib/parser.c +++ b/lib/parser.c @@ -4,11 +4,16 @@ #include "config.h" #else #define _(x) x -void exception(int, char *); #endif #include "exceptions.h" #include "parser.h" +#include "assembler.h" +/*******************************\ +* * +* Parser * +* * +\*******************************/ typedef unsigned char op_t; @@ -22,8 +27,10 @@ static int pile_nestedcall[PILECALL_MAX]; static int pileop_pos = 0, pilecall_pos = 0; +/* La liste des opérateurs reconnus par le parser */ + static operator_t operators[] = { - {',', 0, OP_NEST}, + {',', 0, OP_NEST}, {'+', 2, OP_PLUS}, {'-', 2, OP_MOINS}, {'*', 3, OP_MUL}, @@ -37,6 +44,8 @@ static operator_t operators[] = { {255, -1, -1} }; +/* Fonction interne: convertit un operateur en sa structure */ + static operator_t get_op(op_t op) { int i; @@ -49,6 +58,8 @@ static operator_t get_op(op_t op) return operators[i]; } +/* Fonctions internes de lectures sur la structure */ + static int get_pri(op_t op) { return get_op(op).pri; @@ -59,6 +70,8 @@ static int get_func(op_t op) return get_op(op).func; } +/* Focntions internes d'empilement / dépilement */ + static op_t get_last_op(void) { if (pileop_pos) @@ -87,20 +100,22 @@ static int pop_call(void) { if (pilecall_pos) return pile_nestedcall[--pilecall_pos]; - return -1; + return -1; } -static void increment_call(void) { - if (pilecall_pos) { - if (pile_nestedcall[pilecall_pos - 1] != -1) - pile_nestedcall[pilecall_pos - 1]++; - } -} - -static int get_last_call(void) { - if (pilecall_pos) - return pile_nestedcall[pilecall_pos - 1]; - return -1; +static void increment_call(void) +{ + if (pilecall_pos) { + if (pile_nestedcall[pilecall_pos - 1] != -1) + pile_nestedcall[pilecall_pos - 1]++; + } +} + +static int get_last_call(void) +{ + if (pilecall_pos) + return pile_nestedcall[pilecall_pos - 1]; + return -1; } static void push_call(int call) @@ -111,6 +126,8 @@ static void push_call(int call) exception(-1, _("Too many nested functions calls in expression.\n")); } +/* Cette fonction lit un "mot" sur la chaine line et renvoit le nouveau pointeur */ + static char *getword(char *line, char *p) { char o = 0, *d = line, instring = 0, gotbslash = 0; @@ -120,18 +137,19 @@ static char *getword(char *line, char *p) o = *(p++) = *line; if (!gotbslash) { switch (instring) { - case 1: - if (*line == '\'') { - instring = 0; - } - break; - case 2: - if (*line == '"') { - instring = 0; - } - break; + case 1: + if (*line == '\'') { + instring = 0; + } + break; + case 2: + if (*line == '"') { + instring = 0; + } + break; } - if (*line == '\\') gotbslash = 1; + if (*line == '\\') + gotbslash = 1; } else { gotbslash = 0; } @@ -143,7 +161,7 @@ static char *getword(char *line, char *p) o = *(p++) = *line; instring = 2; } else { - if (*(line) != ' ') { + if (*(line) != ' ' && *(line) != '\t') { o = *(p++) = *line; } else if (d != line) { *p = '\0'; @@ -153,20 +171,28 @@ static char *getword(char *line, char *p) } line++; } while (((*line) && (*line != ')') && (*line != ']') && (*line != ';') && (get_func(*line) == -1) - && (get_func(o) == -1)) || (instring)); + && (get_func(o) == -1)) || (instring)); *p = '\0'; return line; } +/* Cette fonction va parcourire une chaine afin d'appeler les fonction push_pule() et act_pile() */ + void parse_line(char *line) { - char buffer[BUFSIZ], imm[BUFSIZ]; + char buffer[BUFSIZ], imm[BUFSIZ], *d = line; op_t op; int got_unary = 128, nbrargs; + sprintf(buffer, "Read line '%s'", line); + pushcontext(buffer); + while (*line) { line = getword(line, buffer); + sprintf(imm, "Analysing word '%s' at position %i", buffer, line - d); + pushcontext(imm); if (get_func(buffer[0]) != -1) { + /* Le mot lut est un operateur, on agit sur la pile */ buffer[0] += got_unary; if (got_unary) { } @@ -177,28 +203,35 @@ void parse_line(char *line) exception(-1, _("Invalid binary operator")); } } - while (get_pri(get_last_op()) >= get_pri(buffer[0]) && (((get_last_op() & 127) != '(') && ((get_last_op() & 127) != '['))) { + while (get_pri(get_last_op()) >= get_pri(buffer[0]) + && (((get_last_op() & 127) != '(') && ((get_last_op() & 127) != '['))) { act_pile(get_func(pop_op())); got_unary = 0; } if (buffer[0] == '(') { push_call(0); - } + } if (buffer[0] == ',') { - increment_call(); - } else push_op(buffer[0]); + increment_call(); + } else + push_op(buffer[0]); got_unary = 128; } else if ((buffer[0] == ';') || (buffer[0] == ')') || (buffer[0] == ']')) { + /* Le mot lut est un opérateur spécial, on vide la pile */ switch (buffer[0]) { case ';': + /* Equivalent a fin de ligne */ while (pileop_pos) { op = pop_op(); if (op == '(') exception(-1, _("Parse error: too much left parenthesis")); act_pile(get_func(op)); } - break; + popcontext(); + popcontext(); + return; case ')': + /* Fin de parenthese (Appel de fonction ou expression mathématique) */ while (1) { if (!pileop_pos) exception(-1, _("Parse error: too much right parenthesis")); @@ -209,15 +242,16 @@ void parse_line(char *line) exception(-1, _("Parse error: enclosure mismatch")); act_pile(get_func(op)); } - if (op == '(') { - nbrargs = pop_call(); - sprintf(imm, "%i", nbrargs); - push_pile(imm); - act_pile(get_func(op)); - } + if (op == '(') { + nbrargs = pop_call(); + sprintf(imm, "%i", nbrargs); + push_pile(imm); + act_pile(get_func(op)); + } got_unary = 0; break; case ']': + /* Fin d'opérateur de décalage */ while (1) { if (!pileop_pos) exception(-1, _("Parse error: too much right parenthesis")); @@ -228,28 +262,30 @@ void parse_line(char *line) exception(-1, _("Parse error: enclosure mismatch")); act_pile(get_func(op)); } - act_pile(get_func(op)); + act_pile(get_func(op)); got_unary = 0; break; } } else if (((buffer[0] >= 'A') && (buffer[0] <= 'Z')) || ((buffer[0] >= 'a') && (buffer[0] <= 'z')) - || ((buffer[0] >= '0') && (buffer[0] <= '9')) || (buffer[0] == '_') || (buffer[0] == '"') || (buffer[0] == '\'')) { + || ((buffer[0] >= '0') && (buffer[0] <= '9')) || (buffer[0] == '_') || (buffer[0] == '"') + || (buffer[0] == '\'')) { + /* Dans tous les autres cas, on a reçu un symbole, on le pose sur la pile */ push_pile(buffer); got_unary = 0; - if (!get_last_call()) increment_call(); + if (!get_last_call()) + increment_call(); } else if (buffer[0]) { exception(-1, _("Invalid character")); } + popcontext(); } + + popcontext(); } #ifndef HAVE_CONFIG_H -void exception(int level, char *msg) -{ - fprintf(stderr, "%s\n", msg); - exit(level); -} +/* Les quelques fonctions de test, lorsque le parser est compilé en dehors du projet. */ void push_pile(char *word) { @@ -279,9 +315,9 @@ void act_pile(int func) case OP_MOINS_UNARY: op = '|'; break; - case OP_FUNC_CALL: - op = '@'; - break; + case OP_FUNC_CALL: + op = '@'; + break; case OP_DECAL: op = '['; break; @@ -295,15 +331,20 @@ void act_pile(int func) void main(void) { parse_line("ADD R18, R20, 39;"); - printf("\n\n"); fflush(stdout); + printf("\n\n"); + fflush(stdout); parse_line("MOV R31, Bidule[48 + R12];"); - printf("\n\n"); fflush(stdout); + printf("\n\n"); + fflush(stdout); parse_line("MOV R12, [R3];"); - printf("\n\n"); fflush(stdout); + printf("\n\n"); + fflush(stdout); parse_line("MOV R22, Truc[(3+2)*8];"); - printf("\n\n"); fflush(stdout); + printf("\n\n"); + fflush(stdout); parse_line("Trucmuche DB \"Test de chaîne complète avec des opérateurs comme le + et le - ...\""); - printf("\n\n"); fflush(stdout); + printf("\n\n"); + fflush(stdout); } #endif -- cgit v1.2.3