我正在为给定的AST实现字节码生成器。在创建表达式类时,我注意到一元和二进制运算符之间的区别。为简单起见,unum是首选解决方案,因此我以这种方式嵌套了enuns:
enum EXP_TYPE
{
enum BINARY
{
PLUS,
MINUS,
MULTIPLY,
DIV,
...
};
enum UNARY
{
PLUS,
MINUS,
POINTER,
INC,
...
};
};
当然,此代码会发出警告,告知不允许这样做。所以,我搜索了计算器和其他来源了一下,发现使用的解决方案namespace
,而不是enum
对EXP_TYPE声明。但是现在的问题是在表达式类内部的使用:
class expression
{
expression *right_exp;
expression *left_exp;
EXP_TYPE type;
...
};
由于EXP_TYPE是anamespace
而不是enum
类型,因此已不再允许使用。我打算做的是一个通用enum
声明,可以将其用作类中的属性,在这里泛型意味着它可以是BINARY或UNARY,也就是说,该属性EXP_TYPE type
可以具有如下赋值和比较:
expression exp1;
exp1.type = EXP_TYPE::BINARY::PLUS;
exp1.type = EXP_TYPE::UNARY::PLUS;
有没有一种方法可以使这些简单的泛型类型不使用namespace
呈现的方式,也不需要为一元和二进制运算符创建类层次结构?
我把这当作难题,以了解我能达到OP要求的距离。
这就是我得到的(尽管我必须承认它看起来有点吓人):
#include <cassert>
#include <iostream>
struct ExpType {
struct Unary {
enum {
Plus, Minus, Pointer, Inc,
N
};
};
struct Binary {
enum {
Plus = Unary::N, Minus, Multiply, Div,
N
};
};
enum {
N = Binary::N
};
int value;
ExpType(int value = 0): value((assert(value >= 0 && value < N), value)) { }
~ExpType() = default;
ExpType(const ExpType&) = default;
ExpType& operator=(const ExpType&) = default;
operator int () { return value; }
};
int main()
{
for (int i = 0; i < ExpType::N; ++i) {
ExpType expType = i;
switch (expType) {
#define CASE(TYPE) case TYPE: std::cout << #TYPE "\n"; break
CASE(ExpType::Unary::Plus);
CASE(ExpType::Unary::Minus);
CASE(ExpType::Unary::Pointer);
CASE(ExpType::Unary::Inc);
CASE(ExpType::Binary::Plus);
CASE(ExpType::Binary::Minus);
CASE(ExpType::Binary::Multiply);
CASE(ExpType::Binary::Div);
#undef CASE
default: std::cout << "Unknown expression type!\n";
}
}
}
输出:
ExpType::Unary::Plus
ExpType::Unary::Minus
ExpType::Unary::Pointer
ExpType::Unary::Inc
ExpType::Binary::Plus
ExpType::Binary::Minus
ExpType::Binary::Multiply
ExpType::Binary::Div
但是,我必须承认,我个人肯定会喜欢其他答案中的建议。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句