2015-10-21 127 views
4

我在學習如何使用JavaCC編寫解析器。如何在JavaCC分析器中使用JFlex詞法分析器?

我已經使用JFlex生成了一個詞法分析器,並返回一個令牌列表。每個令牌都是它自己的類。

我正在編寫生產規則,但是例如,我不能寫「;」因爲它不會接收分號,而是TokenSemicolon的一個實例呢?

我該怎麼辦?

另外,我對TokenMangager等感到困惑。我已經有了一個詞法分析器和我自己的兼容令牌類的列表。這是什麼?

請幫忙,因爲我很困惑。

回答

2

你問了兩個相關的問題: 「這是什麼」

由此我假定你的意思是:「什麼是令牌管理器?」

令牌管理器是令牌對象的來源。每個JavaCC解析器都需要一個令牌源。順便說一下,令牌由類Token的對象表示。有兩種方法可以製作令牌管理器。

  1. 讓JavaCC爲您生成一個。 JavaCC根據您放入.jj文件中的一組規則生成一個詞法分析器。這樣就很像JFlex。這是默認設置。
  2. 寫你自己的。要做到這一點設置選項USER_TOKEN_MANAGER=true。然後JavaCC將生成一個名爲TokenManager的Java接口。你所需要做的就是用你自己的類來實現這個接口。當然,您應該使用該類的對象構造解析器。

「我能做什麼?」

有幾種可能性。

  1. 在JavaCC中重寫您的JFlex代碼。然後JavaCC中生成的令牌經理將主要做同樣的事情,你的JFlex的詞法分析器,但它會實現正確的接口,它會產生相應類型的標記(即Token
  2. 寫一個適配器類。使用JavaCC的USER_TOKEN_MANAGER=true選項並編寫一個適配器類,它包裝您的JFlex並實現TokenManager接口。
  3. 說服JFlex生成可用於JavaCC的詞法分析器。我不確定這是否可能,但如果是這樣,它可能是最好的選擇。在這種情況下,你會使用USER_TOKEN_MANAGER=true。然後,讓一類: class FooLexer extends FooJLexLexer implements TokenManager { ...put constructors here... }

選項3你必須確保生成的詞法分析器真正實現所有TokenManager所需的方法。如果你真的需要所有的令牌類,你可以讓它們擴展生成的Token類。

如果您使用選項2去,你的代碼來構建解析器可能會看起來有點像這樣

TokenManager tm = new AdaptJFlexLexerToJavaCC(jflexLexer) ; 
FooParser p = new FooParser(tm) ; 

選項3是很有誘惑力的嘗試。它可能是最簡單的,如果它解決。

如果方案3不能解決問題,並且除非有令人信服的理由保留JFlex詞法分析器,否則我會選擇1.從JFlex到JavaCC的翻譯很可能很大程度上是機械的,因此很容易。 JCC中唯一一個JavaCC沒有很好的解決方案的是A/B結構。

無論您選擇哪個選項,請記住,JavaCC預計每個Token都有一個.kind字段。這是一個整數,但是您會在生成的接口FooConstants中找到整數的符號名稱。