2009-06-04 9 views
12

क्या वाईएसीसी (या मैं अपना केस एमपीपीजी) एक सार सिंटेक्स ट्री (एएसटी) आउटपुट करना संभव बनाता हूं।वाईएसीसी आउटपुट को एएसटी (टोकन ट्री) बनाना

मैं जो चीजें पढ़ रहा हूं, उसे यह बताता है कि वाईएसीसी ऐसा करने के लिए आसान है, लेकिन मैं यह देखने के लिए संघर्ष कर रहा हूं कि पेड़ में नोड को स्थानांतरित करने के दौरान आप कैसे जानते हैं।

उत्तर

5

क्या आपने the manual पर देखा है (स्पॉट खोजने के लिए "पार्स पेड़" खोजें)? यह सुझाव देता है कि नोड सृजन को आपके बाएं और दाएं वंशजों के साथ $ 1 और $ 3, या जो भी हो, के साथ कार्रवाई में डालने का सुझाव दिया गया है। इस मामले में, yacc मैन्युअल रूप से करने के बजाय आपकी ओर से पेड़ को आगे बढ़ाएगा। मान लें कि आप जो पेड़ में एक वस्तु बनाता समारोह node के साथ अपने सार वाक्य रचना पेड़ है

:

expr : expr '+' expr 
    { 
    $$ = node('+', $1, $3); 
    } 

+1

धन्यवाद, मैं Lexx और याक पुस्तक में इस से पहले देखा था में वापसी से पहले बनाई गई हैं। लेकिन मैं इसे एक मृत अंत के रूप में लिखना चाहता था। इसे सभी को एक साथ लटकने के लिए आपको लेक्सटाइप को संशोधित करने की आवश्यकता है जो संघ टैग % संघ { निजी राज्य _स्टेट में परिभाषित है; ... लेक्सवैल्यू (राज्य राज्य, वस्तु बच्चा 1, वस्तु बच्चा 2) {...} } यह आपको अपने राज्य के रूप में एक पेड़ नोड स्टोर करने की अनुमति देता है। फिर आप $$ उपनाम $$ = नए लेक्सवैल्यू (राज्य .chemaImport, $ 3, $ 5) का उपयोग करके डेटा असाइन कर सकते हैं; नोट: लेक्सर को इस संरचना में अपने टोकन डेटा को भी धक्का देना होगा। आसान जब आप जानते हैं कि कैसे ... – Sprotty

6

हाओ के मुद्दे पर और the manual से विस्तार करते हुए, आप निम्नलिखित की तरह कुछ करना चाहता हूँ यह कोड "प्लस के साथ अभिव्यक्ति को पार करते समय, बाएं और दाएं वंशज $1/$3 ले जाएं और उन्हें नोड के लिए तर्क के रूप में उपयोग करें। आउटपुट को अभिव्यक्ति के $$ (वापसी मूल्य) पर सहेजें।

$$ (मैनुअल से):

एक मूल्य के लौटने के लिए, कार्रवाई सामान्य रूप से कुछ मूल्य के लिए pseudovariable `` $$ '' निर्धारित करता है।

1

अन्य उत्तर व्याकरण को संशोधित करने का प्रस्ताव है, इस जब एक सी ++ व्याकरण (नियमों के कई सौ ..)

सौभाग्य के साथ खेल संभव नहीं है, हम यह स्वचालित रूप से कर सकते हैं, डिबग को पुनर्परिभाषित द्वारा मैक्रो। इस कोड में, हम YY_SYMBOL_PRINTYYDEBUG साथ actived को पुनर्परिभाषित कर रहे हैं:

%{ 

typedef struct tree_t { 
    struct tree_t **links; 
    int nb_links; 
    char* type; // the grammar rule 
}; 

#define YYDEBUG 1 
//int yydebug = 1; 

tree_t *_C_treeRoot; 
%} 
%union tree_t 

%start program 

%token IDENTIFIER 
%token CONSTANT 

%left '+' '-' 
%left '*' '/' 
%right '^' 

%% 
progam: exprs { _C_treeRoot = &$1.t; } 
    | 
    | hack 
    ; 

exprs: 
    expr ';' 
    | exprs expr ';' 
    ; 


number: 
    IDENTIFIER 
    | '-' IDENTIFIER 
    | CONSTANT 
    | '-' CONSTANT 
    ; 

expr: 
    number 
    | '(' expr ')' 
    | expr '+' expr 
    | expr '-' expr 
    | expr '*' expr 
    | expr '/' expr 
    | expr '^' expr 
    ; 

hack: 
    { 
    // called at each reduction in YYDEBUG mode 
    #undef YY_SYMBOL_PRINT 
    #define YY_SYMBOL_PRINT(A,B,C,D) \ 
     do { \ 
      int n = yyr2[yyn]; \ 
      int i; \ 
      yyval.t.nb_links = n; \ 
      yyval.t.links = malloc(sizeof *yyval.t.links * yyval.t.nb_links);\ 
      yyval.t.str = NULL; \ 
      yyval.t.type = yytname[yyr1[yyn]]; \ 
      for (i = 0; i < n; i++) { \ 
       yyval.t.links[i] = malloc(sizeof (YYSTYPE)); \ 
       memcpy(yyval.t.links[i], &yyvsp[(i + 1) - n], sizeof(YYSTYPE)); \ 
      } \ 
     } while (0) 

    } 
    ; 
%% 

#include "lexer.c" 


int yyerror(char *s) { 
    printf("ERROR : %s [ligne %d]\n",s, num_ligne); 
    return 0; 
} 


int doParse(char *buffer) 
{ 
    mon_yybuffer = buffer; 
    tmp_buffer_ptr = buffer; 
    tree_t *_C_treeRoot = NULL; 
    num_ligne = 1; 
    mon_yyptr = 0; 

    int ret = !yyparse(); 

    /////////**** 
      here access and print the tree from _C_treeRoot 
    ***/////////// 
} 


char *tokenStrings[300] = {NULL}; 
char *charTokenStrings[512]; 

void initYaccTokenStrings() 
{ 
    int k; 
    for (k = 0; k < 256; k++) 
    { 
     charTokenStrings[2*k] = (char)k; 
     charTokenStrings[2*k+1] = 0; 
     tokenStrings[k] = &charTokenStrings[2*k]; 
    } 
    tokenStrings[CONSTANT] = "CONSTANT"; 
    tokenStrings[IDENTIFIER] = "IDENTIFIER"; 


    extern char space_string[256]; 

    for (k = 0; k < 256; k++) 
    { 
     space_string[k] = ' '; 
    } 
} 

लीफ़्स सिर्फ FLEX lexer

संबंधित मुद्दे