From: Laurent Mazet Date: Thu, 29 Dec 2022 03:53:32 +0000 (+0100) Subject: efficient priority solution X-Git-Tag: v0.8~63 X-Git-Url: https://secure.softndesign.org/git/?a=commitdiff_plain;h=ef37d966deba005de9def3ef3301634fe918c793;p=calc.git efficient priority solution --- diff --git a/calc.c b/calc.c index 9811642..b83bbd6 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 (INFO, PRINTOUT ("line(%d): %s\n", j, buffer + j)); - element_t *element = parser (buffer, NULL); + element_t *element = parser (buffer, NULL, 0); if (element == (void *)(-1)) { VERBOSE (WARNING, PRINTOUT ("error while parsing: %s\n", buffer)); ret = 1; @@ -145,6 +145,7 @@ int main (int argc, char *argv[]) // test: echo "log (2)" | calc.exe // test: echo "1 + 2 - 3" | calc.exe // test: echo "1 + cos (2 - 3)" | calc.exe +// test: echo "cos (1 / 2) * 3" | calc.exe // test: echo "1 + 4 * (2 - 3)" | calc.exe // test: echo "(2 - 3) / 4" | calc.exe // test: echo "pow (2 - 3, 8 / 3)" | calc.exe @@ -154,6 +155,8 @@ int main (int argc, char *argv[]) // 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 +// test: echo "2 ^ 3 * 4 + 5" | calc.exe +// test: echo "2 + 3 * 4 ^ 5" | calc.exe +// test: echo "2 ^ 3 * 4 + cos(5/6)" | calc.exe /* vim: set ts=4 sw=4 et: */ diff --git a/parser.c b/parser.c index 0391246..0caa750 100644 --- a/parser.c +++ b/parser.c @@ -69,7 +69,7 @@ keyword_t functions[NB_FUNCTIONS] = { /* parser function */ -element_t *parser (char *str, char **next) +element_t *parser (char *str, char **next, int prio) { element_t *root = NULL; int i; @@ -96,7 +96,7 @@ element_t *parser (char *str, char **next) if (root) { do { found = 0; - new = parser (str + 1, &str); + new = parser (str + 1, &str, 0); if (new == ERROR_OP) { return ERROR_OP; } @@ -116,7 +116,7 @@ element_t *parser (char *str, char **next) if (root == NULL) { return ERROR_OP; } - new = parser (str + 1, &str); + new = parser (str + 1, &str, 0); if ((new == ERROR_OP) || (*str == ',')) { return ERROR_OP; } @@ -142,29 +142,28 @@ element_t *parser (char *str, char **next) keyword_t *operator = operators + i; if (codecmp (operator->keyword, str) == 0) { VERBOSE (DEBUG, PRINTOUT ("start processing operator\n")); - str += operator->offset; if (root) { + if ((prio) && (prio > operator->prio)) { + VERBOSE (DEBUG, PRINTOUT ("stop processing operator because operator priority\n")); + *next = str; + return root; + } + str += operator->offset; VERBOSE (INFO, PRINTOUT ("Oper: %d\n", operator->func)); new = newelement (operator->func, operator->nbops, operator->prio); if (new == NULL) { return ERROR_OP; } - element_t *next = parser (str, &str); - if (next == ERROR_OP) { + new->ops[0] = root; + new->ops[1] = parser (str, &str, new->prio); + if (new->ops[1] == ERROR_OP) { return ERROR_OP; } - 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; + root = newelement (Val, 1, 4); + if (root == ERROR_OP) { + return ERROR_OP; } + root->ops[0] = new; } else { return ERROR_OP; } diff --git a/parser.h b/parser.h index 71fd33f..767fcf0 100644 --- a/parser.h +++ b/parser.h @@ -37,7 +37,7 @@ typedef struct _element_t { /* parser function */ -element_t *parser (char *str, char **next); +element_t *parser (char *str, char **next, int prio); void print_element (element_t *root, int level);