2015-06-19 15 views
0

我正在使用JavaCC來制定識別語言的規範。我的問題是JavaCC給我一個警告,因爲public是Member()聲明的通用前綴。 Member()可以具有Attributes()和/或Method(),但必須至少有一個Method,順序無關緊要。避免使用通用前綴而不改變lookahead

警告的JavaCC給我是:

在選擇衝突(...)+構造在第66行,列23 擴展嵌套構建體和膨脹以下構建物內具有共同的前綴,其中之一是: 「上市」。考慮使用一個2或更多的前瞻來進行嵌套擴展。

第66行是Member()的唯一行。此外,我需要這樣做而不需要更改前瞻值

下面是代碼:

void Member() : {} 
    { 
     (Attribute())* (Method())+ (Attribute() | Method())* 
    } 

void Attribute() : {} 
    { 
     "private" Type() <Id> [":=" Expr()]";" 
    } 

void Method() : {} 
    { 
     MethodHead() MethodBody() 
    } 

void MethodHead() : {} 
    { 
     ("public")? (<Id> | Type() | "void") <Id> "(" Parameter() ")" 
    } 

感謝。

回答

0

的問題是,此正則表達式

(Method())+ (Attribute() | Method())* 

是不明確的。讓我們用M來縮寫方法,用A來表示屬性。如果輸入是MAM,那麼沒有問題。 (Method())+匹配第一個M,(Attribute() | Method())*匹配剩餘的AM。但是如果輸入是MMA,那麼分界線應該在哪裏? (Method())+匹配M和(Attribute() | Method())*匹配MA或(Method())+匹配MM和(Attribute() | Method())*匹配A.兩個分析都是可能的。 JavaCC不知道你想要哪個解析,所以它抱怨。

你可以做什麼:

  • 沒有。忽略警告。默認行爲是儘可能多的方法儘可能地將(Method())+只有方法來確認後的第一個屬性將被(Attribute() | Method())*的認可。
  • 使用前視來抑制警告。你說你不想加入前瞻,但爲了完整,我會提到,你可以改變(Method())+(LOOKAHEAD(1) Method())+。這不會改變解析器的行爲,但會抑制警告。
  • 重寫語法。

該問題的行可以被重寫爲

(Attribute())* Method() (Attribute() | Method())* 

或作爲

(Attribute())* (Method())+ [Attribute() (Attribute() | Method())*] 
+0

感謝。它從Method()中移除了'+'。非常感謝。 – apeiron