2012-09-10 1 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*; 

IT는 NOT 토큰뿐만 아니라 생략됩니다. 이미이 WS 문자를 건너 뛰는 경우

, 당신은 다른 렉서 규칙에 포함 할 필요가 없습니다 : 단순히 다른 규칙의 모든 WS*을 제거 :

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

(또한 파서에서 제거 규칙 : 모든 skip 렉서의 토큰은 파서 규칙에서 결코 사용할 수 없습니다!)

+0

당신은 완전히 바트에 감사합니다. – user1394066

+0

@ user1394066, 안녕하세요. 이것을 잊어 버리십시오. 인터프리터에 너무 많이 의존하지 마십시오. 거의 모든 임베디드 코드를 무시합니다 (인터프리터에서 대부분의 경우'skip()이 호출되지 않아 작동하는 것처럼 보입니다!). –

+0

맞아요, 해석과 생성 된 코드의 다른 결과를 설명합니다. 다시 한번 감사드립니다. – user1394066

관련 문제