您需要輸入的所有屬性返回$$
變量中的結構;根據需要分配給其成員。下面是一些代碼,我放在手邊的例子:
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;
};
感謝您的解決方案工作好的,我在if語句中遇到了麻煩,但這是另一個話題。我發佈了一個更通用的解決方案 – Warer