📄 lr0.c
字号:
return (sp->number);}/* subroutine of get_state. create a new state for those items, if necessary. */core *new_state (int symbol){ register int n; register core *p; register short *isp1; register short *isp2; register short *iend;#ifdef TRACE fprintf(stderr, "Entering new_state, symbol = %d\n", symbol);#endif if (nstates >= MAXSHORT) toomany("states"); isp1 = kernel_base[symbol]; iend = kernel_end[symbol]; n = iend - isp1; p = (core *) xmalloc((unsigned) (sizeof(core) + (n - 1) * sizeof(short))); p->accessing_symbol = symbol; p->number = nstates; p->nitems = n; isp2 = p->items; while (isp1 < iend) *isp2++ = *isp1++; last_state->next = p; last_state = p; nstates++; return (p);}voidinitialize_states (void){ register core *p;/* register unsigned *rp1; JF unused *//* register unsigned *rp2; JF unused *//* register unsigned *rend; JF unused */ p = (core *) xmalloc((unsigned) (sizeof(core) - sizeof(short))); first_state = last_state = this_state = p; nstates = 1;}voidsave_shifts (void){ register shifts *p; register short *sp1; register short *sp2; register short *send; p = (shifts *) xmalloc((unsigned) (sizeof(shifts) + (nshifts - 1) * sizeof(short))); p->number = this_state->number; p->nshifts = nshifts; sp1 = shiftset; sp2 = p->shifts; send = shiftset + nshifts; while (sp1 < send) *sp2++ = *sp1++; if (last_shift) { last_shift->next = p; last_shift = p; } else { first_shift = p; last_shift = p; }}/* find which rules can be used for reduction transitions from the current state and make a reductions structure for the state to record their rule numbers. */voidsave_reductions (void){ register short *isp; register short *rp1; register short *rp2; register int item; register int count; register reductions *p; short *rend; /* find and count the active items that represent ends of rules */ count = 0; for (isp = itemset; isp < itemsetend; isp++) { item = ritem[*isp]; if (item < 0) { redset[count++] = -item; } } /* make a reductions structure and copy the data into it. */ if (count) { p = (reductions *) xmalloc((unsigned) (sizeof(reductions) + (count - 1) * sizeof(short))); p->number = this_state->number; p->nreds = count; rp1 = redset; rp2 = p->rules; rend = rp1 + count; while (rp1 < rend) *rp2++ = *rp1++; if (last_reduction) { last_reduction->next = p; last_reduction = p; } else { first_reduction = p; last_reduction = p; } }}/* Make sure that the initial state has a shift that accepts thegrammar's start symbol and goes to the next-to-final state,which has a shift going to the final state, which has a shiftto the termination state.Create such states and shifts if they don't happen to exist already. */voidaugment_automaton (void){ register int i; register int k;/* register int found; JF unused */ register core *statep; register shifts *sp; register shifts *sp2; register shifts *sp1 = NULL; sp = first_shift; if (sp) { if (sp->number == 0) { k = sp->nshifts; statep = first_state->next; /* The states reached by shifts from first_state are numbered 1...K. Look for one reached by start_symbol. */ while (statep->accessing_symbol < start_symbol && statep->number < k) statep = statep->next; if (statep->accessing_symbol == start_symbol) { /* We already have a next-to-final state. Make sure it has a shift to what will be the final state. */ k = statep->number; while (sp && sp->number < k) { sp1 = sp; sp = sp->next; } if (sp && sp->number == k) { sp2 = (shifts *) xmalloc((unsigned) (sizeof(shifts) + sp->nshifts * sizeof(short))); sp2->number = k; sp2->nshifts = sp->nshifts + 1; sp2->shifts[0] = nstates; for (i = sp->nshifts; i > 0; i--) sp2->shifts[i] = sp->shifts[i - 1]; /* Patch sp2 into the chain of shifts in place of sp, following sp1. */ sp2->next = sp->next; sp1->next = sp2; if (sp == last_shift) last_shift = sp2; FREE(sp); } else { sp2 = NEW(shifts); sp2->number = k; sp2->nshifts = 1; sp2->shifts[0] = nstates; /* Patch sp2 into the chain of shifts between sp1 and sp. */ sp2->next = sp; sp1->next = sp2; if (sp == 0) last_shift = sp2; } } else { /* There is no next-to-final state as yet. */ /* Add one more shift in first_shift, going to the next-to-final state (yet to be made). */ sp = first_shift; sp2 = (shifts *) xmalloc(sizeof(shifts) + sp->nshifts * sizeof(short)); sp2->nshifts = sp->nshifts + 1; /* Stick this shift into the vector at the proper place. */ statep = first_state->next; for (k = 0, i = 0; i < sp->nshifts; k++, i++) { if (statep->accessing_symbol > start_symbol && i == k) sp2->shifts[k++] = nstates; sp2->shifts[k] = sp->shifts[i]; statep = statep->next; } if (i == k) sp2->shifts[k++] = nstates; /* Patch sp2 into the chain of shifts in place of sp, at the beginning. */ sp2->next = sp->next; first_shift = sp2; if (last_shift == sp) last_shift = sp2; FREE(sp); /* Create the next-to-final state, with shift to what will be the final state. */ insert_start_shift(); } } else { /* The initial state didn't even have any shifts. Give it one shift, to the next-to-final state. */ sp = NEW(shifts); sp->nshifts = 1; sp->shifts[0] = nstates; /* Patch sp into the chain of shifts at the beginning. */ sp->next = first_shift; first_shift = sp; /* Create the next-to-final state, with shift to what will be the final state. */ insert_start_shift(); } } else { /* There are no shifts for any state. Make one shift, from the initial state to the next-to-final state. */ sp = NEW(shifts); sp->nshifts = 1; sp->shifts[0] = nstates; /* Initialize the chain of shifts with sp. */ first_shift = sp; last_shift = sp; /* Create the next-to-final state, with shift to what will be the final state. */ insert_start_shift(); } /* Make the final state--the one that follows a shift from the next-to-final state. The symbol for that shift is 0 (end-of-file). */ statep = (core *) xmalloc((unsigned) (sizeof(core) - sizeof(short))); statep->number = nstates; last_state->next = statep; last_state = statep; /* Make the shift from the final state to the termination state. */ sp = NEW(shifts); sp->number = nstates++; sp->nshifts = 1; sp->shifts[0] = nstates; last_shift->next = sp; last_shift = sp; /* Note that the variable `final_state' refers to what we sometimes call the termination state. */ final_state = nstates; /* Make the termination state. */ statep = (core *) xmalloc((unsigned) (sizeof(core) - sizeof(short))); statep->number = nstates++; last_state->next = statep; last_state = statep;}/* subroutine of augment_automaton. Create the next-to-final state, to which a shift has already been made in the initial state. */voidinsert_start_shift (void){ register core *statep; register shifts *sp; statep = (core *) xmalloc((unsigned) (sizeof(core) - sizeof(short))); statep->number = nstates; statep->accessing_symbol = start_symbol; last_state->next = statep; last_state = statep; /* Make a shift from this state to (what will be) the final state. */ sp = NEW(shifts); sp->number = nstates++; sp->nshifts = 1; sp->shifts[0] = nstates; last_shift->next = sp; last_shift = sp;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -