나는 Antlr 문법에 관한 질문의 양으로 다소 편안함을 느낀 반면 (단지이 야크 모양의 물건을 면도하려고하는 것이 아닙니다), 도움이되는 질문/답변을 찾지 못했습니다. 내 문제.간단한 Antlr3 토큰 파싱
Antlr3.3을 혼합 토큰/파서 렉서와 함께 사용하고 있습니다.
gUnit을 사용하여 문법 및 일부 jUnit 테스트를 증명합니다. 이것은 재미가 시작되는 곳입니다. 나는 문제가 "식별자"를 파싱 (이 예제는 foobar) 데
identifier foobar {
port=8080
stub plusone.google.com {
status-code = 206
header = []
body = []
}
}
: 나는 간단한 설정 파일이
내가 구문 분석 할 내가 허용 할 유효한 이름은 다음과 같습니다
foobar
foo-bar
foo_bar
foobar2
foo-bar2
foo_bar2
3foobar
_foo-bar3
등, 따라서 유효한 이름이 문자를 'a..z'|'A..Z', '0..9' '_' and '-'
난에 도착했습니다 문법을 사용할 수 있습니다이 (이 전체 g 밤은주의입니다 이 질문에 관련 rammar 단지 부)
fragment HYPHEN : '-' ;
fragment UNDERSCORE : '_' ;
fragment DIGIT : '0'..'9' ;
fragment LETTER : 'a'..'z' |'A'..'Z' ;
fragment NUMBER : DIGIT+ ;
fragment WORD : LETTER+ ;
IDENTIFIER : DIGIT | LETTER (LETTER | DIGIT | HYPHEN | UNDERSCORE)*;
및 gUnit 테스트를 실행하는 해당 시험 gUnit
IDENTIFIER:
"foobar" OK
"foo_bar" OK
"foo-bar" OK
"foobar1" OK
"foobar12" OK
"foo-bar2" OK
"foo_bar2" OK
"foo-bar-2" OK
"foo-bar_2" OK
"5foobar" OK
"f_2-a" OK
"aA0_" OK
// no "funny chars"
"foo[email protected]" FAIL
// not with whitepsace
"foo bar" FAIL
은 "5foobar"실패. 나는 어려운 것들을 파싱 할 수 있었지만, 식별자를 파싱하는 겉으로는 간단한 작업이 나를 때렸다.
누군가 내가 잘못 가고있는 부분을 지적 할 수 있습니까? 탐욕스럽지 않고 나는 어떻게 맞습니까?
미리 감사드립니다.
- UPDATE - 나는 바트의 대답에 따라,이에 대한 문법 변화
:
IDENTIFIER : ('0'..'9'| 'a'..'z'|'A'..'Z' | '_'|'-') ('_'|'-'|'a'..'z'|'A'..'Z'|'0'..'9')* ;
을하고 이것이 실패 gUnit 테스트를 고정하지만, unreleated JUnit 테스트를 파산, 그 "port"매개 변수를 테스트합니다. 위의 설정 스 니펫 (snippet)의 다음은과 문법 거래를 다음 "포트 = 8080"요소 :
configurationStatement[MiddlemanConfiguration config]
: PORT EQ port=NUMBER {
config.setConfigurationPort(Integer.parseInt(port.getText())); }
| def=proxyDefinition { config.add(def); }
;
내가 얻는 메시지는 다음과 같습니다 번호가 NUMBER : ('0'..'9')+ ;
mismatched input '8080' expecting NUMBER
IDENTIFIER 블록 위에 NUMBER에 대한 규칙을 이동하면이 문제가 해결되었습니다.
IDENTIFIER
: DIGIT
| LETTER (LETTER | DIGIT | HYPHEN | UNDERSCORE)*
;
그래서 IDENTIFIER
단일 DIGIT
eiter거나 (LETTER | DIGIT | HYPHEN | UNDERSCORE)*
뒤에 LETTER
로 시작
그는'_foo-bar3'이 유효한 식별자이므로 밑줄을 허용 가능한 첫 번째 문자로 추가해야한다고 지시했습니다. 또한 ANTLR 4는 규칙을 조각으로 분리하는 성능상의 문제가 없지만 ANTLR 3은 단순히 "HYPHEN", "0"... "9"대신에 "-"를 사용하면 훨씬 효율적으로 작동합니다 'DIGIT' 등 –
@ 280Z28, 네, 맞아요. OP가 언급 한 gUnit 테스트 사례를 살펴 보았습니다. 'IDENTIFIER' 규칙의 시작 부분에'UNDERSCORE'를 추가했습니다. –
안녕하세요 @Bart @ 280Z28, 문법을 다음과 같이 변경했습니다 : 'IDENTIFIER : ('0 '..'9 '|'a '..'z '|'A '..'Z '|'_ ' '' '' '' '' '' '' '' '' '' '' '0'.. '9') *; ' ' '(' '' '' , 그러나 그것의 "포트 = 8080"깨진, 그 테스트는 지금 실패합니다. 나는 그 질문을 편집 할 것이다. – user1512122