2016-11-19 9 views

답변

2

해결책을 찾았습니다. 비 결정론을 처리해야합니다. 그것은 처음에는 분명 아니었지만, 올바른 해결책은 다음과 같이이다 : 당신은 당신이 콜백을 발사 이전에 캡처 한 정보를 사용하기 전에 완전한 CDATA 태그를 구문 분석하는 것을 확인하기 전까지

inner_text = any*; 
tag_cdata = '<![CDATA[' inner_text >text_begin %text_end ']]>' %cdata_end; 

action text_begin { 
    text_begin_at = p; 
} 

action text_end { 
    text_end_at = p; 
} 

action cdata_end { 
    delegate.cdata(data.byteslice(text_begin_at, text_end_at-text_begin_at)) 
} 

은 기본적으로 당신이 기다립니다.

또한 Ragel의 일부 비 결정론은 우선 순위를 사용하여 명시 적으로 처리해야한다는 것을 알게되었습니다. 이것은 약간 추한 것처럼 보이지만, 경우에 따라서는 유일한 해결책입니다.

과 같은 패턴을 처리 할 때 가장 긴 하위 시퀀스가 ​​아닌 a이 발생할 때마다 이벤트가 호출됩니다. 이 모호함은 어떤 경우에는 가장 긴 일치 인 kleene star **을 사용하여 해결할 수 있습니다. 이것이하는 일은 포장하는 것보다는 기존의 패턴을 맞추는 것을 선호하는 것입니다.

나에게 놀라운 것은 이벤트가 호출되는 방식을 실제로 변경한다는 것입니다.

%%{ 
    machine example; 

    action a_begin {} 
    action a_end {} 

    main := ('a'+ >a_begin %a_end | 'b')*; 
}%% 

가 생산 :

Non-greedy Parser

당신은 a_begin를 호출하는 것을 알 수 있습니다 예를 들어,이 콜백을 호출 할 때 한 번에 두 개 이상의 문자를 버퍼링 할 수없는 기계를 생산 매번 a_end입니다.

대조적으로, 우리는 내부 루프와 이벤트가 욕심 처리 할 수 ​​있습니다 :

%%{ 
    machine example; 

    action a_begin {} 
    action a_end {} 

    main := ('a'+ >a_begin %a_end | 'b')**; 
}%% 

생산되는 :

Greedy Parser

+0

가능하지 않음이 이상한 당신이 1 년에 자신의 해결책을 찾을 때 미래와 생각, 나는 정말로 그것을 썼는가? :) – ioquatix