1 /* vim: set et sts=4 sw=4 fdm=indent fdl=1 fdn=0 fo+=t tw=80:
3 * Taller de Programación (75.42).
6 * Programa calculadora.
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/).
12 * Creado: dom sep 14 13:03:49 ART 2003
19 #include "parseerror.h"
25 bool is_space(char c) {
26 return (c == ' ') || (c == '\t');
29 bool is_number(char c) {
30 return ('0' <= c) && (c <= '9');
33 bool is_alpha(char c) {
34 return (c == '_') || (('a' <= c) && (c <= 'z')) || (('A' <= c) && (c <= 'Z'));
37 bool is_alpha_num(c) {
38 return is_number(c) || is_alpha(c);
41 size_t DLList_equation_print(DLList* l, FILE* fp) {
44 for (eq = DLList_begin(l); DLList_have_more(l); eq = DLList_next(l)) {
45 cant += Equation_print(eq, fp);
50 void DLList_equation_delete(DLList* l) {
52 while (!DLList_empty(l)) {
53 Equation_delete((Equation*)DLList_pop(l));
59 #define PARSE_ERROR(str) ParseError_set_pos_message(error, str, i + 1, c)
61 bool parser_equation(const char* line, size_t len, DLList* equation_list,
63 enum {SEARCH_VAR, VAR, SEARCH_EQUAL, EXP} state = SEARCH_VAR;
69 for (i = 0; i < len; i++) {
72 case SEARCH_VAR: /* Busca el comienzo de una variable. */
75 /* Es una letra => es el comienzo de la variable. */
78 } else { /* es otra cosa => error */
79 PARSE_ERROR("un espacio o una letra");
83 /* Si es espacio, no hace nada, deja que siga. */
85 case VAR: /* Se fija cual es el nombre de la variable. */
86 if (!is_alpha_num(c)) {
88 /* Es un espacio, entonces hay que buscar un igual. */
90 /* Calculo la longitud de la variable. */
91 var_len = i - var_start;
92 } else if (c == '=') {
93 /* Es igual, empieza la expresión. */
95 /* Calculo la longitud de la variable. */
96 var_len = i - var_start;
97 } else { /* es otra cosa */
99 "un espacio, una letra, un número o un igual");
103 /* Si es alfanumérico, no hace nada, deja que siga. */
105 case SEARCH_EQUAL: /* Busca un signo de igual. */
108 /* Es igual, empieza la expresión. */
110 } else { /* es otra cosa */
111 PARSE_ERROR("un espacio o un igual");
115 /* Si es espacio, no hace nada, deja que siga. */
117 case EXP: /* Encontró la expresión, la agrego a la lista. */
118 eq = Equation_new(line, var_start, var_len,
119 i, /* Comienzo de la ecuación */
120 len - i); /* Longitud de la ecuación (sin el "\n") */
121 /* No se pudo alocar la memoria. */
124 ParseError_set_message(error,
125 "No se pudo alocar la memoria para la ecuación");
128 /* Lo agrego a la lista y si no se agregó bien da error. */
129 if (!DLList_push(equation_list, eq)) {
131 ParseError_set_message(error,
132 "No se poner la ecuación en la lista");
133 /* Elimino la ecuación recién creada. */
137 /* Se terminó todo bien. */
141 /* Error, no se llego a parsear todo bien. */
145 ParseError_set_message(error,
146 "No se encontró la definición de una variable");
150 ParseError_set_message(error, "No se encontró un igual");
153 ParseError_set_message(error, "No se encontró una expresión");
159 #undef PARSE_ERROR /* Sólo queremos usarlo en este fragmento */