2014-12-23 30 views
1

我有一個巨大的ANTLR語法,而且我正面臨一小塊問題。語法有兩個規則EXPR和套下文所定義:ANTLR中的優先模糊4

expr: 
    id 
    |(PLUS|MINUS|MULTIPLY|AND|NEGATION)expr 
    | expr (MULTIPLY |DIVIDE| MODULO) 
    | expr (PLUS | MINUS) expr 
; 

set: 
    EMPTY 
    | MULTIPLY set 
    | set PLUS set 
    | UNION '(' set (COMMA set)* ')' 
    | INTER '(' set (COMMA set)* ')' 
    | expr 
    ; 

這裏的問題是,對於一組形式的* S1 + * S2應減少如下:

set -> set PLUS set 

,然後每一組在RHS應減少到:

set -> MULTIPLY set 
set -> expr 
term -> id 

但是,相反,他們正在減少爲:

set -> MULTIPLY set 
set -> expr 
expr -> expr PLUS expr 

由於forn *s1 +*s2的哪一組被解析爲*(s1 + *s2)而不是(*s1) + (*s2)

設置的規則之一,將其降至expr。在語法中還有很多其他類似的規則可以簡化爲expr。問題在這裏發生,因爲set和expr中的一些規則是相似的。但是由於一些規則不同,我無法將它們合併在一起。

即使規則MULTIPLY set的優先級高於set PLUS set,設置也會減少MUTIPLY set規則。

有沒有辦法解決這個問題?

編輯:

添加一個工作示例:

語法:

grammar T; 

expr 
: ID 
    | (PLUS | MINUS | MULTIPLY | AND | NEGATION) expr 
    | expr (MULTIPLY | DIVIDE | MODULO) 
    | expr (PLUS | MINUS) expr 
; 

set: 
    EMPTY 
    | MULTIPLY set 
    | set PLUS set 
    | UNION '(' set (COMMA set)* ')' 
    | INTER '(' set (COMMA set)* ')' 
    | expr 
    ; 
ID : [a-zA-Z] [a-zA-Z0-9]*; 
PLUS : '+'; 
MINUS : '-'; 
MULTIPLY : '*'; 
AND : '&&'; 
NEGATION : '!'; 
DIVIDE : '/'; 
MODULO : '%'; 
COMMA : ','; 
EMPTY: '\\empty'; 
UNION: '\\union'; 
INTER: '\\inter'; 
SPACES : [ \t\r\n] -> skip; 

代碼以執行它:它產生

TLexer lexer = new TLexer(new ANTLRInputStream("*s1 + *s2")); 
TParser parser = new TParser(new CommonTokenStream(lexer)); 
RuleContext tree = parser.set(); 
tree.inspect(parser); 

輸出:

set 
/\ 
* set 
    | 
    expr 
    /| \ 
/| \ 
expr + expr 
    |  /\ 
    s1  * expr 
      | 
      s2 
+0

你能否提供一個[SSCCE](http://sscce.org/)這個,因爲我無法複製它? (請參閱我的回答) –

+0

@BartKiers,我添加了一個工作示例。對不起,以前沒有提供這個例子。 – user2888308

回答

0

我無法複製此內容。

鑑於語法:

grammar T; 

expr 
: ID 
| (PLUS | MINUS | MULTIPLY | AND | NEGATION) expr 
| expr (MULTIPLY | DIVIDE | MODULO) 
| expr (PLUS | MINUS) expr 
; 

ID : [a-zA-Z] [a-zA-Z0-9]*; 
PLUS : '+'; 
MINUS : '-'; 
MULTIPLY : '*'; 
AND : '&&'; 
NEGATION : '!'; 
DIVIDE : '/'; 
MODULO : '%'; 
SPACES : [ \t\r\n] -> skip; 

您輸入*s1 + *s2會被解析爲:

 expr 
    /| \ 
/| \ 
expr + expr 
/\ /\ 
* expr * expr 
    |  | 
    s1  s2 

或者在明碼:

TLexer lexer = new TLexer(new ANTLRInputStream("*s1 + *s2")); 
TParser parser = new TParser(new CommonTokenStream(lexer)); 
System.out.println(parser.expr().toStringTree(parser)); 

會打印:

(expr (expr * (expr s1)) + (expr * (expr s2))) 
+0

我正在面對的問題是當輸入* s1 + * s2以「set」作爲起點解析時發生。由於expr在語法中的許多其他規則中使用,我無法將set合併到expr中。 – user2888308