122 lines
2.6 KiB
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;
|
|
}
|