用java實現一個簡易編譯器-文法解析

來源:互聯網
上載者:User

標籤:驗證   地方   過程   img   例子   java   運算式   字元   替換   

文法和解析樹:

舉個例子看看,文法解析的過程。句子:“我看到劉德華唱歌”。在電腦裡,怎麼用程式解析它呢。從文法上看,句子的組成是由主語,動詞,和謂語從句組成,主語是“我”,動詞是“看見”, 謂語從句是”劉德華唱歌“。因此一個句子可以分解成 主語 + 動詞 + 謂語從句:

 

句子-->主語+動詞 + 謂語從句 

 

主語是名詞,因此有 :

 

主語->名詞

 

句子裡的名詞有: “我”, “劉德華”,因此有解析規則:

名詞-> "我“  |  "劉德華".

句子裡的動詞是“看見”, “唱歌”,由此有解析規則:

動詞-> “看見” | “唱歌”

 

再看謂語從句,謂語從句由賓語和謂語動片語成, 賓語是 “劉德華”, 謂語動詞是“唱歌", 謂語從句的解析規則就是:

謂語從句 -> 賓語 + 謂語動詞

謂語動詞是屬於動詞,於是又有:

謂語動詞-> 動詞

動詞->”看見” | "唱歌"

 

這樣,整個句子的解析規則就有:

 

1.句子-->主語+動詞 + 謂語從句

2.謂語從句 -> 賓語 + 謂語動詞

3.主語->名詞

4.謂語動詞->動詞

5.動詞-> “看見” | “唱歌”

6.名詞-> "我“  |  "劉德華".

 

上面這組解析規則就是在電腦中用來解析句子的演算法,接下來我們通過一系列替換,從這組規則還原回句子,首先從第一個規則開始,用右邊的式子替換左邊的符號,

1. 句子 通過規則 :句子-->主語+動詞 + 謂語從句 替換得到:

2. 主語+動詞 + 謂語從句, 通過規則 主語->名詞 替換得到:

3. 名詞 + 動詞 + 謂語從句, 通過規則 名詞-> "我“  |  "劉德華" 替換得到

4. 我 + 動詞 + 謂語從句, 通過規則 動詞-> "看見" 替換得到:

5. 我 看見 + 謂語從句, 通過規則 謂語從句 -> 賓語 + 謂語動詞 替換得到:

6. 我 看見 賓語+謂語動詞, 通過規則 賓語->名詞 替換得到:

7. 我 看見 名詞+謂語動詞, 通過規則 名詞-> "我“  |  "劉德華" 替換得到:

8. 我 看見 劉德華 + 謂語動詞, 通過規則 謂語動詞->動詞 替換得到:

9. 我 看見 劉德華 動詞。通過規則 動詞-> “唱歌” 替換得到

10 我 看見 劉德華 唱歌

至此,我們已經沒有可替換的地方,於是文法解析完成。 由此可見,文法解析就是通過設立一組規則,然後判斷輸入的文本是否符合給定規則的過程。我們看到,最底層的一些規則是這樣的:

名詞-> "我“  |  "劉德華", 動詞-> “看見” |“唱歌“

這幾條規則,其實就是以前(http://blog.csdn.net/tyler_download/article/details/50668983)所說的詞法分析,-> 左邊就是標籤,右邊就是詞法分析的字串。整個解析過程,形成了一種樹狀結構,這個結構就叫文法解析樹:


                         

設想,由文字組成的文本,其形式是無窮的,文法解析的規則是將無窮的文本中,選取出組合形式符合文法規則的文本,例如對於上述文法,句子:“我看見張學友唱歌” 就無法通過文法規則,按照上面的替換過程,我們發現,到第7步時 解析到賓語,賓語替換成名詞後無法將名詞替換成“張學友”, 因此“我看見張學友唱歌”對於上面的文法規則而言,是非法輸入。

 

當然,文法規則所限定的文本輸入也不是唯一的,句子:“劉德華看見我唱歌” 也符合上面的文法規則,大家可以仿照上面的替換過程驗證一下。

如果想要文法識別“我看見張學友唱歌”, 那麼只要將規則改一下:名詞->”我“ | ”劉德華” | “張學友” 即可。

 

我們看看,將上述替代過程轉成電腦偽碼是怎樣的:

假定“我看見劉德華唱歌” 這歌句子存在緩衝區buffer 裡,那麼代碼錶述如下:

句子(buffer) {

   //主語 + 動詞 + 謂語從句 替換 句子

    主語(buffer);

    動詞(buffer);

   謂語從句(buffer);

}

主語(buffer) {

//名詞 替換 主語

   名詞(buffer);

}

 

名詞(buffer) {

  // “我” | “劉德華” 替換 名詞

    if (buffer[0] == “我”) {

        buffer = buffer.substring(1);

        return;

  }

 if (buffer[0,1,2] == “劉德華”) {

    buffer = buffer.substring(3);

    return;

 }

 

throw new Exception (“該語句不符合文法”);

}

 

動詞(buffer) {

 // “看見” | “唱歌“ 替換 動詞

  if (buffer[0,1]== “看見” || buffer[0,1] == “唱歌") {

    buffer = buffer.substring(2);

    return; 

  }

 throw new Exception (“該語句不符合文法”);

}

 

謂語從句(buffer) {

//賓語 謂語動詞 替換 謂語從句

    賓語(buffer);

    謂語動詞(buffer);

}

 

賓語(buffer) {

  //名詞 替換 賓語

    名詞(buffer);

}

 

謂語動詞(buffer) {

  //動詞 替換 謂語動詞

    動詞(buffer);

}

 

在下一篇,我們看看,如何對帶有加好和乘號的算術運算式,如何制定一套文法規則以及相應的文法替換代碼。

用java實現一個簡易編譯器-文法解析

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.