2011-10-28 50 views
2

我的語法是這樣如何在Bison解析器上返回多個標記?

decl: 

    attributes; {/*create an object here with the attributes $$?*/ } 


attributes: 



    | 

    att1 attributes {$$ = $1;} 

    | 

    att2 attributes {$$ = $1;} 

    | 

    attn attributes {$$ = $1;}; 

我想獲得用戶,他們中的一些是可選的,次序沒關係,類型不同

回答

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; 

    }; 
+0

感謝您的解決方案工作好的,我在if語句中遇到了麻煩,但這是另一個話題。我發佈了一個更通用的解決方案 – Warer

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; 
} 
//... 
;