2012-09-10 59 views
1

我知道這已經被討論了幾千次,但我仍然無法弄清楚爲什麼遵循語法失敗。在解釋器中一切正常,沒有任何錯誤或警告。但是,當運行生成的代碼時,我會得到不匹配的輸入,如下所示。Antlr 3.4.0生成解析器和解釋器中不匹配的輸入

對於這個語法:

grammar xxx; 

options { 
    language = Java; 
    output = AST; 
} 

@members { 
    @Override 
    public String getErrorMessage(RecognitionException e, 
    String[] tokenNames) 
    { 
     List stack = getRuleInvocationStack(e, this.getClass().getName()); 
     String msg = null; 
     if (e instanceof NoViableAltException) { 
      NoViableAltException nvae = (NoViableAltException)e; 
      msg = " no viable alt; token="+e.token+ 
      " (decision="+nvae.decisionNumber+ 
      " state "+nvae.stateNumber+")"+ 
      " decision=<<"+nvae.grammarDecisionDescription+">>"; 
     } 
     else { 
      msg = super.getErrorMessage(e, tokenNames); 
     } 
     return stack+" "+msg; 
    } 

    @Override 
    public String getTokenErrorDisplay(Token t) { 
     return t.toString(); 
    } 
} 

obj 
     : first=subscription 
     (COMMA other=subscription)* 
     ; 

subscription 
     : ID 
     (EQUALS arguments_in_brackets)? 
     filters 
     ; 

arguments_in_brackets 
     : LOPAREN arguments ROPAREN 
     ; 

arguments 
     : (arguments_body) 
     ; 

arguments_body 
     : argument (arguments_more)? 
     ; 

arguments_more 
     : SEMICOLON arguments_body 
     ; 

argument 
    : id_equals argument_body 
    ; 

argument_body 
    : STRING 
    | INT 
    | FLOAT 
    ; 

filters 
     : LSPAREN expression RSPAREN 
     ; 

expression 
     : or 
     ; 

or 
    : first=and 
    (OR^ second=and)* 
    ; 

and  : first=atom 
    (AND^ second=atom)* 
    ; 

atom 
    : filter 
    | atom_expression 
    ; 

atom_expression 
    : LCPAREN 
    expression 
    RCPAREN 
    ; 

filter 
    : id_equals arguments_in_brackets 
    ; 

id_equals 
    : WS* ID WS* EQUALS WS* 
    ; 

COMMA: WS* ',' WS*; 
LCPAREN : WS* '(' WS*; 
RCPAREN : WS* ')' WS*; 
LSPAREN : WS* '[' WS*; 
RSPAREN : WS* ']' WS*; 
LOPAREN : WS* '{' WS*; 
ROPAREN : WS* '}' WS*; 
AND: WS* 'AND' WS*; 
OR: WS* 'OR' WS*; 
NOT: WS* 'NOT' WS*; 
EQUALS: WS* '=' WS*; 
SEMICOLON: WS* ';' WS*; 

ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')* 
    ; 

INT : '0'..'9'+ 
    ; 

FLOAT 
    : ('0'..'9')+ '.' ('0'..'9')* EXPONENT? 
    | '.' ('0'..'9')+ EXPONENT? 
    | ('0'..'9')+ EXPONENT 
    ; 

// : '"' (ESC_SEQ | ~('\\'|'"'))* '"' 
// : '"' (~'"')* '"' 
STRING 
    : '"' (~'"')* '"' 
    ; 

fragment 
EXPONENT : ('e'|'E') ('+'|'-')? ('0'..'9')+ ; 

fragment 
HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ; 

fragment 
ESC_SEQ 
    : '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\') 
    | UNICODE_ESC 
    | OCTAL_ESC 
    ; 

fragment 
OCTAL_ESC 
    : '\\' ('0'..'3') ('0'..'7') ('0'..'7') 
    | '\\' ('0'..'7') ('0'..'7') 
    | '\\' ('0'..'7') 
    ; 

fragment 
UNICODE_ESC 
    : '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT 
    ; 

NEWLINE: '\r'? '\n' {skip();} ; 

WS:  (' '|'\t')+ {skip();} ; 

而且此輸入:

status={name="Waiting";val=5}[ownerEmail1={email="[email protected]"} OR internalStatus={status="New"}],comments={type="fds"}[(internalStatus={status="Owned"} AND ownerEmail2={email="[email protected]"}) OR (role={type="Contributor"} AND status={status="Closed"})] 

我越來越:

line 1:67 [obj, subscription, filters, expression, or, and, atom, filter, arguments_in_brackets] mismatched input [@18,67:80='internalStatus',<11>,1:67] expecting ROPAREN 
line 1:157 [obj, subscription, filters, expression, or, and, atom, atom_expression, expression, or, and, atom, filter, arguments_in_brackets] mismatched input [@42,157:167='ownerEmail2',<11>,1:157] expecting ROPAREN 

能有人給我任何線索這是爲什麼失敗,請?我試圖用很多方式重寫它,但錯誤仍然是一樣的。

回答

1

問題是,您在其他詞法分析器規則中使用WS標記,因此會跳過這些標記。這會導致詞法分析器完全丟棄這些標記,因此不能用於解析器規則。

所以,如果你有這樣一個規則:

WS : ' ' {skip();}; 

,然後在NOT使用這樣的規則:

NOT : WS* 'NOT' WS*; 

它會導致NOT令牌一併跳過。

如果您已經跳過這些WS字符,你不需要它們包括在其他詞法規則:只要刪除所有WS*其他規則:

... 
NOT : 'NOT'; 
... 

(也來自解析器中刪除規則:無論如何,詞法分析器規則中的所有skip單詞令牌都不可用!)

+0

你完全正確,非常感謝Bart。 – user1394066

+0

@ user1394066,不客氣。忘了提及這一點:從不過分依賴解釋器:它忽略了幾乎所有的嵌入代碼(這就是爲什麼'skip()'在大多數情況下不會在解釋器中調用,而且它似乎工作!)。 –

+0

對,這解釋瞭解釋和生成代碼中的不同結果,再次非常感謝。 – user1394066