在 Bison 中使用自定义类型时访问标识符内容
Access identifier content when using a custom type in Bison
我使用 flex 和 bison 准备好了扫描器和解析器。
解析器直接在动作中构建树,为此我创建了一个名为 STreeNode 的结构,我正在使用
#define YYSTYPE_IS_DECLARED
typedef STreeNode* YYSTYPE;
结构是:
typedef struct tagSTreeNode
{
EOperationType type;
int count;
struct tagSTreeNode **children;
char *string;
} STreeNode;
大约有 40 个标记,对于每条规则,我都有
unlabeled_statement:
assignment {$$ = createNode(eUNLABELED_STATEMENT, 1, );}
| function_call_statement {$$ = createNode(eUNLABELED_STATEMENT, 1, );}
| goto {$$ = createNode(eUNLABELED_STATEMENT, 1, );}
| return {$$ = createNode(eUNLABELED_STATEMENT, 1, );}
| conditional {$$ = createNode(eUNLABELED_STATEMENT, 1, );}
| repetitive {$$ = createNode(eUNLABELED_STATEMENT, 1, );}
| empty_statement {$$ = createNode(eUNLABELED_STATEMENT, 1, );}
;
createNode 函数的签名是
STreeNode *createNode(EOperationType type, int count, ...) {
这棵树工作正常。问题是访问变量名、函数名等的真实值。由于 YYSTYPE 是一个结构,$x 没有我想保存在结构中的 char * 字符串元素上的字符串值。
我有一个名为 IDENTIFIER 的 %token 和另一个名为 INTEGER 的令牌,它们应该接收我想要的值。
经过研究,我发现我可以尝试使用 union { } 来获得特定类型的每个标记。也许这会有所帮助?如果是这样,我一定需要指定每个令牌的类型吗?如何实施?
yytext呢?难道不能用来实现这个目标吗?
谢谢!
--- 编辑 --
所以我创建了
%union {
char *string;
STreeNode *node;
}
并指定每个终端和非终端类型都是其中之一。节点仍在工作,但使用 (例如 $1) 的字符串返回空值。
我还需要更改扫描仪中的任何内容吗?我的扫描仪有:
[a-zA-Z][a-z0-9A-Z]* { return IDENTIFIER; }
[0-9]+ { return INTEGER; }
再次感谢。
如果你的标记有一个类型设置,词法分析器需要将 yylval
设置为有问题的类型。类似于:
[a-zA-Z][a-z0-9A-Z]* { yylval.string = strdup(yytext); return IDENTIFIER; }
[0-9]+ { yylval.string = strdup(yytext); return INTEGER; }
我使用 flex 和 bison 准备好了扫描器和解析器。
解析器直接在动作中构建树,为此我创建了一个名为 STreeNode 的结构,我正在使用
#define YYSTYPE_IS_DECLARED
typedef STreeNode* YYSTYPE;
结构是:
typedef struct tagSTreeNode
{
EOperationType type;
int count;
struct tagSTreeNode **children;
char *string;
} STreeNode;
大约有 40 个标记,对于每条规则,我都有
unlabeled_statement:
assignment {$$ = createNode(eUNLABELED_STATEMENT, 1, );}
| function_call_statement {$$ = createNode(eUNLABELED_STATEMENT, 1, );}
| goto {$$ = createNode(eUNLABELED_STATEMENT, 1, );}
| return {$$ = createNode(eUNLABELED_STATEMENT, 1, );}
| conditional {$$ = createNode(eUNLABELED_STATEMENT, 1, );}
| repetitive {$$ = createNode(eUNLABELED_STATEMENT, 1, );}
| empty_statement {$$ = createNode(eUNLABELED_STATEMENT, 1, );}
;
createNode 函数的签名是
STreeNode *createNode(EOperationType type, int count, ...) {
这棵树工作正常。问题是访问变量名、函数名等的真实值。由于 YYSTYPE 是一个结构,$x 没有我想保存在结构中的 char * 字符串元素上的字符串值。
我有一个名为 IDENTIFIER 的 %token 和另一个名为 INTEGER 的令牌,它们应该接收我想要的值。
经过研究,我发现我可以尝试使用 union { } 来获得特定类型的每个标记。也许这会有所帮助?如果是这样,我一定需要指定每个令牌的类型吗?如何实施?
yytext呢?难道不能用来实现这个目标吗?
谢谢!
--- 编辑 --
所以我创建了
%union {
char *string;
STreeNode *node;
}
并指定每个终端和非终端类型都是其中之一。节点仍在工作,但使用 (例如 $1) 的字符串返回空值。
我还需要更改扫描仪中的任何内容吗?我的扫描仪有:
[a-zA-Z][a-z0-9A-Z]* { return IDENTIFIER; }
[0-9]+ { return INTEGER; }
再次感谢。
如果你的标记有一个类型设置,词法分析器需要将 yylval
设置为有问题的类型。类似于:
[a-zA-Z][a-z0-9A-Z]* { yylval.string = strdup(yytext); return IDENTIFIER; }
[0-9]+ { yylval.string = strdup(yytext); return INTEGER; }