int sig;
while (*ref != '\0') {
- sig = *str++ - *ref++;
+ if (*ref == '\t') {
+ sig = (*str == '.') ? -1 : ((*str >= '0') && (*str <= '9'));
+ } else {
+ sig = *str - *ref;
+ }
if (sig != 0) {
return (sig > 0) ? 1 : -1;
}
+ str++;
+ ref++;
}
return 0;
/* functions */
-#define NB_OPERATORS 7
+#define NB_OPERATORS 5
keyword_t operators[NB_OPERATORS] = {
- { "+ ", Add, 2, 1 },
- { "+\t", Add, 2, 1 },
- { "- ", Sub, 2, 1 },
- { "- ", Sub, 2, 1 },
+ { "+\t", Add, 2, 1 },
+ { "-\t", Sub, 2, 1 },
{ "*", Mul, 2, 1 },
{ "/", Div, 2, 1 },
{ "^", Pow, 2, 1 }
/* parser function */
-element_t *parser (char *str) {
+element_t *parser (char *str, char **next)
+{
element_t *root = NULL;
int i;
+ VERBOSE (DEBUG, PRINTOUT ("Starting parsing\n"));
+
/* main loop */
while (*str != '\0') {
int found = 0;
element_t *new = NULL;
- VERBOSE (DEBUG, PRINTOUT ("Processing: %s\n", str));
+ VERBOSE (INFO, PRINTOUT ("Processing: %s\n", str));
/* skip spaces and tabs */
continue;
}
+ /* check for open bracket */
+
+ if (*str == '(') {
+ VERBOSE (DEBUG, PRINTOUT ("start processing bracket\n"));
+ if (root) {
+ do {
+ found = 0;
+ new = parser (str + 1, &str);
+ if (new == ERROR_OP) {
+ return ERROR_OP;
+ }
+ for (i = 0; i < root->nbops; i++) {
+ if (root->ops[i] == NULL) {
+ root->ops[i] = new;
+ found = 1;
+ break;
+ }
+ }
+ if (!found) {
+ return ERROR_OP;
+ }
+ } while (*str == ',');
+ } else {
+ root = newelement (Val, 1);
+ if (root == NULL) {
+ return ERROR_OP;
+ }
+ new = parser (str + 1, &str);
+ if ((new == ERROR_OP) || (*str == ',')) {
+ return ERROR_OP;
+ }
+ root->ops[0] = new;
+ }
+ str++;
+ VERBOSE (DEBUG, PRINTOUT ("stop processing bracket\n"));
+ continue;
+ }
+
+ /* check for closing bracket or koma */
+
+ if ((*str == ')') || (*str == ',')) {
+ if (next != NULL) {
+ *next = str;
+ }
+ return root;
+ }
+
/* look for operators */
for (i = 0; i < NB_OPERATORS; i++) {
keyword_t *operator = operators + i;
if (codecmp (operator->keyword, str) == 0) {
- if ((root) && (root->func == Val)) {
- VERBOSE (DEBUG, PRINTOUT ("Oper: %d\n", operator->func));
+ VERBOSE (DEBUG, PRINTOUT ("start processing operator\n"));
+ str += operator->offset;
+ if ((root) && (root->func != Set)) {
+ VERBOSE (INFO, 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);
+ new = parser (str, &str);
+ if (new == ERROR_OP) {
+ return ERROR_OP;
+ }
+ root->ops[1] = new;
+ } else {
+ return ERROR_OP;
}
- str += operator->offset;
found = 1;
+ VERBOSE (DEBUG, PRINTOUT ("stop processing operator\n"));
break;
}
}
if (found) {
- VERBOSE (DEBUG, PRINTOUT ("stop processing operator\n"));
continue;
}
-
+
/* look for functions */
for (i = 0; i < NB_FUNCTIONS; i++) {
keyword_t *function = functions + i;
if (codecmp (function->keyword, str) == 0) {
+ VERBOSE (DEBUG, PRINTOUT ("start processing function\n"));
if (root == NULL) {
- VERBOSE (DEBUG, PRINTOUT ("Func: %d\n", function->func));
+ VERBOSE (INFO, 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;
+ VERBOSE (DEBUG, PRINTOUT ("stop processing function\n"));
break;
}
}
if (found) {
- VERBOSE (DEBUG, PRINTOUT ("stop processing function\n"));
continue;
}
- /* last attend to detect addition and substraction */
-
- 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;
- }
- new->ops[0] = root;
- root = new;
- }
-
/* look for number */
if (((*str >= '0') && (*str <= '9')) ||
- (*str == '.') || (*str == '-') ||(*str == '+')) {
+ (*str == '.') || (*str == '+') || (*str == '-')) {
+ VERBOSE (DEBUG, PRINTOUT ("start processing value\n"));
char *pt;
float value = strtof (str, &pt);
- VERBOSE (DEBUG, PRINTOUT ("Value: %f\n", value));
+ VERBOSE (INFO, PRINTOUT ("Value: %f\n", value));
if (str != pt) {
new = newelement (Val, 1);
- new->value = value;
if (new == NULL) {
- return (element_t *)-1;
+ return ERROR_OP;
}
+ new->value = value;
if (root == NULL) {
root = new;
- } else {
- for (i = 0; i < root->nbops; i++) {
- if (root->ops[i] == NULL) {
- root->ops[i] = new;
- found = 1;
- break;
+ } else if (root->func == Val) {
+ if ((*str == '+') || (*str == '-')) {
+ element_t *add = newelement (Add, 2);
+ if (add == NULL) {
+ return ERROR_OP;
}
+ add->ops[0] = root;
+ add->ops[1] = new;
+ root = add;
+ } else {
+ return ERROR_OP;
}
- if (!found) {
- return (element_t *)-1;
- }
+ } else {
+ return ERROR_OP;
}
str = pt;
found = 1;
}
+ VERBOSE (DEBUG, PRINTOUT ("stop processing value\n"));
}
/* error */
if (!found) {
- return (element_t *)-1;
+ return ERROR_OP;
}
}
+ if (next != NULL) {
+ *next = str;
+ }
return root;
}
char *func = NULL;
int i;
- if (root == NULL)
+ if ((root == NULL) || (root == ERROR_OP)) {
return;
-
+ }
+
for (i = 0; i < level; i++) {
PRINTOUT (" ");
}
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;
PRINTOUT ("Function: %s\n", func);
- if (root->func == Val) {
+ if ((root->func == Val) && (root->ops[0] == NULL)) {
for (i = 0; i < level; i++) {
PRINTOUT (" ");
}