2013-06-27 42 views
1

以下代碼應該生成輸入表達式的解析樹,但問題在於輸出E,T,F,S(代碼中使用的函數)。我希望它是這樣的:在c中生成分析樹

A + B * C => E * c => E + B * C => A + B * C

 #include <stdio.h> 
    #include <stdlib.h> 
    #include <ctype.h> 
    char next; 
    void E(void);void T(void); 
    void S(void);void F(void); 
    void error(int);void scan(void); 
    void enter(char); 
    void leave(char); 
    void spaces(int); 
    int level = 0; 



    //The main should always be very simple 
    //First scan the string 
    //second check for end of string reached , if yes success and if not error. 

    //P ---> E '#' 
    int main(void){ 
     printf("Input:"); 
     scan(); E(); 
     if (next != '#') error(1); 
     else printf("***** Successful parse *****\n"); 
    } 

    //E ---> T {('+'|'-') T} 
    void E(void){ 
     enter('E'); 
     T(); 
     while (next == '+' || next == '-') { 
      scan(); 
      T(); 
     } 
     leave('E'); 
    } 


    //T ---> S {('*'|'/') S} 
    void T(void) 
    { 
     enter('T'); S(); 
     while (next == '*' || next == '/') { 
      scan(); S(); 
     } 
     leave('T'); 
    } 

    //S ---> F '^' S | F 
    void S(void) 
    { 
     enter('S'); F(); 
     if (next == '^') { 
      scan(); S(); 
     } 
     leave('S'); 
    } 

    //F ---> char | '(' E ')' 
    void F(void) 
    { 
     enter('F'); 
     if (isalpha(next)) 
     { 
      scan(); 
     } 
     else if (next == '(') { 
      scan(); E(); 
      if (next == ')') 
       scan(); 
      else 
       error(2); 
     } 
     else { 
      error(3); 
     } 
     leave('F'); 
    } 
    //Scan the entire input 
    void scan(void){ 
     while (isspace(next = getchar())); 
    } 

    void error(int n) 
    { 
     printf("\n*** ERROR: %i\n", n); 
     exit(1); 
    } 

    void enter(char name) 
    { 
     spaces(level++); 
     printf("+-%c\n", name); 
    } 

    void leave(char name) 
    { 
     spaces(--level); 
     printf("+-%c\n", name); 

    } 
    //TO display the parse tree 
    void spaces(int local_level) 
    { 
     while (local_level-- > 0) 
     printf("| "); 
    } 
+0

我完全困惑。你是什​​麼意思,「問題是輸出E,T,F,S」? (當我在同一個輸入上運行它時,我看不到任何類似輸出。)「a + b * c」與「E * c」等價嗎?你爲什麼最終會用同樣的表達方式?你想要的序列與程序生成輸出的方式有什麼關係(這似乎是正確的,順便說一句)? –

+0

實際上a + b * c只是一個例子,並且認爲它是樹,所以'*'優先級高,它將首先評估,左邊部分將被視爲表達式,即'E',類似地a + b,當然你在樹中獲得與實際相同的表達式。 –

+0

問題是這段代碼是以E,T,F,S的形式給出輸出,當它需要輸入表達式時,它應該給出同樣的表達式......:/我很困惑應該做什麼樣的改變要做到這一點... :) –

回答

0

你不」不必選擇分析樹。我想你不明白的輸出,但(再次)我想你想

​​

因此,這裏有幾個問題,以幫助。

  1. 什麼樣的解析正在那裏進行?自下而上或自上而下?
  2. 解析器打印時的狀態輸入/輸出ET

如果你回答了第一個問題,E,T,S,F,F表示什麼(輸入E,輸入T,輸入S,輸入F,離開F)?當您離開F時,意味着解析器成功識別了非終端。 嘗試輸入字符串1+b*c。你得到了什麼?爲什麼在E,T,S,F之後出現錯誤?

如果您瞭解當前生成的內容,您似乎需要的輸出可以很容易地生成。希望這可以幫助。

0

看起來像一個遞歸下降解析器。首先,手工制定你的語法。你所期望的不是你的語法所說的。你得從你的意見,

E ---> T {('+'|'-') T} expression 
T ---> S {('*'|'/') S} term 
S ---> F '^' S | F  subexpression? 
F ---> char | '(' E ')' factor 

E的定義和T把*在優先級高於+,所以沒有辦法,你將獲得E *℃。如果你想,你就必須語法切換到

E ---> T {('*'|'/') T} expression 
T ---> S {('+'|'-') S} term 

如果你只是想輸出中包含的表達式的其餘部分,

  1. 得到全行
  2. 變化您的掃描儀或詞法分析器從該掃描線中獲取下一個字符。將其標記爲掃描點。
  3. 更改Enter例程以打印助記符以及掃描點中的行。