]> git.llucax.com Git - z.facultad/75.42/calculadora.git/commitdiff
Primera version (muy prematura) del parser de expresiones.
authorLeandro Lucarella <llucax@gmail.com>
Tue, 16 Sep 2003 02:15:19 +0000 (02:15 +0000)
committerLeandro Lucarella <llucax@gmail.com>
Tue, 16 Sep 2003 02:15:19 +0000 (02:15 +0000)
parser_expression.c [new file with mode: 0644]
parser_expression.h [new file with mode: 0644]

diff --git a/parser_expression.c b/parser_expression.c
new file mode 100644 (file)
index 0000000..588027c
--- /dev/null
@@ -0,0 +1,114 @@
+/* vim: set et sts=4 sw=4 fdm=indent fdl=1 fdn=0 fo+=t tw=80:
+ *
+ * Taller de Programación (75.42).
+ *
+ * Ejercicio Número 2:
+ * Programa calculadora.
+ *
+ * Copyleft 2003 - Leandro Lucarella <llucare@fi.uba.ar>
+ * Puede copiar, modificar y distribuir este programa bajo los términos de
+ * la licencia GPL (http://www.gnu.org/).
+ *
+ * Creado: dom sep 14 13:03:49 ART 2003
+ *
+ * $Id: parser_equation.c 50 2003-09-15 06:44:27Z luca $
+ */
+
+#include "bool.h"
+#include "parseerror.h"
+#include "dllist.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+bool is_space(char c) {
+    return (c == ' ') || (c == '\t');
+}
+
+bool is_number(char c) {
+    return ('0' <= c) && (c <= '9');
+}
+
+bool is_alpha(char c) {
+    return (c == '_') || (('a' <= c) && (c <= 'z')) || (('A' <= c) && (c <= 'Z'));
+}
+
+bool is_alpha_num(c) {
+    return is_number(c) || is_alpha(c);
+}
+
+size_t DLList_equation_print(DLList* l, FILE* fp) {
+    size_t cant = 0;
+    Equation* eq;
+    for (eq = DLList_begin(l); DLList_have_more(l); eq = DLList_next(l)) {
+        cant += Equation_print(eq, fp);
+    }
+    return cant;
+}
+
+void DLList_equation_delete(DLList* l) {
+    if (l) {
+        while (!DLList_empty(l)) {
+            Equation_delete((Equation*)DLList_pop(l));
+        }
+    }
+    DLList_delete(l);
+}
+
+#define PARSE_ERROR(str) ParseError_set_pos_message(error, str, i + 1, c)
+
+bool parser_expression(const char* exp, size_t len, float* result,
+        ParseError* error) {
+    enum {SEARCH_VAR, VAR, SEARCH_EQUAL, EXP} state = SEARCH_VAR;
+    size_t var_start = 0;
+    size_t var_len = 0;
+    size_t i;
+    char c;
+    /* Si es una expresión numérica, la devolvemos directamente. */
+    *result = strntod(exp, len, &err);
+    if (*err == '\0') { /* OK */
+        return TRUE; /* La expresión es numérica (FIXME: puede ser numérica
+                        entre paréntesis y esto falla). */
+    }
+    /* No es una expresión numérica, busco operadores de alta precedencia. */
+    for (i = 0; i < len; i++) {
+        c = exp[i];
+        if ((c == '(')) {
+            level++;
+        } else if (c == ')') {
+            level--;
+        } else if (((c == '+') || (c == '-')) && !level) {
+            /* FIXME: Es una operador => segundo operando. */
+            if (!parser_expression(exp, i - 1, result1, error)) {
+                return FALSE;
+            }
+            /* FIXME: verificar que no este vacío el segundo operando. */
+            if (!parser_expression(exp + i + 1, len - i - 1, result2, error)) {
+                return FALSE;
+            }
+        } else if (((c == '+') || (c == '-')) && !level) {
+        } else { /* es otra cosa => error */
+            PARSE_ERROR("un espacio o una letra");
+            return FALSE;
+        }
+    }
+    /* Error, no se llego a parsear todo bien. */
+    error->pos = len;
+    switch (state) {
+        case SEARCH_VAR:
+            ParseError_set_message(error,
+                    "No se encontró la definición de una variable");
+            break;
+        case VAR:
+        case SEARCH_EQUAL:
+            ParseError_set_message(error, "No se encontró un igual");
+            break;
+        case EXP:
+            ParseError_set_message(error, "No se encontró una expresión");
+            break;
+    }
+    return FALSE;
+}
+
+#undef PARSE_ERROR /* Sólo queremos usarlo en este fragmento */
+
diff --git a/parser_expression.h b/parser_expression.h
new file mode 100644 (file)
index 0000000..7c9d12b
--- /dev/null
@@ -0,0 +1,47 @@
+/* vim: set et sts=4 sw=4 fdm=indent fdl=1 fdn=1 fo+=t tw=80:
+ *
+ * Taller de Programación (75.42).
+ *
+ * Ejercicio Número 2:
+ * Programa calculadora.
+ *
+ * Copyleft 2003 - Leandro Lucarella <llucare@fi.uba.ar>
+ * Puede copiar, modificar y distribuir este programa bajo los términos de
+ * la licencia GPL (http://www.gnu.org/).
+ *
+ * Creado: lun sep 15 01:26:35 ART 2003
+ *
+ * $Id: parser_equation.h 50 2003-09-15 06:44:27Z luca $
+ */
+
+#ifndef PARSER_EQUATION_H
+#define PARSER_EQUATION_H
+
+#include "bool.h"
+#include "parseerror.h"
+#include "dllist.h"
+#include <stdlib.h>
+
+size_t DLList_equation_print(DLList* l, FILE* fp);
+
+void DLList_equation_delete(DLList* l);
+
+/* TODO:
+ *
+ * opcion1:
+ *   que devuelva la posición en donde empieza la exresión o cero si hubo
+ *   error. En otro lugar debe dejar la variable que se parseo.
+ *
+ * opcion2: <---------------------------- Creo que es la mejor.
+ *   Que devuelva una estructura con
+ *     - variable.
+ *     - expresion.
+ *
+ * opcion3:
+ *   Que devuelva una estructura de nodo de variable o de ecuacion segun como
+ *   se la llame.
+ */
+bool parser_equation(const char* line, size_t len, DLList* equation_list,
+        ParseError* error);
+
+#endif /* PARSER_EQUATION_H */