exptok.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 339 行
C
339 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#include <stdlib.h>
#include <string.h>
#include "wic.h"
static pSLList tokQue;
static int eofScanned = 0;
static pToken getNextTokQueElem(void);
static pToken getNextTokQueElemEmitEOL(int emitEol);
void initExpandToken(void) {
tokQue = createSLList();
g_currLineCode = createSLList();
eofScanned = 0;
}
void zapExpandToken(void) {
assert(isEmptySLList(tokQue));
zapSLList(tokQue, NULL);
zapSLList(g_currLineCode, NULL);
}
static pTokPos _pushMacroCodePosArgument;
int _pushMacroCodeFirstToken;
static void *changeToken(void *_token) {
pToken token = _token;
pToken newToken;
newToken = dupToken(token, _pushMacroCodePosArgument);
if (_pushMacroCodeFirstToken) {
_pushMacroCodeFirstToken = 0;
} else {
newToken->pos->spacesBefore = token->pos->spacesBefore;
}
return newToken;
}
static void prependTokQue(pSLList list, pTokPos pos) {
rewindCurrSLListPos(list);
_pushMacroCodePosArgument = pos;
_pushMacroCodeFirstToken = 1;
addBegSLListSLList(tokQue, list, changeToken);
}
static int expandMacroWithParams(pSLList mCode, char *name, pTokPos pos,
ExpOpType expandOp) {
#define maxArgs 15
int numArgs = 0;
pToken tok;
char* mArg[maxArgs];
pSLList realArg[maxArgs];
pSLList expanded = NULL;
pSLList backList = NULL;
int code = 0;
int retval = 1;
int i;
memset(realArg, 0, (sizeof realArg[0])*maxArgs);
// Get params (at the beginning of mCode). (Here we DO report errors)
rewindCurrSLListPos(mCode);
incCurrSLListPos(mCode); // Skip Y_PRE_SPECIAL_LEFT_PAREN
for (numArgs = 0; numArgs < maxArgs; numArgs++) {
getCurrSLListPosElem(mCode, &tok);
incCurrSLListPos(mCode);
code = tok->data->code;
mArg[numArgs] = getTokDataIdName(tok->data);
if (numArgs == 0 && code == Y_RIGHT_PAREN) {
break; // no arguments is OK
}
if (code != Y_ID) {
reportError(RERR_EXPECTING_BUT_FOUND, "identifier", mArg[numArgs]);
}
getCurrSLListPosElem(mCode, &tok);
incCurrSLListPos(mCode);
code = tok->data->code;
if (code == Y_RIGHT_PAREN) {
numArgs++;
break;
} else if (code == Y_COMMA) {
} else {
break; // error will be displayed upon exit
}
}
if (code != Y_RIGHT_PAREN) {
reportError(RERR_EXPECTING_BUT_FOUND, ")",
getTokDataIdName(tok->data));
}
// get the replacements for arguments -- here we have to allow
// errors, so that if expansion is unsuccessful and we are in preparser,
// we repass the line without expanding. This means no premature return!
// We'll push tokens back on stack if error occurs.
backList = createSLList();
tok = getNextTokQueElemEmitEOL(expandOp&EXP_OP_EMIT_EOL);
addBegSLListElem(backList, tok);
if (tok->data->code != Y_LEFT_PAREN) {
if (!(expandOp & EXP_OP_HIDE_ERRORS)) {
reportError(RERR_EXPECTING_BUT_FOUND, "(",
staticGetTokenStr(tok, 0));
}
retval = 0;
} else {
for (i = 0; i < numArgs ; i++) {
realArg[i] = createSLList();
}
for (i = 0; i < numArgs ; i++) {
int parenNest = 0;
for (;;) {
tok = getNextTokQueElemEmitEOL(expandOp&EXP_OP_EMIT_EOL);
addBegSLListElem(backList, tok);
code = tok->data->code;
if (code == Y_EOF ||
getTokDataType(tok->data) == TT_PREPROCESSOR)
{
if (!(expandOp&EXP_OP_HIDE_ERRORS)) {
char errstr[80];
strcpy(errstr, "an argument to ");
strncpy(errstr+strlen(errstr), name, 60);
errstr[75] = 0;
reportError(RERR_EXPECTING_BUT_FOUND,
errstr, staticGetTokenStr(tok, 0));
}
retval = 0;
} else if (code == Y_LEFT_PAREN) {
parenNest++;
} else if (code == Y_RIGHT_PAREN) {
if (parenNest > 0) {
parenNest--;
} else {
if (i != numArgs-1) {
if (!(EXP_OP_HIDE_ERRORS&expandOp)) {
reportError(RERR_NOT_ENOUGH_ARGS, name);
}
i = numArgs-1;
retval = 0;
}
break;
}
} else if (code == Y_COMMA && parenNest == 0) {
break;
}
addSLListElem(realArg[i], tok);
}
}
if (code != Y_RIGHT_PAREN) {
if (!(EXP_OP_HIDE_ERRORS&expandOp)) {
reportError(RERR_EXPECTING_BUT_FOUND, ")", staticGetTokenStr(tok, 0));
}
retval = 0;
}
if (retval) {
// Do the actual expansion
expanded = createSLList();
while (getCurrSLListPosElem(mCode, &tok)) {
if (tok->data->code == Y_ID) {
char *s = getTokDataIdName(tok->data);
for (i = 0; i < numArgs; i++) {
if (s == mArg[i]) break;
}
} else {
i = numArgs;
}
if (i == numArgs) {
addSLListElem(expanded, tok);
} else {
rewindCurrSLListPos(realArg[i]);
while (getCurrSLListPosElem(realArg[i], &tok)) {
addSLListElem(expanded, tok);
incCurrSLListPos(realArg[i]);
}
}
incCurrSLListPos(mCode);
}
// And now, put back into tokQue
prependTokQue(expanded, pos);
}
// cleanup
for (i = 0; i < numArgs; i++) {
zapSLList(realArg[i], NULL);
}
zapSLList(expanded, NULL);
}
if (!retval) {
// error has occured: put backList back into tokQue
while (popStackElem(backList, &tok)) {
addBegSLListElem(tokQue, tok);
}
}
zapSLList(backList, NULL);
return retval;
}
static int pushMacroCode(pSLList macroCode, char *name, pTokPos pos,
ExpOpType expandOp) {
pToken tok;
rewindCurrSLListPos(macroCode);
if (getCurrSLListPosElem(macroCode, &tok)) {
if (tok->data->code == Y_PRE_SPECIAL_LEFT_PAREN) {
return expandMacroWithParams(macroCode, name, pos, expandOp);
} else {
prependTokQue(macroCode, pos);
return 1;
}
}
return 1;
}
static pToken getNextTokQueElemEmitEOL(int emitEol) {
pToken tok;
do {
tok = getNextTokQueElem();
} while (!emitEol && tok->data->code == Y_PRE_NEWLINE);
return tok;
}
static pToken getNextTokQueElem(void) {
pToken token;
WicErrors err;
int continueFlag;
static int beginNewLine = 1;
if (unqueSLListElem(tokQue, &token)) {
return token;
}
if (beginNewLine) {
zapSLList(g_currLineCode, NULL);
g_currLineCode = createSLList();
beginNewLine = 0;
}
do {
continueFlag = 0;
token = createToken(createTokData(), createTokPos());
err = getNextToken(token);
while (err != ERR_NONE) {
reportError(err);
err = getNextToken(token);
}
if (token->data->code == Y_PRE_NEWLINE) {
beginNewLine = 1;
} else if (token->data->code == Y_PRE_COMMENT) {
continueFlag = 1;
/* Place all of the comments at the end of the line, but
before newline */
token->pos->colNum = MAX_COL_NUM-1;
addSLListElem(g_commentList, token);
continue;
} else if (token->data->code == Y_EOF) {
if (!eofScanned) {
if (popTokFile()) {
zapToken(token);
continueFlag = 1;
} else {
eofScanned = 1;
}
}
} else {
addSLListElem(g_currLineCode, token);
}
} while (continueFlag);
return token;
}
/*----------------------- getExpandToken ---------------------------*/
pToken getExpandToken(ExpOpType expandOp, int *expandResult) {
pToken token;
pSymTabEntry symbol;
int continueFlag;
*expandResult = 1;
do {
continueFlag = 0;
token = getNextTokQueElemEmitEOL(expandOp&EXP_OP_EMIT_EOL);
if ((expandOp&EXP_OP_EXPAND) && token->data->code == Y_ID) {
char *name = getTokenIdName(token);
symbol = findSymbol(name);
if (symbol != NULL) {
if (symbol->type == SYMT_MACRO) {
*expandResult = pushMacroCode(symbol->repr.macroCode,
name, token->pos, expandOp);
// In case of error above, the tokQue is unmodified, and we
// may return the current token
continueFlag = *expandResult;
} else if (symbol->type == SYMT_TYPEDEF) {
token->data->code = Y_TYPEDEF_NAME;
token->data->repr.pTypeDecl = symbol->repr.typeCode;
}
}
}
} while(continueFlag);
return token;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?