int main(int argc, char *argv[]) { (argc+1 ? has_destructor() : throw 0); CI((argc+1 ? throw 0 : has_destructor())); CI((0 ? has_destructor() : throw 0)); CI((1 ? throw 0 : has_destructor())); (0 ? throw 0 : has_destructor()); (1 ? has_destructor() : throw 0); (argc+1 ? no_destructor() : throw 0); CI((argc+1 ? throw 0 : no_destructor())); CI((0 ? no_destructor() : throw 0)); CI((1 ? throw 0 : no_destructor())); (0 ? throw 0 : no_destructor()); (1 ? no_destructor() : throw 0); int i = 1; CI(throw PI(i)); if (i != 2) abort(); (1 ? 0 : throw PI(i)); if (i != 2) abort(); CI(0 ? 0 : throw PI(i)); if (i != 3) abort(); CI(0 ? has_destructor() : throw PI(i)); if (i != 4) abort(); (argc+1 ? has_destructor() : throw PI(i)); if (i != 4) abort(); i = 1; CI(throw i++); if (i != 2) abort(); (1 ? 0 : throw i++); if (i != 2) abort(); CI(0 ? 0 : throw i++); if (i != 3) abort(); CI(0 ? has_destructor() : throw i++); if (i != 4) abort(); (argc+1 ? has_destructor() : throw i++); if (i != 4) abort(); }
/* ** zCode is a string that is the action associated with a rule. Expand ** the symbols in this string so that they refer to elements of the parser ** stack. ** (Return a new string stored in space obtained from malloc?) */ PRIVATE void translate_code(struct lmno *lmnop, struct rule *rp) { char *cp, *xp; bool lhsused = false; // True if the LHS element has been used char used[MAXRHS]; // True for each RHS element which is used for(int i = 0; i < rp->nrhs; i++) used[i] = 0; append_str(0,0,0,0); for(cp=rp->code; *cp; cp++) { if(isalpha(*cp) && (cp==rp->code || (!isalnum(cp[-1]) && cp[-1]!='_'))) { char saved; for(xp= &cp[1]; isalnum(*xp) || *xp=='_'; xp++) { } // find ident saved = *xp; *xp = 0; if(rp->lhsalias && strcmp(cp,rp->lhsalias)==0) { append_str("yygotominor.yy%d",0,rp->lhs->dtnum,0); cp = xp; lhsused = true; } else { for(int i = 0; i < rp->nrhs; i++) { if(rp->rhsalias[i] && strcmp(cp,rp->rhsalias[i])==0) { // If the argument is "@X" then substituted // the token number of X, not the value of X if(cp!=rp->code && cp[-1]=='@') { append_str("yymsp[%d].major",-1,i-rp->nrhs+1,0); } else { append_str("yymsp[%d].minor.yy%d",0, i-rp->nrhs+1,rp->rhs[i]->dtnum); } cp = xp; used[i] = 1; break; } } } *xp = saved; } append_str(cp, 1, 0, 0); } // End loop // Check to make sure the LHS has been used if(rp->lhsalias && !lhsused) { ErrorMsg(lmnop->filename,rp->ruleline, "Label \"%s\" for \"%s(%s)\" is never used.", rp->lhsalias,rp->lhs->name,rp->lhsalias); lmnop->errorcnt++; } // Generate destructor code for RHS symbols which are not used in the // reduction code for(int i = 0; i < rp->nrhs; i++) { if(rp->rhsalias[i] && !used[i]) { ErrorMsg(lmnop->filename, rp->ruleline, "Label %s for \"%s(%s)\" is never used.", rp->rhsalias[i], rp->rhs[i]->name, rp->rhsalias[i]); lmnop->errorcnt++; } else if(rp->rhsalias[i]==0) { if(has_destructor(rp->rhs[i],lmnop)) { append_str(" destructor(%d, &yymsp[%d].minor);\n", 0, rp->rhs[i]->index, i - rp->nrhs + 1); } else { /* No destructor defined for this term */ } } } cp = append_str(0,0,0,0); rp->code = Strsafe(cp); }