From 0b489a77ab06263674d1f4376c3bf6c2ead42cd6 Mon Sep 17 00:00:00 2001 From: Laurent Mazet Date: Sun, 25 Dec 2022 11:38:40 +0100 Subject: [PATCH] preliminary version --- calc.c | 2 +- makefile | 2 +- parser.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++---------- parser.h | 8 +++-- 4 files changed, 83 insertions(+), 20 deletions(-) diff --git a/calc.c b/calc.c index 5c57927..1c4099f 100644 --- a/calc.c +++ b/calc.c @@ -98,7 +98,7 @@ int main (int argc, char *argv[]) if (buffer[i] == '\n') { buffer[i] = 0; VERBOSE (DEBUG, PRINTOUT ("line(%d): %s\n", j, buffer + j)); - element_t *element = parser (buffer); + element_t *element = parser (buffer, NULL); if (element == (void *)(-1)) { VERBOSE (WARNING, PRINTOUT ("error while parsing: %s\n", buffer)); } else { diff --git a/makefile b/makefile index 772aca4..34218b4 100644 --- a/makefile +++ b/makefile @@ -22,7 +22,7 @@ ALLEXE += skel SHELL = bash -MAKE = mingw32-make +#MAKE = mingw32-make MAKEFLAGS += -s # Functions diff --git a/parser.c b/parser.c index 677f9a4..2190178 100644 --- a/parser.c +++ b/parser.c @@ -64,9 +64,10 @@ keyword_t functions[NB_FUNCTIONS] = { /* parser function */ -element_t *parser (char *str) { +element_t *parser (char *str, char **next) +{ element_t *root = NULL; - int i; + int i, j; /* main loop */ while (*str != '\0') { @@ -81,6 +82,57 @@ element_t *parser (char *str) { continue; } + /* skip commas */ + + if (*str == ',') { + if (root == NULL) { + return ERROR_OP; + } else if (root->func != Set) { + new = newelement (Set, MAX_OPERANDS); + new->ops[0] = root; + root = new; + } + str++; + continue; + } + + /* check for parent */ + + if (*str == ')') { + if (next != NULL) { + *next = str + 1; + } + return root; + } + if (*str == '(') { + new = parser (str + 1, &str); + if (new == (void *)(-1)) { + return new; + } + if (root) { + for (i = 0, j = 0; i < root->nbops; i++) { + if (root->ops[i] == NULL) { + if (new->func == Set) { + root->ops[i] = new->ops[j++]; + if (new->ops[j] == NULL) { + found = 1; + break; + } + } else { + root->ops[i] = new; + found = 1; + break; + } + } + } + if (!found) { + return ERROR_OP; + } + } else { + return root; + } + } + /* look for operators */ for (i = 0; i < NB_OPERATORS; i++) { @@ -90,12 +142,12 @@ element_t *parser (char *str) { VERBOSE (DEBUG, PRINTOUT ("Oper: %d\n", operator->func)); new = newelement (operator->func, operator->nbops); if (new == NULL) { - return (element_t *)-1; + return ERROR_OP; } new->ops[0] = root; root = new; } else { - return (element_t *)(-1); + return ERROR_OP; } str += operator->offset; found = 1; @@ -116,11 +168,11 @@ element_t *parser (char *str) { VERBOSE (DEBUG, PRINTOUT ("Func: %d\n", function->func)); new = newelement (function->func, function->nbops); if (new == NULL) { - return (element_t *)-1; + return ERROR_OP; } root = new; } else { - return (element_t *)(-1); + return ERROR_OP; } str += function->offset; found = 1; @@ -132,19 +184,19 @@ element_t *parser (char *str) { continue; } - /* last attend to detect addition and substraction */ + /* last attend to detect addition and substraction */ - if (((*str == '-') || (*str == '+')) && - ((*(str + 1) >= '0') && (*(str + 1) <= '9')) && - ((root) && (root->func == Val))) { + if (((*str == '-') || (*str == '+')) && + ((*(str + 1) >= '0') && (*(str + 1) <= '9')) && + ((root) && (root->func == Val))) { VERBOSE (DEBUG, PRINTOUT ("Oper: %d\n", Add)); new = newelement (Add, 2); if (new == NULL) { - return (element_t *)-1; + return ERROR_OP; } new->ops[0] = root; root = new; - } + } /* look for number */ @@ -157,11 +209,19 @@ element_t *parser (char *str) { new = newelement (Val, 1); new->value = value; if (new == NULL) { - return (element_t *)-1; + return ERROR_OP; } if (root == NULL) { root = new; } else { + if (root->func == Val) { + element_t *set = newelement (Set, MAX_OPERANDS); + if (set == NULL) { + return ERROR_OP; + } + set->ops[0] = root; + root = set; + } for (i = 0; i < root->nbops; i++) { if (root->ops[i] == NULL) { root->ops[i] = new; @@ -170,7 +230,7 @@ element_t *parser (char *str) { } } if (!found) { - return (element_t *)-1; + return ERROR_OP; } } str = pt; @@ -181,7 +241,7 @@ element_t *parser (char *str) { /* error */ if (!found) { - return (element_t *)-1; + return ERROR_OP; } } @@ -205,6 +265,7 @@ void print_element (element_t *root, int level) switch (root->func) { case Val: func = "Value"; break; + case Set: func = "Set"; break; case Add: func = "Addition"; break; case Sub: func = "Subtraction"; break; case Mul: func = "Multiplication"; break; diff --git a/parser.h b/parser.h index 4650007..7d486a3 100644 --- a/parser.h +++ b/parser.h @@ -4,7 +4,7 @@ /* function type */ typedef enum { - Val = 0, + Val = 0, Set, Add, Sub, Mul, Div, Pow, Sqr, @@ -23,7 +23,7 @@ typedef struct _keyword_t { /* calculus element type */ -#define MAX_OPERANDS 2 +#define MAX_OPERANDS 10 typedef struct _element_t { func_t func; int nbops; @@ -31,9 +31,11 @@ typedef struct _element_t { float value; } element_t; +#define ERROR_OP ((element_t *)(-1)) + /* parser function */ -element_t *parser (char *str); +element_t *parser (char *str, char **next); void print_element (element_t *root, int level); -- 2.30.2