From 11cda8d79e2b44c25c26e58f6bfe7c0bb421ee19 Mon Sep 17 00:00:00 2001 From: Laurent Mazet Date: Thu, 29 Dec 2022 04:25:06 +0100 Subject: [PATCH] partial priority solution --- calc.c | 5 ++++- parser.c | 58 +++++++++++++++++++++++++++++++++----------------------- parser.h | 2 ++ 3 files changed, 40 insertions(+), 25 deletions(-) diff --git a/calc.c b/calc.c index ba18700..9811642 100644 --- a/calc.c +++ b/calc.c @@ -151,6 +151,9 @@ int main (int argc, char *argv[]) // test: echo "1 + -2" | calc.exe // test: echo "1 - +2" | calc.exe // test: echo "-1 + +2" | calc.exe -// test: echo "-1 +2" | calc.exe +// test: echo "-1+2" | calc.exe +// test: echo "1-2" | calc.exe +// test: echo "1 * 2 / 3 + 4" | calc.exe +// test: echo "2 ^ 3 * 4 + cos (5)" | calc.exe /* vim: set ts=4 sw=4 et: */ diff --git a/parser.c b/parser.c index 8ddd83a..0391246 100644 --- a/parser.c +++ b/parser.c @@ -30,7 +30,7 @@ int codecmp (char *ref, char *str) /* allocate new element */ -element_t *newelement (func_t function, int nbops) +element_t *newelement (func_t function, int nbops, int prio) { element_t *new = (element_t *) calloc (1, sizeof (element_t)); if (new == NULL) { @@ -39,6 +39,7 @@ element_t *newelement (func_t function, int nbops) } new->func = function; new->nbops = nbops; + new->prio = prio; return new; } @@ -48,22 +49,22 @@ element_t *newelement (func_t function, int nbops) #define NB_OPERATORS 5 keyword_t operators[NB_OPERATORS] = { - { "+\t", Add, 2, 1 }, - { "-\t", Sub, 2, 1 }, - { "*", Mul, 2, 1 }, - { "/", Div, 2, 1 }, - { "^", Pow, 2, 1 } + { "+\t", Add, 2, 1, 1}, + { "-\t", Sub, 2, 1, 1}, + { "*", Mul, 2, 1, 2}, + { "/", Div, 2, 1, 2}, + { "^", Pow, 2, 1, 3} }; #define NB_FUNCTIONS 7 keyword_t functions[NB_FUNCTIONS] = { - { "sqrt", Sqr, 1, 4 }, - { "pow", Pow, 2, 3 }, - { "cos", Cos, 1, 3 }, - { "sin", Sin, 1, 3 }, - { "atan", Atn, 1, 4 }, - { "exp", Exp, 1, 3 }, - { "log", Log, 1, 3 } + { "sqrt", Sqr, 1, 4, 4}, + { "pow", Pow, 2, 3, 4}, + { "cos", Cos, 1, 3, 4}, + { "sin", Sin, 1, 3, 4}, + { "atan", Atn, 1, 4, 4}, + { "exp", Exp, 1, 3, 4}, + { "log", Log, 1, 3, 4} }; /* parser function */ @@ -111,7 +112,7 @@ element_t *parser (char *str, char **next) } } while (*str == ','); } else { - root = newelement (Val, 1); + root = newelement (Val, 1, 4); if (root == NULL) { return ERROR_OP; } @@ -142,19 +143,28 @@ element_t *parser (char *str, char **next) if (codecmp (operator->keyword, str) == 0) { VERBOSE (DEBUG, PRINTOUT ("start processing operator\n")); str += operator->offset; - if ((root) && (root->func != Set)) { + if (root) { VERBOSE (INFO, PRINTOUT ("Oper: %d\n", operator->func)); - new = newelement (operator->func, operator->nbops); + new = newelement (operator->func, operator->nbops, operator->prio); if (new == NULL) { return ERROR_OP; } - new->ops[0] = root; - root = new; - new = parser (str, &str); - if (new == ERROR_OP) { + element_t *next = parser (str, &str); + if (next == ERROR_OP) { return ERROR_OP; } - root->ops[1] = new; + VERBOSE (DEBUG, PRINTOUT ("Priorities: %d > %d -> %s\n", new->prio, next->prio, (new->prio > next->prio) ? "True" : "False")); + if (new->prio > next->prio) { + VERBOSE (DEBUG, PRINTOUT ("Take account of priority\n")); + new->ops[0] = root; + new->ops[1] = next->ops[0]; + next->ops[0] = new; + root = next; + } else { + new->ops[0] = root; + new->ops[1] = next; + root = new; + } } else { return ERROR_OP; } @@ -175,7 +185,7 @@ element_t *parser (char *str, char **next) VERBOSE (DEBUG, PRINTOUT ("start processing function\n")); if (root == NULL) { VERBOSE (INFO, PRINTOUT ("Func: %d\n", function->func)); - new = newelement (function->func, function->nbops); + new = newelement (function->func, function->nbops, function->prio); if (new == NULL) { return ERROR_OP; } @@ -202,7 +212,7 @@ element_t *parser (char *str, char **next) float value = strtof (str, &pt); VERBOSE (INFO, PRINTOUT ("Value: %f\n", value)); if (str != pt) { - new = newelement (Val, 1); + new = newelement (Val, 1, 4); if (new == NULL) { return ERROR_OP; } @@ -211,7 +221,7 @@ element_t *parser (char *str, char **next) root = new; } else if (root->func == Val) { if ((*str == '+') || (*str == '-')) { - element_t *add = newelement (Add, 2); + element_t *add = newelement (Add, 2, 1); if (add == NULL) { return ERROR_OP; } diff --git a/parser.h b/parser.h index 7d486a3..71fd33f 100644 --- a/parser.h +++ b/parser.h @@ -19,6 +19,7 @@ typedef struct _keyword_t { func_t func; int nbops; int offset; + int prio; } keyword_t; /* calculus element type */ @@ -29,6 +30,7 @@ typedef struct _element_t { int nbops; struct _element_t *ops[MAX_OPERANDS]; float value; + int prio; } element_t; #define ERROR_OP ((element_t *)(-1)) -- 2.30.2