如何解析为数据结构供以后执行? (弹性 - 野牛)
How can I parse into a data structure for later execution? (Flex - Bison)
这是一项学校作业。我只是在寻找正确方向的一点。也许我只是在看到它时不认识答案(谷歌搜索)。
我不想解析语法并立即执行{action},而是想将所有内容推送到数据结构中供以后执行。例如:IF-cond-stmt-ELSE-stmt,当正常解析时,两个 stmt 都会被执行。我想如果我能把它放在某个地方,我就能控制发生的事情。
我错了吗?
完全正确。
创建数据结构的通常方法是通过将 $$
(即产生式的语义值)设置为以该节点为根的子树来构建它(作为一种树)。
例如:
%{
typedef
struct Operation {
short type;
short operator;
union {
struct {
struct Operation* left;
struct Operation* right;
};
Identifier* id;
// ... other possible value types
};
} Operation;
Operation* new_binary_node(int operator, Operation* left, Operation* right) {
Operation* subtree = malloc(sizeof *subtree);
subtree->type = BINOP;
subtree->operator = operator;
subtree->left = left;
subtree->right = right;
}
Operation* new_identifier_node(Identifier* id) {
Operation* subtree = malloc(sizeof *subtree);
subtree->type = IDENTIFIER;
subtree->id = id;
}
void free_node(Operation* subtree) {
if (subtree) {
switch (subtree->operator) {
case BINOP: free_node(subtree->left);
free_node(subtree->right);
break;
case IDENTIFIER:
free_identifier(subtree->id);
break;
// ...
}
free(subtree);
}
}
%}
%union {
Operator* op;
Identifier* id;
}
%type <op> expr
%token <id> IDENTIFIER
%left '+' '-'
%left '*' '/'
/* ... */
%%
expr: expr '+' expr { $$ = new_binary_node('+', , ); }
| expr '-' expr { $$ = new_binary_node('-', , ); }
| expr '*' expr { $$ = new_binary_node('*', , ); }
| expr '/' expr { $$ = new_binary_node('/', , ); }
| IDENTIFIER { $$ = new_identifier_node(); }
| '(' expr ')' { $$ = ; }
/* ... */
这是一项学校作业。我只是在寻找正确方向的一点。也许我只是在看到它时不认识答案(谷歌搜索)。
我不想解析语法并立即执行{action},而是想将所有内容推送到数据结构中供以后执行。例如:IF-cond-stmt-ELSE-stmt,当正常解析时,两个 stmt 都会被执行。我想如果我能把它放在某个地方,我就能控制发生的事情。
我错了吗?
完全正确。
创建数据结构的通常方法是通过将 $$
(即产生式的语义值)设置为以该节点为根的子树来构建它(作为一种树)。
例如:
%{
typedef
struct Operation {
short type;
short operator;
union {
struct {
struct Operation* left;
struct Operation* right;
};
Identifier* id;
// ... other possible value types
};
} Operation;
Operation* new_binary_node(int operator, Operation* left, Operation* right) {
Operation* subtree = malloc(sizeof *subtree);
subtree->type = BINOP;
subtree->operator = operator;
subtree->left = left;
subtree->right = right;
}
Operation* new_identifier_node(Identifier* id) {
Operation* subtree = malloc(sizeof *subtree);
subtree->type = IDENTIFIER;
subtree->id = id;
}
void free_node(Operation* subtree) {
if (subtree) {
switch (subtree->operator) {
case BINOP: free_node(subtree->left);
free_node(subtree->right);
break;
case IDENTIFIER:
free_identifier(subtree->id);
break;
// ...
}
free(subtree);
}
}
%}
%union {
Operator* op;
Identifier* id;
}
%type <op> expr
%token <id> IDENTIFIER
%left '+' '-'
%left '*' '/'
/* ... */
%%
expr: expr '+' expr { $$ = new_binary_node('+', , ); }
| expr '-' expr { $$ = new_binary_node('-', , ); }
| expr '*' expr { $$ = new_binary_node('*', , ); }
| expr '/' expr { $$ = new_binary_node('/', , ); }
| IDENTIFIER { $$ = new_identifier_node(); }
| '(' expr ')' { $$ = ; }
/* ... */