#include #include #include #include #include "table.h" #include "program.h" static void *row_clone(void *p) { struct instruction *row; row = (struct instruction *)malloc(sizeof(struct instruction)); memcpy((void *)row, p, sizeof(struct instruction)); return (void *)row; } static int row_cmp(void *a, void *b) { struct instruction *ra, *rb; ra = (struct instruction *)a; rb = (struct instruction *)b; if (ra->state < rb->state) return -1; if (ra->state > rb->state) return 1; if (ra->symbol < rb->symbol) return -1; if (ra->symbol > rb->symbol) return 1; return 0; } static void row_repr(void *p, char *buf, int size) { struct instruction *row; static char *moves = "LNR"; row = (struct instruction *)p; snprintf(buf, size, "[%d %d | %d %d %c]", row->state, row->symbol, row->nextstate, row->write, ((row->move >= -1) && (row->move <=1) ? moves[1+row->move] : '?')); buf[size-1] = '\0'; } static short int parse_move(char *m) { char c; c = (char)tolower(m[0]); if (c == 'l') return -1; if (c == 'r') return 1; if (c == 'n') return 0; return atoi(m); } struct table *program_new() { return table_new(20, 10, row_clone, free, row_cmp, row_repr); } int program_load(FILE *f, struct table *prg, struct table *st, struct table *sym) { char line[LINE_LEN+1]; char state[STATE_LEN+1]; char symbol[SYMBOL_LEN+1]; char write[SYMBOL_LEN+1]; char move[8]; char nextstate[STATE_LEN+1]; int ll; char *l; char *p; int r; struct instruction row; int cnt; line[LINE_LEN] = '\0'; cnt = 0; for (;;) { l = fgets(line, sizeof(line)-1, f); if (l == NULL) break; ll = strlen(l); if (ll > 0) { p = &line[ll-1]; while ((ll > 0) && ((*p == '\r') || (*p == '\n'))) { *p = '\0'; ll--; } } p = strchr(l, '#'); if (p != NULL) *p = '\0'; r = sscanf(l, "%s %s %s %s %s", state, symbol, nextstate, write, move); if (r == 0) continue; if (r != 5) { printf("Parsing error!\n"); } else { row.state = table_insert(st, state); row.symbol = table_insert(sym, symbol); row.write = table_insert(sym, write); row.move = parse_move(move); row.nextstate = table_insert(st, nextstate); table_insert(prg, &row); cnt++; } } return cnt; }