También se agregan algunas funciones de impresión.
CC=gcc-3.2
# Pruebas.
-TESTS=dllist_test memdebug_test
+TESTS=dllist_test memdebug_test parser_equation_test
# Programa a compilar.
TARGETS=$(TESTS)
memdebug_test: dllist.o meminfo.o memdebug.o
+parser_equation_test: dllist.o parseerror.o equation.o parser_equation.o
+
tp1: $(TARGETS)
# Regla para borrar.
free(eq);
}
+size_t Equation_print(Equation* eq, FILE* fp) {
+ return fprintf(fp, "%s = %s\n", eq->variable, eq->expression);
+}
+
#ifndef EQUATION_H
#define EQUATION_H
-/*#include "bool.h"*/
#include <stdlib.h>
+#include <stdio.h>
typedef struct {
char* variable;
void Equation_delete(Equation* eq);
+size_t Equation_print(Equation* eq, FILE* fp);
+
#endif /* EQUATION_H */
bool ParseError_set_pos_message(ParseError* pe, const char* msg, size_t pos,
char wrong_char) {
+ /* Pongo la posición */
+ pe->pos = pos;
/* Si había otro mensaje, liberamos la memoria */
if (pe->message) {
free(pe->message);
if (pe->message) {
/* Copio el nuevo mensaje. */
sprintf(pe->message, "Se buscaba %s pero se encontró '%c' (0x%02X)",
- msg, wrong_char, pos);
+ msg, wrong_char, wrong_char);
}
return pe->message ? TRUE : FALSE;
}
+size_t ParseError_print(ParseError* pe, FILE* fp) {
+ /* No es un error de interpretación específico. */
+ if (!pe->pos) {
+ /* Si hay mensaje. */
+ if (pe->message) {
+ return fprintf(fp, "Error: %s.\n", pe->message);
+ /* Si no hay mensaje. */
+ } else {
+ return fprintf(fp, "Error no especificado.\n");
+ }
+ /* Es un error de interpretación en una posición específica. */
+ } else {
+ /* Si hay mensaje. */
+ if (pe->message) {
+ return fprintf(fp, "Error en la línea %u, posición %u: %s.\n",
+ pe->line, pe->pos, pe->message);
+ /* Si no hay mensaje. */
+ } else {
+ return fprintf(fp,
+ "Error en la línea %u, posición %u no especificado.\n",
+ pe->line, pe->pos);
+ }
+ }
+}
#include "bool.h"
#include <stdlib.h>
+#include <stdio.h>
typedef struct {
size_t line;
bool ParseError_set_pos_message(ParseError* pe, const char* msg, size_t pos,
char wrong_char);
+size_t ParseError_print(ParseError* pe, FILE* fp);
+
#endif /* PARSEERROR_H */
}
bool is_number(char c) {
- return ('0' < c) && (c < '9');
+ return ('0' <= c) && (c <= '9');
}
bool is_alpha(char c) {
- return (c == '_') || (('a' < c) && (c < 'z')) || (('A' < c) && (c < 'Z'));
+ return (c == '_') || (('a' <= c) && (c <= 'z')) || (('A' <= c) && (c <= 'Z'));
}
bool is_alpha_num(c) {
return is_number(c) || is_alpha(c);
}
-#define PARSE_ERROR(str) ParseError_set_pos_message(error, str, i, 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;
+}
+
+#define PARSE_ERROR(str) ParseError_set_pos_message(error, str, i + 1, c)
bool parser_equation(const char* line, size_t len, DLList* equation_list,
ParseError* error) {
char c;
Equation* eq;
for (i = 0; i < len; i++) {
+ c = line[i];
switch (state) {
case SEARCH_VAR: /* Busca el comienzo de una variable. */
if (!is_space(c)) {
} else if (c == '=') {
/* Es igual, empieza la expresión. */
state = EXP;
+ /* Calculo la longitud de la variable. */
+ var_len = i - var_start;
} else { /* es otra cosa */
PARSE_ERROR(
"un espacio, una letra, un número o un igual");
#include "dllist.h"
#include <stdlib.h>
+size_t DLList_equation_print(DLList* l, FILE* fp);
+
/* TODO:
*
* opcion1:
--- /dev/null
+/* 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: sáb ago 30 18:24:31 ART 2003
+ *
+ * $Id$
+ */
+
+/**
+ * \file
+ * Hace varios chequeos para probar si anda bien la función
+ * parser_equation().
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "memdebug_debugger.h"
+#include "parser_equation.h"
+
+/**
+ * Programa para probar parser_equation().
+ *
+ * \return EXIT_SUCCESS si se realizó bien, EXIT_FAILURE si no.
+ */
+int main(int argc, char* argv[]) {
+ /* Declaración de variables. */
+ DLList* lista;
+ ParseError* error;
+
+ if (argc != 2) {
+ fprintf(stderr, "Debe pasar la ecuación a evaluar como parámetro.\n");
+ fprintf(stderr, "Ejemplo: %s 'b = 50 + h*2'\n", argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ lista = DLList_new();
+ if (!lista) {
+ fprintf(stderr, "No se pudo crear la lista.\n");
+ return EXIT_FAILURE;
+ }
+
+ error = ParseError_new();
+ if (!error) {
+ fprintf(stderr, "No se pudo crear el error.\n");
+ return EXIT_FAILURE;
+ }
+
+ if (!parser_equation(argv[1], strlen(argv[1]), lista, error)) {
+ ParseError_print(error, stderr);
+ return EXIT_FAILURE;
+ }
+
+ DLList_equation_print(lista, stdout);
+
+ DLList_delete(lista);
+
+ return EXIT_SUCCESS;
+}
+