2014-05-19 2 views
0

ANTLR4를 사용하여 소스 파일을 구문 분석하려고합니다. 한 가지해야 할 일은 문자열 리터럴에는 모든 종류의 문자와 공백이 포함될 수 있지만 일반 식별자에는 영어 문자와 숫자 만 포함됩니다 (공백은 버려집니다).ANTLR 문자열을 구문 분석하고 (공백 유지) 일반 식별자를 구문 분석합니다.

다음 antlr 문법 규칙 (최소 예)을 사용하지만 예상대로 작동하지 않습니다. 내가 사용하는 테스트 케이스를 들어

grammar parseString; 

rules 
    : stringRule+ 
    ; 

stringRule 
    : formatString 
    | idString 
; 

formatString 
    : STRING_DOUBLEQUOTE STRING STRING_DOUBLEQUOTE 
    ; 

idString 
    : (NONTERM | TERM) 
    ; 

// LEXER 

STRING_DOUBLEQUOTE 
    : '"' ; 

DIGITS 
    : DIGIT+ 
    ; 

TERM 
    : UPPERCHAR CHAR+ 
    ; 

NONTERM 
    : LOWERCHAR CHAR+ 
    ; 

fragment 
CHAR 
    : LOWERCHAR 
    | UPPERCHAR 
    | DIGIT 
    | '-' 
    | '_' 
    ; 

fragment 
DIGIT 
    : [0-9] 
    ; 

fragment 
LOWERCHAR 
    : [a-z] 
    ; 

fragment 
UPPERCHAR 
    : [A-Z] 
    ; 

WS 
    : (' ' | '\t' | '\r' | '\n')+ -> skip 
    ; // skip spaces, tabs, newlines 

LINE_COMMENT 
    : '//' ~[\r\n]* -> skip 
    ; 

STRING 
    : ~('"')* 
    ; 

,

Test 
HelloWorld 
"$this is a string" 
"*this is another string!" 

나는 오류 line 1:0 extraneous input 'Test\nHelloWorld\n' expecting {'"', TERM, NONTERM}을 얻었다. 그리고 'formatString'의 마지막 두 줄을 올바르게 파싱합니다. 그러나 처음 두 줄에서는 개행 문자 ('\ n')가 버려진 것이 아니므로 'idString'과 일치하지 않습니다. 내가 뭘 잘못했는지 궁금해.

답변

0

귀하의 STRING 규칙은 따옴표 외에는 일치하지 않으므로 스카프가 적용됩니다. 그것은 너무 느슨한 방법입니다. 내가 생각하는 다른 것들과 STRING을 구별하는 것의 정확한 정의가 필요하다. 일단 그것이 ~ '' '*' ''까지 스카프 것입니다.

0

예이 문법에는 문제가 있습니다. 토큰 STRING은 'Test \ nHelloWorld \ n'과 일치합니다. 이 토큰에는 모든 것을 넣을 수 있지만 TOKEN STRING 만 사용하는 규칙은 없습니다.

토큰 STRING 변경에 대해 생각하십시오.

관련 문제