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 #define PARSE_ERROR(str) ParseError_set_pos_message(error, str, i + 1, c)
52 bool parser_equation(const char* line, size_t len, DLList* equation_list,
54 enum {SEARCH_VAR, VAR, SEARCH_EQUAL, EXP} state = SEARCH_VAR;
60 for (i = 0; i < len; i++) {
63 case SEARCH_VAR: /* Busca el comienzo de una variable. */
66 /* Es una letra => es el comienzo de la variable. */
69 } else { /* es otra cosa => error */
70 PARSE_ERROR("un espacio o una letra");
74 /* Si es espacio, no hace nada, deja que siga. */
76 case VAR: /* Se fija cual es el nombre de la variable. */
77 if (!is_alpha_num(c)) {
79 /* Es un espacio, entonces hay que buscar un igual. */
81 /* Calculo la longitud de la variable. */
82 var_len = i - var_start;
83 } else if (c == '=') {
84 /* Es igual, empieza la expresión. */
86 /* Calculo la longitud de la variable. */
87 var_len = i - var_start;
88 } else { /* es otra cosa */
90 "un espacio, una letra, un número o un igual");
94 /* Si es alfanumérico, no hace nada, deja que siga. */
96 case SEARCH_EQUAL: /* Busca un signo de igual. */
99 /* Es igual, empieza la expresión. */
101 } else { /* es otra cosa */
102 PARSE_ERROR("un espacio o un igual");
106 /* Si es espacio, no hace nada, deja que siga. */
108 case EXP: /* Encontró la expresión, la agrego a la lista. */
109 eq = Equation_new(line, var_start, var_len,
110 i, /* Comienzo de la ecuación */
111 len - i); /* Longitud de la ecuación (sin el "\n") */
112 /* No se pudo alocar la memoria. */
115 ParseError_set_message(error,
116 "No se pudo alocar la memoria para la ecuación");
119 /* Lo agrego a la lista y si no se agregó bien da error. */
120 if (!DLList_push(equation_list, eq)) {
122 ParseError_set_message(error,
123 "No se poner la ecuación en la lista");
124 /* Elimino la ecuación recién creada. */
128 /* Se terminó todo bien. */
132 /* Error, no se llego a parsear todo bien. */
136 ParseError_set_message(error,
137 "No se encontró la definición de una variable");
141 ParseError_set_message(error, "No se encontró un igual");
144 ParseError_set_message(error, "No se encontró una expresión");
150 #undef PARSE_ERROR /* Sólo queremos usarlo en este fragmento */