2014-06-13 1 views
1

친애하는 Antlr4 커뮤니티,XSD Regex의 문법을 ANTLR4로 구문 분석하는 방법은 무엇입니까?

최근 정규 표현식을 XSD/xml에서 cvc4로 변환하기 위해 ANTLR4를 사용하기 시작했습니다. w3c에 지정된 문법을 사용합니다 (http://www.w3.org/TR/xmlschema11-2/#regexs 참조). 에 (charClass을 제거하여)이 문법을 단순화 나는이 질문에 대한 :

input 12{3,4} 
:

input a(bd){6,7}c{14,15} 

는 그러나, 나는에 대한 오류 메시지가 :

grammar XSDRegExp; 

regExp   :  branch ('|' branch)* ; 
branch   :  piece* ; 
piece    :  atom quantifier? ; 
quantifier  :  Quantifiers | '{'quantity'}' ; 
quantity   :  quantRange | quantMin | QuantExact ; 
quantRange  :  QuantExact ',' QuantExact ; 
quantMin   :  QuantExact ',' ; 
atom    :  NormalChar | '(' regExp ')' ;  // excluded | charClass ; 

QuantExact  :  [0-9]+ ; 
NormalChar  :  ~[.\\?*+{}()|\[\]] ;   
Quantifiers  :  [?*+] ;  

구문 분석 잘 갈 것 같다

오류 :

라인 1 : 0 일치하지 않는 입력 '12'기대 {, '(', '|', NormalChar} 파서는 이후

내가 렉서는 첫 번째 심볼로 QuantExact를 볼 수 있다는 것을 이해하지만, NormalChar 찾고이 오류를 기대하지 않았다.

[1]과 QuantExact NormalChar 정의를 스와핑

저는 많은 변화를 시도했다. 그러나 스와핑 첫 번째 입력에 에러를 도입

line 1:6 no viable alternative at input '6' 

그런 경우 이후 '6'만 QuantExact 같은 NormalChar 같이 NOT 보인다.

[2] 렉서가이 제한된 컨텍스트에서 QuantExact 기호만을 제공하도록 QuantExact (수량의 중괄호)에 대한 컨텍스트를 만들어보십시오. 그러나 이것에 대한 ANTLR4 프리미티브를 찾지 못했습니다.

아무 것도 작동하지 않는 것 같습니다. 따라서 내 질문은 다음과 같습니다. 이 문법을 ANTLR4로 구문 분석 할 수 있습니까? 그렇다면 어떻게?

+0

당신을 얼마나 자신이 그 'NormalChar의 정의에 .'는 내가 ANTLR 사용자 아니에요, 그리고 (이스케이프 할 필요가 없다 [문서] (https : //로 theantlrguy.atlassian.net/wiki/display/ANTLR4/Lexer+Rules) 약간 희미한가요?) 문자열 '12'는 표시된대로 문법을 구문 분석합니까? (오류 메시지에서 '아니오'라고 추측합니다.) 문자열 'abc'가 구문 분석합니까? –

+0

@ C.M.Sperberg-McQueen, ANTLR4의 문자 집합 (문자 클래스)은 예상대로 동작합니다. \ 및] 만 이스케이프해야하고 다른 메타 문자는 필요하지 않습니다. –

+0

"예상대로"? 내 기대는 그 것이다. 탈출해야합니다. 당연히 다른 기대치가있을 수 있지만, 2 ~ 3 개 이상의 정규 표현식 도구를 사용하는 사람은 기대가 문서화만큼 유용하지 않다는 것을 알게됩니다. –

답변

0

은 내가 렉서는 첫 번째 심볼로 QuantExact를 볼 수 있다는 것을 이해하지만, 파서 만 NormalChar을 찾고 있기 때문에이 오류를 기대하지 않았다.

렉서는 파서에 "듣지"하지 않습니다 상관없이 파서가 NormalChar 일치하려고하는 경우, 문자 12 항상 QuantExact으로 일치됩니다. 렉서는 가능한 한 많은 문자를 매치하려고하며, 동점 일 경우 먼저 정의 된 규칙을 선택합니다.

당신은 일치하는 normalChar 규칙을 소개 할 수 모두 NormalCharQuantExact과에서 해당 규칙을 사용하여 atom :

atom    :  normalChar | '(' regExp ')' ; 
normalChar  :  NormalChar | QuantExact ; 

또 다른 옵션은 렉서는 단일 문자 토큰을 만들 수 있도록하고 파서하게하는 것 이들을 함께 붙이십시오 (많이 PEG처럼).이런 식으로 뭔가 :

regExp   :  branch ('|' branch)* ; 
branch   :  piece* ; 
piece    :  atom quantifier? ; 
quantifier  :  Quantifiers | '{'quantity'}' ; 
quantity   :  quantRange | quantMin | quantExact ; 
quantRange  :  quantExact ',' quantExact ; 
quantMin   :  quantExact ',' ; 
atom    :  normalChar | '(' regExp ')' ; 
normalChar  :  NormalChar | Digit ; 
quantExact  :  Digit+ ; 

Digit    :  [0-9] ; 
NormalChar  :  ~[.\\?*+{}()|\[\]] ; 
Quantifiers  :  [?*+] ; 
+0

후자의 솔루션에 감사드립니다! 참고 : 12+는 1 (2+)이고 (12) +가 아니기 때문에 첫 번째 값은 올바르지 않습니다. –

+0

@ 피에르 환영합니다. –

관련 문제