#include #include #include #include #include #include #include #include #include typedef struct burm_state *STATEPTR_TYPE; #include "gforth9.h" void burm_trace(NODEPTR_TYPE p, int eruleno, int cost, int bestcost) { printf("match: op=%d, rule=%d, cost=%d, bestcost=%d\n", p->op, eruleno, cost, bestcost); } unsigned short *input(char *filename, size_t *nelem) { void *res; struct stat st; int fd=open(filename,O_RDONLY); if (fd==-1) { perror(filename); exit(1); } fstat(fd, &st); res=mmap(NULL,st.st_size,PROT_READ,MAP_PRIVATE,fd,0); if (res==(short *)-1) { perror(filename); exit(1); } *nelem = st.st_size/sizeof(short); return (unsigned short *)res; } /* adapted from http://www.complang.tuwien.ac.at/ublu/burg.pdf */ int reduce(NODEPTR_TYPE p, int goalnt, unsigned short **rulep) { int eruleno; short *nts; NODEPTR_TYPE kids[100]; int i; int cost; eruleno=burm_rule(STATE_LABEL(p), goalnt); /* matching rule number */ cost = burm_cost[eruleno][0]; **rulep = eruleno; (*rulep)++; nts=burm_nts[eruleno]; /* subtree goal non-terminals */ if (eruleno==0) { fprintf(stderr, "tree cannot be derived from start symbol"); exit(1); } burm_kids(p, eruleno, kids); /* initialize subtree pointers */ for (i=0; nts[i]; i++) /* traverse subtrees left-to-right */ cost += reduce(kids[i], nts[i], rulep); /* reduce kids */ return cost; } void process(unsigned short *seqs, size_t nseqs, int canonical_state, unsigned short **rulesp, size_t *nrulesp, unsigned short **costsp, size_t *ncostsp) { size_t i, nroots; // unsigned short *s; struct tree leaf = {s0+canonical_state,{NULL},NULL}; NODEPTR_TYPE nodes = calloc(nseqs,sizeof(struct tree)); NODEPTR_TYPE *roots = calloc(nseqs,sizeof(NODEPTR_TYPE)); NODEPTR_TYPE root = nodes; unsigned short *rules = calloc(nseqs*2,sizeof(short)); unsigned short *lastrule = rules; unsigned short *costs = calloc(nseqs,sizeof(short)); unsigned short *lastcosts = costs; for (i=0, nroots=0; i [0-8]\n", argv[0]); exit(1); } seqs=input(argv[1],&nseqs); canonical_state = atoi(argv[4]); if (canonical_state<0 || canonical_state>8) { fprintf(stderr, "You cannot use state %d\n",canonical_state); exit(1); } process(seqs,nseqs,canonical_state,&rules,&nrules,&costs,&ncosts); writefile(argv[2],rules,nrules*sizeof(short)); writefile(argv[3],costs,ncosts*sizeof(short)); return 0; }