turing/program.c

122 lines
2.6 KiB
C

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#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;
}