我准备好扫描仪和解析器,使用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; }
再次感谢。
答案 0 :(得分:0)
如果您的令牌为其设置了类型,则词法分析器需要将yylval
设置为相关类型。类似的东西:
[a-zA-Z][a-z0-9A-Z]* { yylval.string = strdup(yytext); return IDENTIFIER; }
[0-9]+ { yylval.string = strdup(yytext); return INTEGER; }