在Bison中使用自定义类型时访问标识符内容

时间:2016-11-02 12:46:46

标签: c bison yacc lex

我准备好扫描仪和解析器,使用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, $1);}
        | function_call_statement                                           {$$ = createNode(eUNLABELED_STATEMENT, 1, $1);}
        | goto                                                              {$$ = createNode(eUNLABELED_STATEMENT, 1, $1);}
        | return                                                            {$$ = createNode(eUNLABELED_STATEMENT, 1, $1);}
        | conditional                                                       {$$ = createNode(eUNLABELED_STATEMENT, 1, $1);}
        | repetitive                                                        {$$ = createNode(eUNLABELED_STATEMENT, 1, $1);}
        | empty_statement                                                   {$$ = createNode(eUNLABELED_STATEMENT, 1, $1);}
        ;

createNode函数的签名是

STreeNode *createNode(EOperationType type, int count, ...) {

树很好用。问题是访问变量名,函数名等的实际值。由于YYSTYPE是一个结构,$ x没有我想要保存在结构中char * string元素的字符串值。

我有一个名为IDENTIFIER的%标记和另一个名为INTEGER的标记,它们应该接收我想要的值。

研究,我发现我可以尝试使用union {}来获取特定类型的每个标记。也许那会有所帮助?如果是这样,我一定需要指定每个令牌的类型?如何实施?

yytext怎么样?无法用来实现这一目标吗?

谢谢!

--- 编辑 -

所以我已经创建了

%union {
    char *string;
    STreeNode *node;
}

并指定每个终端和非终端类型为其中之一。节点仍在工作,但使用(例如$ 1)的字符串返回null。

我是否还需要更改扫描仪中的任何内容?我的扫描仪有:

[a-zA-Z][a-z0-9A-Z]*        { return IDENTIFIER; }
[0-9]+                      { return INTEGER; }

再次感谢。

1 个答案:

答案 0 :(得分:0)

如果您的令牌为其设置了类型,则词法分析器需要将yylval设置为相关类型。类似的东西:

[a-zA-Z][a-z0-9A-Z]*        { yylval.string = strdup(yytext); return IDENTIFIER; }
[0-9]+                      { yylval.string = strdup(yytext); return INTEGER; }