Hi I'm writing rpn calculator in C and I'd to compile rpn expression to byte-code. But I'm not sure what would be the data structure to represent them??? My stack data structure so far is
struct stack_t{
int type;
union {
double val;
开发者_如何学Go char *str;
/* probably some more */
}u;
};
It actually depends a lot on the feature set you are going to support. For example, if your calculator supports integers (e.g., integer division), you probably would need int
in your union.
The advantage of RPN bytecode is that it doesn't need to be stored in a special structure. An array/vector/list will do. You need a stack to interpret it, but to store the program you should only convert each token to a bytecode instruction.
As for what types to put in your union, it really depends on the semantics of your calculator. Why do you want to be able to store strings? Do you plan on using strong typing?
Look into Forth, the canonical simple RPN language.
I've gone through several re-writes of a postscript interpreter, and while my object struct started out exactly like yours, I eventually found this layout to be "better" for reasons that I may not be able to articulate. I found this idea in the X11 Event structure.
typedef struct {
word tag;
word pad;
dword padw;
} mark_;
typedef struct {
word tag;
word pad;
integer val;
} int_;
typedef struct {
word tag;
word pad;
real val;
} real_;
typedef struct {
word tag;
word sz;
word ent;
word off;
} comp_;
typedef union {
word tag;
mark_ mark_;
int_ int_;
real_ real_;
comp_ comp_;
} object;
It may seem redundant to have the tag both outside and inside each structure, but it keeps everything in nice little boxes. It allows you to see the memory layout more clearly.
Edit: I call it "tag" instead of "type" because it contains both type and flags.
Edit: One of the reasons I consider this better is it eliminates the .u
term from the access expressions. Instead of stk.u.val
, you have stk.real_.val
or stk.int_.val
. The union part is shifted upstream, so the data portions can have internal structure without additional nesting. And the tag
is still accessible at the top-level to determine which sub-type is being used.
精彩评论