2016-11-02 36 views
0

我使用flex和bison準備好掃描儀和分析器。在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,那些應該會收到我想要的值。

研究,我發現我可以嘗試使用聯合{}來獲取特定類型的每個標記。也許這可能有幫助?如果是這樣,我一定需要指定每個令牌的類型?那該如何實施?

yytext怎麼樣?難道這不能用來實現這個目標嗎?

謝謝!

--- 編輯 -

所以我創建

%union { 
    char *string; 
    STreeNode *node; 
} 

,並指定每個終端和非終端類型是其中的一個。節點仍在工作,但使用(例如$ 1)的字符串返回null。

我是否需要更改掃描儀中的任何內容?我的掃描儀有:

[a-zA-Z][a-z0-9A-Z]*  { return IDENTIFIER; } 
[0-9]+      { return INTEGER; } 

再次感謝。

+0

如果您使用的是野牛,爲什麼標記爲'yacc'? –

+0

只是一個小問題,與您的問題無關,但爲什麼您爲不需要它的事物創建節點?不要爲'conditioal'創建一個新節點,爲什麼不簡單地將$ $$設置爲'$ 1'?這將簡化你的樹,並導致其中更少的節點。 –

+0

@ScottHunter'flex'標籤是針對[Apache Flex](http://flex.apache.org/)而不是GNU lex克隆的,因此我將其刪除。 –

回答

0

如果您的令牌具有爲其設置的類型,則詞法分析器需要將yylval設置爲相關類型。例如:

[a-zA-Z][a-z0-9A-Z]*  { yylval.string = strdup(yytext); return IDENTIFIER; } 
[0-9]+      { yylval.string = strdup(yytext); return INTEGER; } 
相關問題