我的语法是这样的
decl:
attributes; {/*create an object here with the attributes $$?*/ }
attributes:
|
att1 attributes {$$ = $1;}
|
att2 attributes {$$ = $1;}
|
attn attributes {$$ = $1;};
我想获取用户输入的所有属性,其中一些是可选的,顺序无关紧要,类型不同
答案 0 :(得分:1)
您需要在$$
变量中返回结构;根据需要分配给其成员。以下是我方便的一些代码示例:
struct value_list {
char *value;
struct value_list *next;
};
# ...
valuelist: TOK_VALUE
{
struct value_list *new = calloc(1, sizeof(struct value_list));
if (!new)
yyerror(_("Memory allocation error."));
PDEBUG("Matched: value (%s)\n", $1);
new->value = $1;
new->next = NULL;
$$ = new;
}
valuelist: valuelist TOK_VALUE
{
struct value_list *new = calloc(1, sizeof(struct value_list));
if (!new)
yyerror(_("Memory allocation error."));
PDEBUG("Matched: value (%s)\n", $1);
new->value = $2;
new->next = $1;
$$ = new;
}
来自同一个解析器的另一个例子,它比基于上述更简单的规则更加努力地根据条目自定义struct
;缺点是这变得非常复杂,但好处是这可以更好地展示单个对象的属性:
/* from a header file */
struct codomain {
char *namespace;
char *name; /* codomain name */
char *attachment;
struct alt_name *altnames;
void *xmatch;
size_t xmatch_size;
int xmatch_len;
/* ... and it goes on like this ... */
}
# from the grammar:
profile_base: TOK_ID opt_id flags TOK_OPEN rules TOK_CLOSE
{
struct codomain *cod = $5;
if (!cod) {
yyerror(_("Memory allocation error."));
}
cod->name = $1;
cod->attachment = $2;
if ($2 && $2[0] != '/')
/* we don't support variables as part of the profile
* name or attachment atm
*/
yyerror(_("Profile attachment must begin with a '/'."));
cod->flags = $3;
if (force_complain)
cod->flags.complain = 1;
post_process_nt_entries(cod);
PDEBUG("%s: flags='%s%s'\n",
$3,
cod->flags.complain ? "complain, " : "",
cod->flags.audit ? "audit" : "");
$$ = cod;
};
答案 1 :(得分:1)
struct objectStruct{
char* name;
int value;
objectStruct next;
//...
}
现在的语法
decl:
attributes {
objectStruct* myObject = $1;
while(myObject!=NULL){
if(myObject->name!=NULL){
//do something with name
myObject=myObject->next;
}
else if(myObject->value!=NULL){
//do something with value
myObject=myObject->next;
}
//...
}
};
attributes:
{$$=NULL;}
|
NAME attributes {
objectStruct* myObject = new objectStruct();
myObject->name = $1;
myObject->value = NULL;
myObject->next = $2;
$$=myObject;
}
|
VALUE attributes {
objectStruct* myObject = new objectStruct();
myObject->value = $1;
myObject->name= NULL;
myObject->next = $2;
$$=myObject;
}
//...
;