char CharMapper::linesplice() { if (ls_has_unget) { ls_has_unget = false; return ls_unget; } while (true) { char c = trigraph(); if (c == '\\') { c = trigraph(); if (c != '\n') { ls_has_unget = true; ls_unget = c; return '\\'; } } else { return c; } } }
/* * fill in a row of tokens from input, terminated by NL or END * First token is put at trp->lp. * Reset is non-zero when the input buffer can be "rewound." * The value is a flag indicating that possible macros have * been seen in the row. */ int gettokens(Tokenrow *trp, int reset) { register int c, state, oldstate; register uchar *ip; register Token *tp, *maxp; int runelen; Source *s = cursource; int nmac = 0; tp = trp->lp; ip = s->inp; if (reset) { s->lineinc = 0; if (ip>=s->inl) { /* nothing in buffer */ s->inl = s->inb; fillbuf(s); ip = s->inp = s->inb; } else if (ip >= s->inb+(3*INS/4)) { memmove(s->inb, ip, 4+s->inl-ip); s->inl = s->inb+(s->inl-ip); ip = s->inp = s->inb; } } maxp = &trp->bp[trp->max]; runelen = 1; for (;;) { continue2: if (tp>=maxp) { trp->lp = tp; tp = growtokenrow(trp); maxp = &trp->bp[trp->max]; } tp->type = UNCLASS; tp->hideset = 0; tp->t = ip; tp->wslen = 0; tp->flag = 0; state = START; for (;;) { oldstate = state; c = *ip; if ((state = bigfsm[c][state]) >= 0) { ip += runelen; runelen = 1; continue; } state = ~state; reswitch: switch (state&0177) { case S_SELF: ip += runelen; runelen = 1; case S_SELFB: tp->type = GETACT(state); tp->len = ip - tp->t; tp++; goto continue2; case S_NAME: /* like S_SELFB but with nmac check */ tp->type = NAME; tp->len = ip - tp->t; nmac |= quicklook(tp->t[0], tp->len>1?tp->t[1]:0); tp++; goto continue2; case S_WS: tp->wslen = ip - tp->t; tp->t = ip; state = START; continue; default: if ((state&QBSBIT)==0) { ip += runelen; runelen = 1; continue; } state &= ~QBSBIT; s->inp = ip; if (c=='?') { /* check trigraph */ if (trigraph(s)) { state = oldstate; continue; } goto reswitch; } if (c=='\\') { /* line-folding */ if (foldline(s)) { s->lineinc++; state = oldstate; continue; } goto reswitch; } error(WARNING, "Lexical botch in cpp"); ip += runelen; runelen = 1; continue; case S_EOB: s->inp = ip; fillbuf(cursource); state = oldstate; continue; case S_EOF: tp->type = END; tp->len = 0; s->inp = ip; if (tp!=trp->bp && (tp-1)->type!=NL && cursource->fd!=-1) error(WARNING,"No newline at end of file"); trp->lp = tp+1; return nmac; case S_STNL: error(ERROR, "Unterminated string or char const"); case S_NL: tp->t = ip; tp->type = NL; tp->len = 1; tp->wslen = 0; s->lineinc++; s->inp = ip+1; trp->lp = tp+1; return nmac; case S_EOFSTR: error(FATAL, "EOF in string or char constant"); break; case S_COMNL: s->lineinc++; state = COM2; ip += runelen; runelen = 1; continue; case S_EOFCOM: error(WARNING, "EOF inside comment"); --ip; case S_COMMENT: ++ip; tp->t = ip; tp->t[-1] = ' '; tp->wslen = 1; state = START; continue; } break; } ip += runelen; runelen = 1; tp->len = ip - tp->t; tp++; } }
struct listnode* processoperators(struct listnode *newnode,int c) { int expect[10],ifyes[10],code; newnode->token.tokentype=OPERATOR; switch(c) { case '+' : expect[0]='+'; ifyes[0]=PLUSPLUS; expect[1]='=' ; ifyes[1]=PLUSEQ; code=lookahead(expect,ifyes,2); if(code) newnode->token.Ctoken.operator->code=code; else newnode->token.Ctoken.operator->code=c; return newnode; case '-' : expect[0]='-'; ifyes[0]=MINUSMINUS; expect[1]='='; ifyes[1]=MINUSEQ; expect[2]='>'; ifyes[2]=ARROW; code=lookahead(expect,ifyes,3); if(code) newnode->token.Ctoken.operator->code=code; else newnode->token.Ctoken.operator->code=c; return newnode; case '*' : expect[0]='='; ifyes[0]=STAREQ; if( (code=lookahead(expect,ifyes,1)) != 0 ) newnode->token.Ctoken.operator->code=code; else newnode->token.Ctoken.operator->code=c; return newnode; case '/': newnode->token.Ctoken.operator->code=c; expect[0]='='; ifyes[0]=SLASHEQ; if( (code=lookahead(expect,ifyes,1)) != 0 ) newnode->token.Ctoken.operator->code=code; return newnode; case '^' : newnode->token.Ctoken.operator->code=c; expect[0]='='; ifyes[0]=EXOREQ; if( (code=lookahead(expect,ifyes,1)) != 0 ) newnode->token.Ctoken.operator->code=code; return newnode; case '%': newnode->token.Ctoken.operator->code=c; expect[0]='='; ifyes[0]=MODEQ; if( (code=lookahead(expect,ifyes,1)) != 0 ) newnode->token.Ctoken.operator->code=code; return newnode; case '=': newnode->token.Ctoken.operator->code=c; expect[0]='='; ifyes[0]=EQ; if( (code=lookahead(expect,ifyes,1)) != 0 ) newnode->token.Ctoken.operator->code=code; return newnode; case '!': newnode->token.Ctoken.operator->code=c; expect[0]='='; ifyes[0]=NE; if( (code=lookahead(expect,ifyes,1)) != 0 ) newnode->token.Ctoken.operator->code=code; return newnode; case '|': newnode->token.Ctoken.operator->code=c; expect[0]='|'; ifyes[0]=OR; expect[1]='='; ifyes[1]=OREQ; if( (code=lookahead(expect,ifyes,2)) != 0 ) newnode->token.Ctoken.operator->code=code; return newnode; case '&': newnode->token.Ctoken.operator->code=c; expect[0]='&'; ifyes[0]=AND; expect[1]='='; ifyes[1]=ANDEQ; if( (code=lookahead(expect,ifyes,2)) != 0 ) newnode->token.Ctoken.operator->code=code; return newnode; case '<': newnode->token.Ctoken.operator->code=c; expect[0]='='; ifyes[0]=LE; expect[1]='<'; ifyes[1]=LS; if( (code=lookahead(expect,ifyes,2)) != 0 ) newnode->token.Ctoken.operator->code=code; if(code==LS) { expect[0]='='; ifyes[0]=LSE; if( (code=lookahead(expect,ifyes,1))!=0 ) newnode->token.Ctoken.operator->code=code; } return newnode; case '>': newnode->token.Ctoken.operator->code=c; expect[0]='='; ifyes[0]=GE; expect[1]='>'; ifyes[1]=RS; if( (code=lookahead(expect,ifyes,2)) != 0 ) newnode->token.Ctoken.operator->code=code; if(code==RS) { expect[0]='='; ifyes[0]=RSE; if( (code=lookahead(expect,ifyes,1))!=0 ) newnode->token.Ctoken.operator->code=code; } return newnode; case '?' : newnode->token.Ctoken.operator->code=c; if( (code=trigraph()) != 0 ) return processoperators(newnode,c); /*recursion*/ /*else return '?' to stream*/ ungetc(c,yyin); return newnode; default: newnode->token.Ctoken.operator->code=c; return newnode; }/*end of switch*/ }/*End of process operators*/