2012-05-24 80 views
4

我正在學習解析,bison & lex。我找了一個明確的&完整的教程/示例演示了所有:Bison/Flex教程使用C++,AST和可重複使用的詞法分析器和解析器

  1. C++(不是C)抽象語法樹。
  2. 重入詞法分析器。
  3. 重入解析器。
  4. 從字符串中讀取(與文件相比)也不錯。

我發現了多個示例和教程,但每個示例和教程通常只滿足上述幾個要求。到目前爲止,我最好的教程來自John Levine的Oreilly書中的第3-2章 - 它有AST;所有C雖然,只會遇到Re_1以上。我歡迎有關好的示例/教程,現實生活中的開源項目的建議。例如,我看到MySql .yy文件 - 看起來寫得很好,但對於像我這樣的初學者來說太大/複雜了。

+0

您的意思是用C++編碼?或者你想解析C++? –

+0

我希望我的代碼與flex/bison交互爲C++。特別是AST(抽象語法樹)。提到的例子取決於c型寬大。另外,我想使用STL等等。至於我想解析的內容:一個類似於正則表達式的簡單語法。 –

回答

4

最後我結合了幾個例子來得到我想要的。前兩個例子來自John Levine關於野牛& flex(第二版),ISBN-10:0596155972的書。另外一個例子來自一個php編譯器網站,它不幸於2017-02-28不再存在。如果網站存檔在某處,我將離開鏈接:www.phpcompiler.org/articles/reentrantparser.html

謝謝阿德里安,這裏是已存檔的版本(作品於2017-03-02):

http://web.archive.org/web/20120520150851/http://www.phpcompiler.org/articles/reentrantparser.html

+1

該鏈接似乎已經死亡。 – Adrien

+0

事實上,phpcompiler.org網站已經沒有了,謝謝你通知我。我已經編輯了我的2012年答案。 –

+0

嗨Radim,我碰巧需要編寫一個(不是那麼簡單)的編譯器。你可以上傳你組裝到Github之類的例子嗎?人們可能會發現它很有用,因爲現有的例子並不容易。只是想知道,謝謝。 – jack

1

首先我想說C++語法對於Lex/Bison來說太複雜了。這裏的問題主要是在語法衝突中。編寫沒有它們的C++語法是不可能的。 C++標準明確規定了這一點,幷包含一些關於如何解決它們的指導原則。

解決語法衝突沒有通用的解決方案。特別是C++的語法衝突解決方案需要詳細瞭解已定義的標識符。這意味着你需要擁有更大部分的C++前端。只有語法是不夠的。

儘管如此,構建AST仍是可能的。看一個小樣本程序。

class HashEntry 
{ 
private: 

     int key; 
     int value; 

public: 

     HashEntry(int key, int value) 
     { 
      this->key = key; 
      this->value = value; 
     } 

     int getKey() { return key; } 

     int getValue() { return value; } 
}; 

const int TABLE_SIZE = 128; 

class HashMap 
{ 
private: 

     HashEntry **table; 

public: 

     HashMap() 
     { 
      table = new HashEntry*[TABLE_SIZE]; 

      for (int i = 0; i < TABLE_SIZE; i++) 
        table[i] = NULL; 
     } 

     int get(int key) 
     { 
      int hash = (key % TABLE_SIZE); 

      while (table[hash] != NULL && table[hash]->getKey() != key) 
        hash = (hash + 1) % TABLE_SIZE; 

      if (table[hash] == NULL) 
        return -1; 
      else 
        return table[hash]->getValue(); 
     } 

     void put(int key, int value) 
     { 
      int hash = (key % TABLE_SIZE); 

      while (table[hash] != NULL && table[hash]->getKey() != key) 
        hash = (hash + 1) % TABLE_SIZE; 

      if (table[hash] != NULL) 
        delete table[hash]; 

      table[hash] = new HashEntry(key, value); 
     }  

     ~HashMap() 
     { 
      for (int i = 0; i < TABLE_SIZE; i++) 
        if (table[i] != NULL) 
         delete table[i]; 

      delete[] table; 
     } 
}; 

這是對這一計劃的AST: enter image description here

這棵樹被嚴重縮小。葉子上的黃色圓圈(非常小)是終端符號,中間的綠色圓圈是非終端符號。中心的粉紅色圓圈就是TranslationUnit。這棵樹有2009個節點。

+1

嗨基里爾,正如我在另一個評論中指出的,我不是想解析C++,我只是想在C++項目中使用bison/flex。我現在有一個解決方案,我會試着去解決這個問題。 –