efficient priority solution
authorLaurent Mazet <mazet@softndesign.org>
Thu, 29 Dec 2022 03:53:32 +0000 (04:53 +0100)
committerLaurent Mazet <mazet@softndesign.org>
Thu, 29 Dec 2022 03:53:32 +0000 (04:53 +0100)
calc.c
parser.c
parser.h

diff --git a/calc.c b/calc.c
index 9811642f46e6bfe07559a3c1e3e1f3447837cdbd..b83bbd6af9f91ab16a971a6cb0339305e1de0950 100644 (file)
--- 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: */
index 0391246e5e6b9334e9b545d7b6e44a91baebf9ac..0caa750c65020c7f490c3da51ed64b7a82e8a0b5 100644 (file)
--- 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;
                 }
index 71fd33ffb34b8c8aff27c1a6e7dfb9217b960bcb..767fcf08bdc848c6005157f22368744e5b9e7ea7 100644 (file)
--- 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);