2014-03-12 26 views
2

我有Grammar_A語法,我想分成兩種語法:Grammar_A1Grammar_A2; Grammar_A2進口Grammar_A1(我已包括在問題的最後)。用@init stub導入語法的問題

當我嘗試編譯我的項目時,儘管存在三個'@init'操作,但我在Grammar_A2中獲得了錯誤redefinition of 'init' action兩次。

如果我評論三個@init行爲中的兩個,無論如何,編譯都很好。

我將語法翻譯爲Java,並像Antlr4網站中的教程一樣進行編譯:我獲得了與java -classpath .;../antlr-4.2-complete.jar org.antlr.v4.Tool Grammar_A2.g4相同的錯誤,但是指出錯誤94,ACTION_REDEFINITION

我試着用antlr 4.1和4.2版進行編譯。

任何想法,我可以做什麼錯了?

Grammar_A

grammar Grammar_A; 

@parser::members 
{ 
    protected const int EOF = Eof; 
    int numPrints, numReads; 
} 

@lexer::members 
{ 
    protected const int EOF = Eof; 
    protected const int HIDDEN = Hidden; 
} 

program 
@init { numPrints = numReads = 0; } 
    : (printExpression | readExpression)+ 
    ; 

printExpression 
@init {numPrints++;} 
    : PRINT_KEY 
     (id 
      | QUOT id QUOT 
     ) 
     SEMICOLON 
; 

readExpression 
@init {numReads++;} 
    : ID READ_KEY SEMICOLON 
; 

id 
    : ID | PRINT_KEY | READ_KEY 
    ; 

WS 
    : (' ' | '\r' | '\n') -> channel(HIDDEN) 
    ; 

PRINT_KEY : 'print'; 
READ_KEY : 'read'; 

ID : ('a'..'z')+ ; 


SEMICOLON : ';'; 
QUOT : '"'; 

Grammar_A1

grammar Grammar_A1; 

@parser::members 
{ 
    protected const int EOF = Eof; 
} 

@lexer::members 
{ 
    protected const int EOF = Eof; 
    protected const int HIDDEN = Hidden; 
} 

id 
    : ID | PRINT_KEY | READ_KEY 
    ;  

WS 
    : (' ' | '\r' | '\n') -> channel(HIDDEN) 
    ; 

PRINT_KEY : 'print'; 
READ_KEY : 'read'; 

ID : ('a'..'z')+ ; 

Grammar_A2

grammar Grammar_A2; 

import Grammar_A1; 


@parser::members { 
    int numPrints, numReads; 
} 

program 
@init { numPrints = numReads = 0; } 
    : (printExpression | readExpression)+ 
    ; 

printExpression 
@init {numPrints++;} 
    : PRINT_KEY 
     (id 
      | QUOT id QUOT 
     ) 
     SEMICOLON 
; 

readExpression 
@init {numReads++;} 
    : ID READ_KEY SEMICOLON 
; 


SEMICOLON : ';'; 
QUOT : '"'; 
+0

我看到在我的語法包含init和行動後,多條規則類似的問題。這沒有被提及爲禁止..但它似乎有一個問題。我試圖弄清楚,希望能夠構建一個測試用例。 –

回答

1
  1. 如果你可以在Java代碼中重現這個問題(它AP梨可以),您可以將其報告爲reference implementation's issue tracker上的錯誤。否則,如果這是針對C#目標的,則可以在C# target's issue tracker上報告。

  2. 如果你有一個語法,我強烈建議你有沒有考慮過被拆分爲一個lexer grammarparser grammar唯一的分離,而不是使用import聲明。實際上有助於說明的情況很少,而且很遙遠。

  3. 您在問題中指出的操作對於正確的解析並不重要,因此應該重新定位到解析完成後執行的偵聽器或訪問者。通過將這些操作置於正確的位置,您將不再受到您描述的問題的限制。

0

我有同樣的問題,它可能是ANTLR中的錯誤?

要變通解決此問題,我將所有內嵌塊@init@after重新分配。 像這樣(未測試):

grammar Grammar_A2; 

import Grammar_A1; 


@parser::members { 
    int numPrints, numReads; 
} 

program 
    : { numPrints = numReads = 0; } // previously @init 
     (printExpression | readExpression)+ 
     { int numWhat = (numPrints + numReads); 
      System.out.println(numWhat); } // @after block 
    ; 

printExpression 
    : {numPrints++;} // previously @init 
     PRINT_KEY 
     (id 
      | QUOT id QUOT 
     ) 
     SEMICOLON 
    ; 

readExpression 
    : {numReads++;} // previously @init 
     ID READ_KEY SEMICOLON 
    ; 


SEMICOLON : ';'; 
QUOT : '"'; 

編輯: 我這裏開一個問題 https://github.com/antlr/antlr4/issues/2041