所以我正在编写一个词法分析器,并且在我的宏生成 token 时遇到了问题( token 是一个具有值类型(枚举)和值( union )的结构。
#define MAKE_TOKEN(token, tokenType, valueType, tokValue) \
token.type=tokenType; \
token.value.type=valueType; \
switch(valueType){ \
case VAL_NIL: break; \
case VAL_BOOL: token.value.as.boolean=(bool)tokValue; break; \
case VAL_NUMBER: token.value.as.number=(double)tokValue; break; \
case VAL_STRING: token.value.as.string=(char*)tokValue; break; \
}
例如,如果 tokValue 为 5(因为 5 可以转换为 bool、double 和 char*),则此方法有效,但是,这不会编译,因为编译器无法将字符串转换为 double。这意味着当值类型为 VAL_STRING 时无法使用该宏,如何解决这个问题?
最佳答案
你不能让它作为宏工作,因为 C 预处理器中的宏仅执行字符串插值,因此麻烦的行会执行以下操作:
case VAL_NUMBER: token.value.as.number=(double)"some_string"; break;
只需使用一个函数即可。没有明显的理由使该片段成为宏。
void MAKE_TOKEN(struct token *token, enum token_type tokenType, enum value_type valueType, void *tokValue) {
token->type = tokenType;
token->value.type = valueType;
switch(valueType){
case VAL_NIL:
break;
case VAL_BOOL:
token->value.as.boolean = *(bool*)tokValue;
break;
case VAL_NUMBER:
token->value.as.number = *(double*)tokValue;
break;
case VAL_STRING:
token->value.as.string = *(char**)tokValue;
break;
}
}
关于C 预处理器为多种类型赋值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59002201/