2014-09-11 2 views
2

거꾸로 구문 분석하려는 ANTLR4 규칙의 일부가 있습니다. 그게 진짜 해결책이 아니라고 생각합니다. 그래서 내가 놓친 것 같습니다.ANTLR4 파서의 하위 규칙과 일치합니다.

내 문제의 핵심은 내 표현의 중간 부분에 내가 추출하고 싶은 부분이 있다는 것입니다. 그러나이 부분에는 가능한 경우 별개로 추출하려는 일부 (정의 된) 접미사가 있습니다. 이 접미어는 쉼표로 구분하거나 구분할 수 없습니다. 문법은 쉼표로 잘 작동하지만 쉼표가없는 경우 접미사가있는 경우에도 전체 부분은 unknown으로 표시됩니다.

나는이 게시물의 하단에 표시되는 작은 예제로 내 문법을 정리했습니다.

문자열이 why hello, x y z foo bar baz blah blah blah, goodbye! 인 경우 내 문법은 x y z foo bar bazphrase으로 구문 분석합니다. 접미사로 x y zunknownfoo bar baz과 일치시키고 싶습니다. 쉼표 (x y z, foo bar baz)가 있다면, 그것은 작동합니다 tree generated with comma

을 그러나, 쉼표가없는 경우, 그것은 전체 x y z foo bar baz (물론 이후 텍스트의 일부 등) unknown로 취 tree generated with no comma

을 FO 할 수있는 방법이 있나요 tree generated with no comma and nongreedy unknown

: 나는 (+?를) nongreedy로 unknown을 변경 시도,하지만 phrase에 대해 하나의 토큰을 소모뿐만 아니라 바람직하지 않다 phrase 규칙을 수정하여 오른쪽에서 첫 번째로 일치하는 접미사를 시도한 후 unknown으로 떨어지십니까?

또 다른 방법을 넣어 : 그것은 하나 이상의 접미사 종료 될 때 제외 unknown 일치 아무것도 을하는 방법이 있나요? 의 구문 분석을

Another way to put it: is there a way to have unknown match anything except when it ends with one or more suffixes? (The suffixes can appear in the text as long as they're not at the end)

그러나 이전 :

grammar Example; 

// parse tree root 
exampleExpression : ignored HELLO separator phrase separator? unknown separator? GOODBYE ignored; 

// what I want to match 
phrase : unknown (COMMA? suffix+)*; 

// convenience rule for swaths of tokens to be ignored (e.g. at the beginning and end) 
ignored : (unknown | separator)*; 

// roll up unknown tokens under one rule 
unknown : (~(PERIOD | COMMA | PIPE | BULLET | SP_SEP_DASH))+; 
separator : PERIOD | COMMA | PIPE | BULLET | SP_SEP_DASH; 

// the pre-defined suffixes 
suffix : FOO | BAR | BAZ; 

/* TOKENS */ 

HELLO : 'hello'; 
GOODBYE : 'goodbye'; 
FOO : 'foo'; 
BAR : 'bar'; 
BAZ : 'baz'; 

/* FRAGMENTS */ 

fragment DIGIT : [0-9]; 
fragment DASH : '-'; 

/* REMAINING TOKENS */ 

LPAREN : '(' ; 
RPAREN : ')' ; 
COMMA : ','; 
PERIOD : '.'; 
PIPE : '|'; 
BULLET : '\u00B7' | '\u2219' | '\u22c5'; 
SP_SEP_DASH : SP DASH SP; 

SP : [ \u000B\t\r\n] -> channel(HIDDEN); 

NUMBER : ([0] | [1-9] DIGIT*) ('.' DIGIT+)?; 
WORD : [A-Za-z] [A-Za-z-]*; 

// catch-all 
OTHER : .; 
+0

Wild guess : 'phrase : unknown COMMA? (접미사 +) *;'대신'phrase : unknown (COMMA? suffix +) *;'를 사용합니다. –

+0

@ 500-InternalServerError : 분명히'(suffix +) *'는'suffix * '와 동일하지만 실제로는 괄호 안에있는 COMMA가있는 접미사 +가 필요합니다. IOW : '콤마? (접미사 + COMMA) * 접미사 +'. 그러나 그것이 그것이 근본적인 문제라고 생각하지 않습니다. – rici

+0

필자의 주장에 따르면'phrase '는'COMMA'도 존재할 경우에만'suffix'를 받아들이는 것처럼 보입니다. –

답변

1

문제는 말한다 :

예 문법 (접미사는 그들이 말 아니에요으로 텍스트에 나타날 수 있습니다) 내부 접미사 unknown이 거부되었습니다 : 일치하지 않는 것 같다

However, if there is no comma, it takes the entire x y z foo bar baz (as well as some of the text after) as unknown

합니다.

예에서 자연어 구문 분석을 시도하는 것처럼 보입니다. ANTLR은 그 미덕이 무엇이든간에 아마 ANTLR을위한 좋은 도구는 아닙니다. 하지만 그것은 단순화에 기초한 키메라 일 수 있습니다.

원래 질문에 대한 답변 - "접미어 클래스에서 하나 이상의 토큰으로 끝나지 않는 토큰 시퀀스로 비 터미널을 정의 할 수 있습니까?"예, 문맥 자유 문법으로 쓰여질 수 있습니다. " ANTLR 사양에 익숙하지 않으면 여기에 간단한 CFG가 있습니다.

wordlist: /* empty */ | wordlist non_suffix | wordlist suffix_list non_suffix ; 
suffix_list: suffix | suffix_list suffix ; 
+0

"그러나 쉼표가 없다면, xy z foo bar baz 전체를 알 수없는 텍스트로 받아들입니다."나는 그런 일이 일어난다는 것을 의미합니다. 그런 경우, 나는'알려지지 않은'접미사''알려지지 않은''을 예상했을 것이다. 그러나 그것이 어떻게 든 후방으로 해석되지 않는다면 (또는 그것이 내 사고였습니다.) 알아 내기가 어려울 수도 있습니다. 제안 된 CFG를 주셔서 감사합니다. 나는 이것을 출발점으로 삼지 않을 것이다. – NickAldwin

+0

@NickAldwin : 이해했습니다. 그러나 귀하의 요구 사항에서, 미지수는 끝 부분에 없으면 접미사를 포함 할 수 있다고 말하면됩니다 (내 인용 부호에 강조 표시되어 있음). 그런 다음 문법이 끝이 아닌 접미사로 알 수 없음을 접수하고 있다고 불평합니다. 그것은 불일치입니다. 접미어가 어디에서 발생하는지에 관계없이 접미사로 구문 분석되기를 원하면 문법은 사소합니다. 당신이 다른 기대를 가지고 있다면, 당신은 그들에 대해 더 정확하게해야합니다. – rici

+0

알 수 있듯이, 파서가 '알려지지 않은'접미사와 '알 수없는 접미사'를 알 수있는 방법은 없습니다. – NickAldwin