📄 ckwart.c
字号:
cur->actno = ++nacts; cur->inchr = (char) (tokval[0] - 32); if (head == NULL) head = cur; else prev->nxt = cur; prev = cur; cur = NULL; copyact(fp,out,nacts); break; default: fatal("bad input format"); } return(head);}/* * read a list of (comma-separated) states, set them in the * given transition. * */VOIDstatelist(fp,t) FILE *fp; trans t; { int curtok,sval; curtok = COMMA; while (curtok != RBRACK) { if (curtok != COMMA) fatal("missing comma"); if ((curtok = gettoken(fp)) != WORD) fatal("missing state name"); if ((sval = lkup(tokval)) == -1) { fprintf(stderr,"state %s undefined\n",tokval); fatal("undefined state"); } setwstate(sval,t); curtok = gettoken(fp); }}/* * copy an action from the input to the output file * */VOIDcopyact(inp,outp,actno) FILE *inp,*outp; int actno; { int c,bcnt; fprintf(outp,"case %d:\n",actno); while (c = getc(inp), (isspace(c) || c == C_L)) if (c == '\n') lines++; if (c == '{') { bcnt = 1; fputs(" {",outp); while (bcnt > 0 && (c = getc(inp)) != EOF) { if (c == '{') bcnt++; else if (c == '}') bcnt--; else if (c == '\n') lines++; putc(c,outp); } if (bcnt > 0) fatal("action doesn't end"); } else { while (c != '\n' && c != EOF) { putc(c,outp); c = getc(inp); } lines++; } fprintf(outp,"\n break;\n");}/* * find the action associated with a given character and state. * returns -1 if one can't be found. * */intfaction(hd,state,chr) trans hd; int state,chr; { while (hd != NULL) { if (hd->anyst || teststate(state,hd)) if (hd->inchr == ('.' - 32) || hd->inchr == (char) chr) return(hd->actno); hd = hd->nxt; } return(-1);}/* * empty the table... * */VOIDemptytbl() { int i; for (i=0; i<nstates*96; i++) tbl[i] = -1;}/* * add the specified action to the output for the given state and chr. * */VOIDaddaction(act,state,chr) int act,state,chr; { tbl[state*96 + chr] = act;}VOIDwritetbl(fp) FILE *fp; { warray(fp,"tbl",tbl,96*(nstates+1),TBL_TYPE);}/* * write an array to the output file, given its name and size. * */VOIDwarray(fp,nam,cont,siz,typ) FILE *fp; char *nam; int cont[],siz; char *typ; { int i; fprintf(fp,"%s %s[] = {\n",typ,nam); for (i = 0; i < siz - 1; ) { fprintf(fp,"%2d, ",cont[i]); if ((++i % 16) == 0) putc('\n',fp); } fprintf(fp,"%2d ",cont[siz-1]); fprintf(fp,"};\n");}#ifdef __DECC#ifdef __ALPHAint#elseVOID#endif /* __ALPHA */#else#ifdef STRATUSint#elseVOID#endif /* STRATUS */#endif /* __DECC */main(argc,argv) int argc; char *argv[]; { trans head; int state,c; FILE *infile,*outfile; if (argc > 1) { if ((infile = fopen(argv[1],"r")) == NULL) { fprintf(stderr,"Can't open %s\n",argv[1]); fatal("unreadable input file"); } } else infile = stdin; if (argc > 2) { if ((outfile = fopen(argv[2],"w")) == NULL) { fprintf(stderr,"Can't write to %s\n",argv[2]); fatal("bad output file"); } } else outfile = stdout; clrhash(); /* empty hash table */ head = rdinput(infile,outfile); /* read input file */ emptytbl(); /* empty our tables */ for (state = 0; state <= nstates; state++) for (c = 1; c < 96; c++) /* find actions, */ addaction(faction(head,state,c),state,c); /* add to tbl */ writetbl(outfile); copyrest(infile,outfile); printf("%d states, %d actions\n",nstates,nacts); exit(GOOD_EXIT);}/* * fatal error handler * */VOIDfatal(msg) char *msg; { fprintf(stderr,"error in line %d: %s\n",lines,msg); exit(BAD_EXIT);}VOIDprolog(outfp) FILE *outfp; { int c; while ((c = *txt1++) != '\0') putc(c,outfp); while ((c = *fname++) != '\0') putc(c,outfp); while ((c = *txt2++) != '\0') putc(c,outfp); while ((c = *tbl_type++) != '\0') putc(c,outfp); while ((c = *txt2a++) != '\0') putc(c,outfp); while ((c = *txt2b++) != '\0') putc(c,outfp);}VOIDepilogue(outfp) FILE *outfp; { int c; while ((c = *txt3++) != '\0') putc(c,outfp);}VOIDcopyrest(in,out) FILE *in,*out; { int c; while ((c = getc(in)) != EOF) putc(c,out);}/* * gettoken - returns token type of next token, sets tokval * to the string value of the token if appropriate. * */intgettoken(fp) FILE *fp; { int c; while (1) { /* loop if reading comments... */ do { c = getc(fp); if (c == '\n') lines++; } while ((isspace(c) || c == C_L)); /* skip whitespace */ switch(c) { case EOF: return(SEP); case '%': if ((c = getc(fp)) == '%') return(SEP); tokval[0] = '%'; tokval[1] = (char) c; rdword(fp,tokval+2); return(WORD); case '<': return(LBRACK); case '>': return(RBRACK); case ',': return(COMMA); case '/': if ((c = getc(fp)) == '*') { rdcmnt(fp); /* skip over the comment */ continue; } else { /* and keep looping */ ungetc(c,fp); /* put this back into input */ c = '/'; /* put character back, fall thru */ } default: if (isword(c)) { ungetc(c,fp); rdword(fp,tokval); return(WORD); } else fatal("Invalid character in input"); } }}/* * skip over a comment * */VOIDrdcmnt(fp) FILE *fp; { int c,star,prcnt; prcnt = star = 0; /* no star seen yet */ while (!((c = getc(fp)) == '/' && star)) { if (c == EOF || (prcnt && c == '%')) fatal("Unterminated comment"); prcnt = (c == '%'); star = (c == '*'); if (c == '\n') lines++; }}/* * symbol table management for wart * * entry points: * clrhash - empty hash table. * enter - enter a name into the symbol table * lkup - find a name's value in the symbol table. * */#define HASHSIZE 101 /* # of entries in hash table */struct sym { char *name; /* symbol name */ int val; /* value */ struct sym *hnxt; /* next on collision chain */} *htab[HASHSIZE]; /* the hash table *//* * empty the hash table before using it... * */VOIDclrhash() { int i; for (i=0; i<HASHSIZE; i++) htab[i] = NULL;}/* * compute the value of the hash for a symbol * */inthash(name) char *name; { int sum; for (sum = 0; *name != '\0'; name++) sum += (sum + *name); sum %= HASHSIZE; /* take sum mod hashsize */ if (sum < 0) sum += HASHSIZE; /* disallow negative hash value */ return(sum);}/* * make a private copy of a string... * */static char*copy(s) char *s; { char *new; new = (char *) malloc((int)strlen(s) + 1); strcpy(new,s); return(new);}/* * enter state name into the hash table * */VOIDenter(name,svalue) char *name; int svalue; { int h; struct sym *cur; if (lkup(name) != -1) { fprintf(stderr,"state \"%s\" appears twice...\n", name); exit(BAD_EXIT); } h = hash(name); cur = (struct sym *)malloc(sizeof (struct sym)); cur->name = copy(name); cur->val = svalue; cur->hnxt = htab[h]; htab[h] = cur;}/* * find name in the symbol table, return its value. Returns -1 * if not found. * */intlkup(name) char *name; { struct sym *cur; for (cur = htab[hash(name)]; cur != NULL; cur = cur->hnxt) if (strcmp(cur->name,name) == 0) return(cur->val); return(-1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -