]> git.llucax.com Git - z.facultad/75.42/calculadora.git/commitdiff
Andan (con pruebas moderadas) todos los parsers. Se separan algunas cosas. Se
authorLeandro Lucarella <llucax@gmail.com>
Tue, 16 Sep 2003 06:59:30 +0000 (06:59 +0000)
committerLeandro Lucarella <llucax@gmail.com>
Tue, 16 Sep 2003 06:59:30 +0000 (06:59 +0000)
corrigen bugs.

16 files changed:
Makefile
memdebug.c
parseerror.c
parser_common.c [new file with mode: 0644]
parser_common.h [new file with mode: 0644]
parser_equation.c
parser_expression.c
parser_expression.h
parser_expression_test.c [new file with mode: 0644]
parser_variable.c
parser_variable.h
parser_variable_test.c
strutil.c
strutil.h
variable_list.c [new file with mode: 0644]
variable_list.h [new file with mode: 0644]

index 9b31f1509e81740485f672d5d21a3ccc0a6e54b8..f860561d3ce70313ed9815dcf39a2425e0be537a 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -18,7 +18,8 @@ CFLAGS=-ansi -pedantic -Wall -g3 -DDEBUG
 CC=gcc-3.2
 
 # Pruebas.
 CC=gcc-3.2
 
 # Pruebas.
-TESTS=dllist_test memdebug_test parser_equation_test parser_variable_test
+TESTS=dllist_test memdebug_test parser_equation_test parser_variable_test \
+      parser_expression_test
 # Programa a compilar.
 TARGETS=$(TESTS)
 
 # Programa a compilar.
 TARGETS=$(TESTS)
 
@@ -30,15 +31,21 @@ tests: $(TESTS)
        ./dllist_test
        ./memdebug_test
        ./parser_equation_test 'a = 40'
        ./dllist_test
        ./memdebug_test
        ./parser_equation_test 'a = 40'
-       ./parser_variable_test 'a = 40'
+       ./parser_variable_test 'a 40 -50 0.11'
+       ./parser_expression_test '(3 + (-a)) * 2'
 
 dllist_test: dllist.o
 
 memdebug_test: dllist.o meminfo.o memdebug.o
 
 
 dllist_test: dllist.o
 
 memdebug_test: dllist.o meminfo.o memdebug.o
 
-parser_equation_test: dllist.o parseerror.o equation.o strutil.o parser_equation.o meminfo.o memdebug.o
+parser_equation_test: dllist.o strutil.o meminfo.o memdebug.o parseerror.o \
+       parser_common.o equation.o parser_equation.o
 
 
-parser_variable_test: dllist.o parseerror.o variable.o strutil.o parser_variable.o meminfo.o memdebug.o
+parser_variable_test: dllist.o strutil.o meminfo.o memdebug.o parseerror.o \
+       parser_common.o variable.o variable_list.o parser_variable.o
+
+parser_expression_test: dllist.o strutil.o meminfo.o memdebug.o parseerror.o \
+       parser_common.o variable.o variable_list.o parser_expression.o
 
 tp1: $(TARGETS)
 
 
 tp1: $(TARGETS)
 
index 30079adc62ece85b18bcfae1ed620e92bd7f0981..724f9cb6e1e66636c0e3b29154edcbed67da9b1e 100644 (file)
@@ -115,7 +115,7 @@ void memdebug_free(void* ptr) {
         DLList_remove_current(memdebug_list);
 #ifdef DEBUG
     } else {
         DLList_remove_current(memdebug_list);
 #ifdef DEBUG
     } else {
-        fprintf(stderr, "%s: No se encontro el ptr 0x%X en la lista.\n",
+        fprintf(stderr, "%s: No se encontró el ptr 0x%X en la lista.\n",
                 __FILE__, (size_t)ptr);
 #endif
     }
                 __FILE__, (size_t)ptr);
 #endif
     }
index 2b7147990a3a8af14fa87614cd7c99833e5a3412..038314df067c434c55141a23ccdb923f183e6880 100644 (file)
@@ -33,7 +33,9 @@ ParseError* ParseError_new(void) {
 
 void ParseError_delete(ParseError* pe) {
     if (pe) {
 
 void ParseError_delete(ParseError* pe) {
     if (pe) {
-        free(pe->message);
+        if (pe->message) {
+            free(pe->message);
+        }
     }
     free(pe);
 }
     }
     free(pe);
 }
@@ -83,10 +85,12 @@ size_t ParseError_print(ParseError* pe, FILE* fp) {
     if (!pe->pos) {
         /* Si hay mensaje. */
         if (pe->message) {
     if (!pe->pos) {
         /* Si hay mensaje. */
         if (pe->message) {
-            return fprintf(fp, "Error: %s.\n", pe->message);
+            return fprintf(fp, "Error en la línea %u: %s.\n", pe->line,
+                    pe->message);
         /* Si no hay mensaje. */
         } else {
         /* Si no hay mensaje. */
         } else {
-            return fprintf(fp, "Error no especificado.\n");
+            return fprintf(fp, "Error en la línea %u no especificado.\n",
+                    pe->line);
         }
     /* Es un error de interpretación en una posición específica. */
     } else {
         }
     /* Es un error de interpretación en una posición específica. */
     } else {
diff --git a/parser_common.c b/parser_common.c
new file mode 100644 (file)
index 0000000..2c0f988
--- /dev/null
@@ -0,0 +1,35 @@
+/* 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: mar sep 16 00:59:12 ART 2003
+ *
+ * $Id$
+ */
+
+#include "parser_common.h"
+#include "bool.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(char c) {
+    return is_number(c) || is_alpha(c);
+}
+
diff --git a/parser_common.h b/parser_common.h
new file mode 100644 (file)
index 0000000..faed17b
--- /dev/null
@@ -0,0 +1,30 @@
+/* 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: mar sep 16 01:00:39 ART 2003
+ *
+ * $Id$
+ */
+
+#ifndef PARSER_COMMON_H
+#define PARSER_COMMON_H
+
+#include "bool.h"
+
+bool is_space(char c);
+
+bool is_number(char c);
+
+bool is_alpha(char c);
+
+bool is_alpha_num(char c);
+
+#endif /* PARSER_COMMON_H */
index d76bd1dff577d8f3049541b4b72fb86b65578311..ebf36987c7d966e582b4361a0bc7b82e42f97990 100644 (file)
 
 #include "bool.h"
 #include "equation.h"
 
 #include "bool.h"
 #include "equation.h"
+#include "parser_common.h"
 #include "parseerror.h"
 #include "dllist.h"
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.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);
-}
+#include "memdebug_debugger.h"
 
 size_t DLList_equation_print(DLList* l, FILE* fp) {
     size_t cant = 0;
 
 size_t DLList_equation_print(DLList* l, FILE* fp) {
     size_t cant = 0;
index 37a4df445c8bcc3f4c627f697495850982712492..8ee6cc0030930d730acee4c662713298789e9bc5 100644 (file)
 
 #include "bool.h"
 #include "parseerror.h"
 
 #include "bool.h"
 #include "parseerror.h"
+#include "parser_common.h"
+#include "variable.h"
+#include "variable_list.h"
 #include "dllist.h"
 #include "dllist.h"
+#include "strutil.h"
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.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);
-}
+#include "memdebug_debugger.h"
 
 #define PARSE_ERROR(str) ParseError_set_pos_message(error, str, i + 1, c)
 
 
 #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;
+/**
+ * TODO: exp tiene que venir sin espacios.
+ * 
+ * @bug Los números negativos hay que ponerlos entre paréntesis si hay algún
+ *      operador de baja precedencia en el mismo nivel.
+ */
+bool parser_expression(const char* exp, size_t len, float* result, DLList*
+        var_list, ParseError* error) {
+    size_t level = 0;
     size_t i;
     char c;
     size_t i;
     char c;
+    char* exp_cuted;
+    char* err = NULL;
+    float result1;
+    float result2;
+    /* Si es vacío, devuelve cero. */
+    if (!len) {
+        *result = 0.0;
+        return TRUE;
+    }
     /* Si es una expresión numérica, la devolvemos directamente. */
     /* Si es una expresión numérica, la devolvemos directamente. */
-    *result = strntod(exp, len, &err);
+    if ((exp[0] == '(') && (exp[len-1] == ')')) {
+        /* Si está entre paréntesis, se los sacamos. */
+        exp_cuted = strutil_copy_fragment(exp, 1, len - 2);
+    } else {
+        exp_cuted = strutil_copy_fragment(exp, 0, len);
+    }
+    /* No se pudo alocar la memoria. */
+    if (!exp_cuted) {
+        ParseError_set_message(error, "No se pudo alocar memoria");
+        return FALSE;
+    }
+    /* Trato de convertirlo a float. */
+    *result = strtod(exp_cuted, &err);
     if (*err == '\0') { /* OK */
     if (*err == '\0') { /* OK */
-        return TRUE; /* La expresión es numérica (FIXME: puede ser numérica
-                        entre paréntesis y esto falla). */
+        free(exp_cuted);
+        return TRUE;
     }
     }
-    /* No es una expresión numérica, busco operadores de alta precedencia. */
+    /* No es un valor numérico, me fijo si está en la lista de variables. */
+    if (DLList_variable_find(var_list, exp_cuted)) {
+        *result = ((Variable*)DLList_current(var_list))->value;
+        free(exp_cuted);
+        return TRUE;
+    }
+    free(exp_cuted);
+    /* No es una expresión numérica ni una variable, busco operadores de alta
+     * precedencia. */
     for (i = 0; i < len; i++) {
         c = exp[i];
     for (i = 0; i < len; i++) {
         c = exp[i];
+        /* Manejo los niveles de paréntesis. */
         if ((c == '(')) {
             level++;
         } else if (c == ')') {
             level--;
         if ((c == '(')) {
             level++;
         } else if (c == ')') {
             level--;
+        /* Está en el nivel básico y hay un operador. */
         } else if (((c == '+') || (c == '-')) && !level) {
         } else if (((c == '+') || (c == '-')) && !level) {
-            /* FIXME: Es una operador => segundo operando. */
-            if (!parser_expression(exp, i - 1, result1, error)) {
+            /* No hay segundo operando. */
+            if (i == len - 1) {
+                ParseError_set_message(error, "Falta segundo operando");
                 return FALSE;
             }
                 return FALSE;
             }
-            /* FIXME: verificar que no este vacío el segundo operando. */
-            if (!parser_expression(exp + i + 1, len - i - 1, result2, error)) {
+            /* Calcula la expresión del primer operando. */
+            if (!parser_expression(exp, i, &result1, var_list, error)) {
+                /* Si hay error, devuelve FALSE (y "arrastra" el error. */
                 return FALSE;
             }
                 return FALSE;
             }
-        } else if (((c == '+') || (c == '-')) && !level) {
-        } else { /* es otra cosa => error */
-            PARSE_ERROR("un espacio o una letra");
-            return FALSE;
+            /* Calcula la expresión del segundo operando. */
+            if (!parser_expression(exp + i + 1, len - i - 1, &result2,
+                        var_list, error)) {
+                /* Si hay error, devuelve FALSE (y "arrastra" el error. */
+                return FALSE;
+            }
+            *result = (c == '+') ? (result1 + result2) : (result1 - result2);
+            return TRUE;
+        }
+    }
+    /* No hay tampoco operadores de alta precendencia, busco operadores de baja
+     * precedencia. */
+    for (i = 0; i < len; i++) {
+        c = exp[i];
+        /* Manejo los niveles de paréntesis. */
+        if ((c == '(')) {
+            level++;
+        } else if (c == ')') {
+            level--;
+        /* Está en el nivel básico y hay un operador. */
+        } else if (((c == '*') || (c == '/')) && !level) {
+            /* No hay segundo operando. */
+            if (i == len - 1) {
+                ParseError_set_message(error, "Falta segundo operando");
+                return FALSE;
+            }
+            /* Calcula la expresión del primer operando. */
+            if (!parser_expression(exp, i, &result1, var_list, error)) {
+                /* Si hay error, devuelve FALSE (y "arrastra" el error. */
+                return FALSE;
+            }
+            /* Calcula la expresión del segundo operando. */
+            if (!parser_expression(exp + i + 1, len - i - 1, &result2,
+                        var_list, error)) {
+                /* Si hay error, devuelve FALSE (y "arrastra" el error. */
+                return FALSE;
+            }
+            /* Si estamos dividiendo, chequeamos que el divisor no sea cero. */
+            if (c == '/') {
+                /* Segundo operando es cero. */
+                if (result2 == 0.0) {
+                    ParseError_set_message(error, "División por cero");
+                    return FALSE;
+                }
+                *result = result1 / result2;
+            /* Si estamos multiplicando, no hay chequeos extra. */
+            } else {
+                *result = result1 * result2;
+            }
+            return TRUE;
         }
     }
         }
     }
-    /* 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;
+    /* Si no tiene operadores ni valores numéricos ni es una variable, pero está
+     * entre paréntesis, pruebo de evaluar lo que está dentro de los paréntesis.
+     */
+    if ((exp[0] == '(') && (exp[len-1] == ')')) {
+        if (!parser_expression(exp + 1, len - 2, result, var_list, error)) {
+            /* Si hay error, devuelve FALSE (y "arrastra" el error. */
+            return FALSE;
+        } else {
+            return TRUE;
+        }
     }
     }
+    /* Si no tiene operadores ni valores numéricos ni es una variable, es un
+     * error. */
+    ParseError_set_message(error, "La expresión es incorrecta");
     return FALSE;
 }
 
     return FALSE;
 }
 
index c14470483ab6ece3742a094fa5c7caa1201b51e3..b09ac5e7d350c4df210e5a0af14d53987547116e 100644 (file)
@@ -9,39 +9,26 @@
  * Puede copiar, modificar y distribuir este programa bajo los términos de
  * la licencia GPL (http://www.gnu.org/).
  *
  * 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
+ * Creado: mar sep 16 02:39:32 ART 2003
  *
  * $Id$
  */
 
  *
  * $Id$
  */
 
-#ifndef PARSER_EQUATION_H
-#define PARSER_EQUATION_H
+#ifndef PARSER_EXPRESSION_H
+#define PARSER_EXPRESSION_H
 
 #include "bool.h"
 #include "parseerror.h"
 #include "dllist.h"
 #include <stdlib.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.
+/**
+ * TODO: exp tiene que venir sin espacios.
+ * 
+ * @bug Los números negativos hay que ponerlos entre paréntesis si hay algún
+ *      operador de baja precedencia en el mismo nivel.
  */
  */
-bool parser_equation(const char* line, size_t len, DLList* equation_list,
-        ParseError* error);
+bool parser_expression(const char* exp, size_t len, float* result, DLList*
+        var_list, ParseError* error);
 
 
-#endif /* PARSER_EQUATION_H */
+#endif /* PARSER_EXPRESSION_H */
diff --git a/parser_expression_test.c b/parser_expression_test.c
new file mode 100644 (file)
index 0000000..6f58f58
--- /dev/null
@@ -0,0 +1,104 @@
+/* vim: set et sts=4 sw=4 fdm=indent fdl=1 fdn=0 fo+=t:
+ *
+ * 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: mar sep 16 02:24:44 ART 2003
+ *
+ * $Id$
+ */
+
+/**
+ * \file
+ *      Hace varios chequeos para probar si anda bien la función
+ *      parser_expression().
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "memdebug_debugger.h"
+#include "parser_expression.h"
+#include "variable.h"
+#include "variable_list.h"
+#include "strutil.h"
+
+/**
+ * Programa para probar parser_expression().
+ *
+ * \return EXIT_SUCCESS si se realizó bien, EXIT_FAILURE si no.
+ */
+int main(int argc, char* argv[]) {
+    /* Declaración de variables. */
+    int i;
+    float result;
+    DLList* lista;
+    Variable* var;
+    char* arg;
+    ParseError* error;
+
+    if (argc < 2) {
+        fprintf(stderr, "Debe pasar expresiones a evaluar como parámetros.\n");
+        fprintf(stderr, "Ejemplo: %s ' (50 +  10 ) *2/(-1)'\n", argv[0]);
+        return EXIT_FAILURE;
+    }
+
+    lista = DLList_new();
+    if (!lista) {
+        fprintf(stderr, "No se pudo crear la lista.\n");
+        return EXIT_FAILURE;
+    }
+
+    var = Variable_new("a", 0, 3);
+    if (!var) {
+        fprintf(stderr, "No se pudo crear la variable.\n");
+        return EXIT_FAILURE;
+    }
+    Variable_set_value(var, "5", 0, 1);
+
+    if (!DLList_push(lista, var)) {
+        fprintf(stderr, "No se pudo agregar variable a la lista.\n");
+        return EXIT_FAILURE;
+    }
+
+    DLList_variable_print(lista, stdout);
+
+    error = ParseError_new();
+    if (!error) {
+        fprintf(stderr, "No se pudo crear el error.\n");
+        return EXIT_FAILURE;
+    }
+
+    for (i = 1; i < argc; i++) {
+        arg = strutil_copy_stripspaces(argv[i], strlen(argv[i]));
+        if (!arg) {
+            fprintf(stderr, "No se pudo crear copia de argv[%u].\n", i);
+            return EXIT_FAILURE;
+        }
+        if (!parser_expression(arg, strlen(arg), &result, lista,
+                    error)) {
+            error->line = i;
+            ParseError_print(error, stderr);
+        } else {
+            printf("Resultado %u: %f\n", i, result);
+        }
+        free(arg);
+    }
+
+    DLList_variable_delete(lista);
+
+    ParseError_delete(error);
+
+    /* Veo si pierdo memoria. */
+    memdebug_end();
+
+    return EXIT_SUCCESS;
+}
+
index fadb965f1557417d3c1304db1a46ce42e013bcb7..cf9a0269ab0b735b60c64a349409b4ecc5c88574 100644 (file)
  * $Id$
  */
 
  * $Id$
  */
 
+#include "parser_variable.h"
 #include "bool.h"
 #include "variable.h"
 #include "bool.h"
 #include "variable.h"
-#include "parser_variable.h"
+#include "variable_list.h"
+#include "parser_common.h"
 #include "parseerror.h"
 #include "dllist.h"
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.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);
-}
-
-bool DLList_variable_find(DLList* l, Variable* var) {
-    Variable* v;
-    for (v = DLList_begin(l); DLList_have_more(l); v = DLList_next(l)) {
-        if (!strcmp(v->variable, var->variable)) {
-            return TRUE;
-        }
-    }
-    return FALSE;
-}
-
-size_t DLList_variable_print(DLList* l, FILE* fp) {
-    size_t cant = 0;
-    Variable* v;
-    for (v = DLList_begin(l); DLList_have_more(l); v = DLList_next(l)) {
-        cant += Variable_print(v, fp);
-    }
-    return cant;
-}
-
-void DLList_variable_delete(DLList* l) {
-    if (l) {
-        while (!DLList_empty(l)) {
-            Variable_delete((Variable*)DLList_pop(l));
-        }
-    }
-    DLList_delete(l);
-}
+#include "memdebug_debugger.h"
 
 #define PARSE_ERROR(str) ParseError_set_pos_message(error, str, i + 1, c)
 
 
 #define PARSE_ERROR(str) ParseError_set_pos_message(error, str, i + 1, c)
 
@@ -238,7 +198,7 @@ bool parser_variable(const char* line, size_t len, DLList* variable_list,
         return FALSE;
     }
     /* Ahora sí, la puedo agregar a la lista de variables. */
         return FALSE;
     }
     /* Ahora sí, la puedo agregar a la lista de variables. */
-    if (DLList_variable_find(variable_list, var)) {
+    if (DLList_variable_find(variable_list, var->variable)) {
         /* Si ya había uno, lo borro. */
         DLList_remove_current(variable_list);
     }
         /* Si ya había uno, lo borro. */
         DLList_remove_current(variable_list);
     }
index 91cf0fe56f35b70a9e3275d2b34ad8b81f10f278..478b6a20b5e717935625de2e881200e2dd2813c1 100644 (file)
 #include "dllist.h"
 #include <stdlib.h>
 
 #include "dllist.h"
 #include <stdlib.h>
 
-size_t DLList_variable_print(DLList* l, FILE* fp);
-
-void DLList_variable_delete(DLList* l);
-
 bool parser_variable(const char* line, size_t len, DLList* variable_list,
         ParseError* error);
 
 bool parser_variable(const char* line, size_t len, DLList* variable_list,
         ParseError* error);
 
index c682d93834f697fc71846109d15742a6df19f477..f733fc61239cfc39717de319850dda55ece90959 100644 (file)
@@ -25,6 +25,7 @@
 #include <string.h>
 
 #include "memdebug_debugger.h"
 #include <string.h>
 
 #include "memdebug_debugger.h"
+#include "variable_list.h"
 #include "parser_variable.h"
 
 /**
 #include "parser_variable.h"
 
 /**
index 48ec6f2c0eff1e0b9a1db330d44932109eea8632..8a84d43093cb1314867755b62e9bc3f89955bd5a 100644 (file)
--- a/strutil.c
+++ b/strutil.c
@@ -15,6 +15,7 @@
  */
 
 #include "strutil.h"
  */
 
 #include "strutil.h"
+#include "parser_common.h"
 #include <stdlib.h>
 #include <string.h>
 
 #include <stdlib.h>
 #include <string.h>
 
@@ -28,7 +29,24 @@ char* strutil_copy_fragment(const char* orig, size_t start, size_t len) {
         strncpy(new, orig + start, len);
         /* Termino la cadena. */
         new[len] = '\0';
         strncpy(new, orig + start, len);
         /* Termino la cadena. */
         new[len] = '\0';
-    /* Si no pude reservar la memoria, devuelvo NULL. */
+    }
+    return new;
+}
+
+char* strutil_copy_stripspaces(const char* orig, size_t len) {
+    size_t i = 0;
+    size_t j = 0;
+    /* Reservo el espacio (incluyendo el caracter nulo). */
+    char* new = malloc(sizeof(char) * (len + 1));
+    if (new) {
+        /* Copio caracteres que no sean espacios. */
+        for (i = 0; i < len; i++) {
+            if (!is_space(orig[i])) {
+                new[j++] = orig[i];
+            }
+        }
+        /* Termino la cadena. */
+        new[j] = '\0';
     }
     return new;
 }
     }
     return new;
 }
index 6da0a37b3327d49a3d64fbf80e94bfb291a424fe..209308a0683399cf8023787144d34d3b50ea5274 100644 (file)
--- a/strutil.h
+++ b/strutil.h
@@ -25,4 +25,9 @@
  */
 char* strutil_copy_fragment(const char* orig, size_t start, size_t len);
 
  */
 char* strutil_copy_fragment(const char* orig, size_t start, size_t len);
 
+/**
+ * Copia un fragmento de una cadena eliminando los espacios.
+ */
+char* strutil_copy_stripspaces(const char* orig, size_t len);
+
 #endif /* STRUTIL_H */
 #endif /* STRUTIL_H */
diff --git a/variable_list.c b/variable_list.c
new file mode 100644 (file)
index 0000000..0919e7f
--- /dev/null
@@ -0,0 +1,54 @@
+/* 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: mar sep 16 01:59:36 ART 2003
+ *
+ * $Id$
+ */
+
+#include "bool.h"
+#include "dllist.h"
+#include "variable.h"
+#include "variable_list.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "memdebug_debugger.h"
+
+bool DLList_variable_find(DLList* l, const char* var) {
+    Variable* v;
+    for (v = DLList_begin(l); DLList_have_more(l); v = DLList_next(l)) {
+        if (!strcmp(v->variable, var)) {
+            return TRUE;
+        }
+    }
+    return FALSE;
+}
+
+size_t DLList_variable_print(DLList* l, FILE* fp) {
+    size_t cant = 0;
+    Variable* v;
+    for (v = DLList_begin(l); DLList_have_more(l); v = DLList_next(l)) {
+        cant += Variable_print(v, fp);
+    }
+    return cant;
+}
+
+void DLList_variable_delete(DLList* l) {
+    if (l) {
+        while (!DLList_empty(l)) {
+            Variable_delete((Variable*)DLList_pop(l));
+        }
+    }
+    DLList_delete(l);
+}
+
diff --git a/variable_list.h b/variable_list.h
new file mode 100644 (file)
index 0000000..6395d98
--- /dev/null
@@ -0,0 +1,31 @@
+/* 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: mar sep 16 02:01:55 ART 2003
+ *
+ * $Id$
+ */
+
+#ifndef VARIABLE_LIST_H
+#define VARIABLE_LIST_H
+
+#include "bool.h"
+#include "dllist.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+bool DLList_variable_find(DLList* l, const char* var);
+
+size_t DLList_variable_print(DLList* l, FILE* fp);
+
+void DLList_variable_delete(DLList* l);
+
+#endif /* VARIABLE_LIST_H */