2016-12-12 7 views
0

다음과 같은 문법이 있습니다.antlr을 사용하여 값이 공백 인 태그를 어떻게 파싱 할 것인가?

meta 
    : '<' NAME '>' TEXT '</' NAME '>' 
    | '<' NAME S* attribute* '>'; 

dl : '<' NAME '><' TEXT '>' dt* '</' NAME '><' TEXT '>'; 

dt : '<' NAME '><' NAME S* attribute* S* '>' TEXT '</' NAME '>'; 

attribute : attributeName '=' attributeValue; 

attributeName : NAME; 

attributeValue : VAL; 

NAME : [A-Z0-9_-]+; 

VAL : '"'.*?'"'; 

TEXT : [A-Za-z0-9:\/\[email protected]\-;\s*]+; 

S : [ \t\r\n]+ -> skip; 

문자열은

<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8"> 
<TITLE>Abcd</TITLE> 
<H1>Abcd</H1> 
<DL><p> 
    <DT><H3 ADD_DATE="1481473849" LAST_MODIFIED="1481473992" PERSONAL_XYZ_FOLDER="true">Foo bar</H3> 
</DL><p> 

나는 다음과 같은 오류가 발생하고 있습니다 :

ParseError extraneous input 'bar' expecting '</' clj-antlr.common/parse-error (common.clj:146) 

문제는 공간이 너무 건너 Foo bar에 공백이 때 오류를주고 있다는 것입니다 . 그러나 공간을 건너 뛰지 않으면 META 구문 분석에 또 다른 오류가 발생합니다. 공백을 건너 뛰는 경우 S*은 필요하지 않습니다. 나는 다음을 얻을 grun을 사용하여 실행,하지만 난보고 토큰에 오류가 표시되지 않는 경우

T__0=1 
T__1=2 
T__2=3 
T__3=4 
T__4=5 
DTD=6 
COMMENT=7 
NAME=8 
VAL=9 
TEXT=10 
S=11 
'<'=1 
'>'=2 
'</'=3 
'><'=4 
'='=5 

을 그리고 :

ParseError extraneous input ' ' expecting {'>', NAME} 
mismatched input '>' expecting '><' 
mismatched input '<' expecting {<EOF>, COMMENT, S} clj-antlr.common/parse-error (common.clj:146) 

여기 ANTLR에 의해 생성 된 내 토큰 파일입니다. 이것은 내가 정의한 문법과 비슷합니다. 태그 값에 공백을 허용하려면 어떻게해야합니까?

$ grun MyGrammer r -tokens 
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8"> 
[@0,0:0='<',<1>,1:0] 
[@1,1:4='META',<8>,1:1] 
[@2,5:5=' ',<11>,1:5] 
[@3,6:15='HTTP-EQUIV',<8>,1:6] 
[@4,16:16='=',<5>,1:16] 
[@5,17:30='"Content-Type"',<9>,1:17] 
[@6,31:31=' ',<11>,1:31] 
[@7,32:38='CONTENT',<8>,1:32] 
[@8,39:39='=',<5>,1:39] 
[@9,40:65='"text/html; charset=UTF-8"',<9>,1:40] 
[@10,66:66='>',<2>,1:66] 
[@11,67:67='\n',<11>,1:67] 
[@12,68:67='<EOF>',<-1>,2:0] 
No method for rule r or it has arguments 

감사합니다.

답변

1

foobar 사이에 공백을 넣으면 렉서가 두 개의 토큰 (유형이 TEXT)을 생성하지만 문법은 하나의 이름 토큰 만 허용한다고 명시합니다.

dt : '<' NAME '><' NAME S* attribute* S* '>' TEXT+ '</' NAME '>'; 

은 또한 당신의 이름과 꽤 몇 가지 입력을 변환 할 렉서 등의 문제로 실행 수 있다는주의 사항 : 문제를 해결하기 위해 당신은 단순히 더하기 연산자를 통해 seqnece에 몇 가지 텍스트를 허용해야 TEXT는 모두 패턴과 일치 할 수 있습니다. [A-Z0-9]+

+0

'TEXT +'를 주었는데 오류가 발생했습니다 : ParseError 외부 입력 '예상'{/ ', TEXT}' – boring

+0

'BOO '태그 값으로 'NAME'과 일치하므로 오류가 발생합니다. 어떻게 피할 수 있습니까? 나는'NAME'을'TEXT'로 대체하여 여분의 문자와 일치하지 않기를 원합니다. antlr과 함께 할 수 있습니까? – boring

+0

'content'를 값으로주는 마지막 부분을 수정했고'content : NAME * | TEXT *;'. 그러나 우주 문제는 해결되지 않았습니다. – boring