我是Bison的新手。我正在尝试实现一个解析器。我面临的主要问题是解析树。我收到一个与我无法消除的树相关的错误。它说“未知类型名称'树'”。这是我的y文件。如果有人能帮助我解决这个问题,我会很高兴的。我非常需要解析器。提前谢谢。
%{
#include <stdio.h>
#include <string.h>
void yyerror(const char *str)
{
fprintf(stderr,"error FAIL: %s\n",str);
}
int yywrap()
{
return 1;
}
enum treetype {operator_node, variable_node};
typedef struct tree {
enum treetype nodetype;
union {
struct {struct tree *left, *right; char operator;} an_operator;
char *a_variable;
} body;
} tree;
static tree *make_op (tree *l, char o, tree *r) {
tree *result= (tree*) malloc (sizeof(tree));
result->nodetype= operator_node;
result->body.an_operator.left= l;
result->body.an_operator.operator= o;
result->body.an_operator.right= r;
return result;
}
static void printtree (tree *t, int level) {
#define step 4
if (t)
switch (t->nodetype)
{
case operator_node:
printtree (t->body.an_operator.right, level+step);
printf ("%*c%c\n", level, ' ', t->body.an_operator.operator);
printtree (t->body.an_operator.left, level+step);
break;
case variable_node:
printf ("%*c%c\n", level, ' ', t->body.a_variable);
}
}
%}
%union {
char* a_variable;
tree* a_tree;
}
%start file
%token <a_variable> TOKDIGIT TOKFLOAT TOKID TOKSEMICOLON TOLCOLON TOKCOMMA TOKUNRECOG TOKCOMMENT TOKDOT TOKMINUS TOKCOLON
%type <a_tree> field object file ID
%right TOKMINUS
%%
file :
| object file { printtree($1, 1); }
;
object : field object {$$ = make_op($1, '', $2);}
| field {$$ = $1 ; }
;
field : ID TOKCOLON field {$$ = make_op ($1, ':', $3); }
| ID TOKCOMMA field {$$ = make_op ($1, ',', $3); }
| ID TOKSEMICOLON field {$$ = make_op ($1, ';', $3); }
;
ID : TOKID { $$ = $1; }
;
%%
答案 0 :(得分:2)
我将以下补丁应用于您的代码,以修复Bison中的一些警告。您的顶级规则缺少针对空案例的操作(因此无法分配给$$
)而另一个规则也没有为$$
分配任何内容。即您的file
规则没有将对象累积到主树中,因此您的yyparse
函数不会返回树:
Index: test/test.y
===================================================================
--- test.orig/test.y 2012-03-15 16:34:31.992021757 -0700
+++ test/test.y 2012-03-15 17:00:27.666596757 -0700
@@ -57,8 +57,9 @@
%%
-file :
- | object file { printtree($1, 1); }
+file : /* empty */ { return NULL; }
+ | object file { printtree($1, 1); return NULL; }
+ /* TODO: gather the objects into a tree and return */
;
object : field object {$$ = make_op($1, '', $2);}
| field {$$ = $1 ; }
现在,你的语法有问题。主要的一点是您的field
制作不会终止。他们产生无限的句子。 field
的每个作品都会生成以field
结尾的内容;语法扩展无法结束。
主要问题是你的语法中有太多的地方需要进行扩展,而且相同的东西也是如此。您的file
生成零个或多个object
。 object
的实例多为field
。然后一个字段也想生成更多field
。
这意味着您的file
实际上只是field
的序列。已经处理了多个field
- s的排序,并且它必须仅在一个级别处理;字段不必产生更多field
。