]> git.llucax.com Git - z.facultad/75.42/calculadora.git/blob - parser_equation.c
Versión preliminar del programa del TP. Falta evaluar ecuaciones.
[z.facultad/75.42/calculadora.git] / parser_equation.c
1 /* vim: set et sts=4 sw=4 fdm=indent fdl=1 fdn=0 fo+=t tw=80:
2  *
3  * Taller de Programación (75.42).
4  *
5  * Ejercicio Número 2:
6  * Programa calculadora.
7  *
8  * Copyleft 2003 - Leandro Lucarella <llucare@fi.uba.ar>
9  * Puede copiar, modificar y distribuir este programa bajo los términos de
10  * la licencia GPL (http://www.gnu.org/).
11  *
12  * Creado: dom sep 14 13:03:49 ART 2003
13  *
14  * $Id$
15  */
16
17 #include "bool.h"
18 #include "equation.h"
19 #include "parser_common.h"
20 #include "parseerror.h"
21 #include "dllist.h"
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
25
26 #include "memdebug_debugger.h"
27
28 size_t DLList_equation_print(DLList* l, FILE* fp) {
29     size_t cant = 0;
30     Equation* eq;
31     for (eq = DLList_begin(l); DLList_have_more(l); eq = DLList_next(l)) {
32         cant += Equation_print(eq, fp);
33     }
34     return cant;
35 }
36
37 void DLList_equation_delete(DLList* l) {
38     if (l) {
39         while (!DLList_empty(l)) {
40             Equation_delete((Equation*)DLList_pop(l));
41         }
42     }
43     DLList_delete(l);
44 }
45
46 #define PARSE_ERROR(str) ParseError_set_pos_message(error, str, i + 1, c)
47
48 bool parser_equation(const char* line, size_t len, DLList* equation_list,
49         ParseError* error) {
50     enum {SEARCH_VAR, VAR, SEARCH_EQUAL, EXP} state = SEARCH_VAR;
51     size_t var_start = 0;
52     size_t var_len = 0;
53     size_t i;
54     char c;
55     Equation* eq;
56     for (i = 0; i < len; i++) {
57         c = line[i];
58         switch (state) {
59             case SEARCH_VAR: /* Busca el comienzo de una variable. */
60                 if (!is_space(c)) {
61                     if (is_alpha(c)) {
62                         /* Es una letra => es el comienzo de la variable. */
63                         state = VAR;
64                         var_start = i;
65                     } else { /* es otra cosa => error */
66                         PARSE_ERROR("un espacio o una letra");
67                         return FALSE;
68                     }
69                 }
70                 /* Si es espacio, no hace nada, deja que siga. */
71                 break;
72             case VAR: /* Se fija cual es el nombre de la variable. */
73                 if (!is_alpha_num(c)) {
74                     if (is_space(c)) {
75                         /* Es un espacio, entonces hay que buscar un igual. */
76                         state = SEARCH_EQUAL;
77                         /* Calculo la longitud de la variable. */
78                         var_len = i - var_start;
79                     } else if (c == '=') {
80                         /* Es igual, empieza la expresión. */
81                         state = EXP;
82                         /* Calculo la longitud de la variable. */
83                         var_len = i - var_start;
84                     } else { /* es otra cosa */
85                         PARSE_ERROR(
86                                 "un espacio, una letra, un número o un igual");
87                         return FALSE;
88                     }
89                 }
90                 /* Si es alfanumérico, no hace nada, deja que siga. */
91                 break;
92             case SEARCH_EQUAL: /* Busca un signo de igual. */
93                 if (!is_space(c)) {
94                     if (c == '=') {
95                         /* Es igual, empieza la expresión. */
96                         state = EXP;
97                     } else { /* es otra cosa */
98                         PARSE_ERROR("un espacio o un igual");
99                         return FALSE;
100                     }
101                 }
102                 /* Si es espacio, no hace nada, deja que siga. */
103                 break;
104             case EXP: /* Encontró la expresión, la agrego a la lista. */
105                 eq = Equation_new(line, var_start, var_len,
106                         i, /* Comienzo de la ecuación */
107                         len - i); /* Longitud de la ecuación (sin el "\n") */
108                 /* No se pudo alocar la memoria. */
109                 if (!eq) {
110                     error->pos = 0;
111                     ParseError_set_message(error,
112                             "No se pudo alocar la memoria para la ecuación");
113                     return FALSE;
114                 }
115                 /* Lo agrego a la lista y si no se agregó bien da error. */
116                 if (!DLList_push(equation_list, eq)) {
117                     error->pos = 0;
118                     ParseError_set_message(error,
119                             "No se poner la ecuación en la lista");
120                     /* Elimino la ecuación recién creada. */
121                     Equation_delete(eq);
122                     return FALSE;
123                 }
124                 /* Se terminó todo bien. */
125                 return TRUE;
126         }
127     }
128     /* Error, no se llego a parsear todo bien. */
129     error->pos = len;
130     switch (state) {
131         case SEARCH_VAR:
132             ParseError_set_message(error,
133                     "No se encontró la definición de una variable");
134             break;
135         case VAR:
136         case SEARCH_EQUAL:
137             ParseError_set_message(error, "No se encontró un igual");
138             break;
139         case EXP:
140             ParseError_set_message(error, "No se encontró una expresión");
141             break;
142     }
143     return FALSE;
144 }
145
146 #undef PARSE_ERROR /* Sólo queremos usarlo en este fragmento */
147