2017-10-29 1 views
1

완전히 stateless 인 nom에 파서를 썼습니다. 이제는 몇개의 스테이트 풀 레이어로 포장해야합니다.nom 파서에 상태 추가하기

저는 최상위 파싱 함수 alt_fn을 가지고 있습니다.이 파싱 함수는 파스 된 결과의 다음 비트를 enum 변형으로 제공합니다. 세부 사항은 아마도 중요하지 않을 수 있습니다. 나는 세 가지를 가지고

은 그 상태를 포함 할 필요가 : 내가의 일부가 아닌 가변의 HashMap에서 일치가있는 경우 조건부 alt_fn의 출력에 변환을 수행 할 필요가

1) 내 State 구조체. 이것은 기본적으로 map! 같아야하지만 내 구조체에 대한 메서드 호출로. 이런 식으로 뭔가 : 이것은 현재 나와 있습니다

named!(alt_fn<AllTags> ,alt!(// snipped for brevity)); 

fn applyMath(self, i:AllTags)->AllTags { // snipped for brevity } 

method!(apply_math<State, &[u8], AllTags>, mut self, call_m!(self.applyMath, call!(alt_fn))); 

: alt_fnerror: unexpected end of macro invocation 밑줄.

2) 상태 구조체의 다른 필드를 입력 (예 : 계산 체크섬 및 업데이트 타임 스탬프 등)을 통해 얻은 데이터로 업데이트 한 다음이 새로운 지식으로 출력을 다시 변환해야합니다. 이것은 아마도 모양을 다음

method!(pub parse<State,&[u8],Vec<AllTags>>, mut self, many1!(update_state));

는 불행하게도 nom 문서 꽤 있습니다 : 모든 입력이 소진 될 때까지 나는 계속 두 번째 부분에서 메소드를 호출 할 필요가

fn updateState(mut self, i:AllTags) -> AllTags { // snipped for brevity } 

method!(update_state<State, &[u8], AllTags>, mut self, call_m!(self.updateState, call_m!(self.applyMath))); 

3) 제한적이며 매크로 구문이 좋지 않아서 내가 뭘 잘못하고 있는지 알지 못합니다.

+0

나는 답을 알고 있는지 모르겠다. - 나는 그 질문이 무엇인지 모르지만, 매크로가'nom'에서 어떻게 작동하는지 조금 설명 할 수있다. 함수형 언어에서는 [partial application] (https://en.wikipedia.org/wiki/Partial_application)을 사용할 수 있습니다. 여기서 일부 인수를 함수에 전달하면 나머지 인수를 요구하는 새로운 함수가 만들어집니다. Nom은 마지막 인수가 입력 인 이러한 함수로 결합자를보고 있으므로 일부 응용 프로그램에서 다른 인수를 전달하면 구체적인 파서가 작성됩니다. 그래서'tag ("a")'는'i'를 기대하는 함수이고'tag (i, "a")'는 파서를 적용하는 실제 명령입니다. 희망 하시겠습니까? – derekdreery

답변

0

nom으로 복잡한 작업을 수행해야 할 때 일반적으로 내 자신의 기능을 작성합니다. 예를

named!(my_func<T>, <my_macros>); 

를 들어

는 (내 의견을 참조) 매크로에 i를 통과해야합니다, 단

fn my_func(i: &[u8]) -> nom::IResult<T, &[u8]> { 
    <my_macros> 
} 

에 해당합니다.

자신의 기능을 사용하면 당신이 거기에 원하는 제어 흐름을 가질 수 있음을 의미 생성, 그것은 오래 그것은 & [U8] 소요 NOM : IResult 출력 & [U8]를 반환으로 nom에 좋은 재생됩니다 나머지 해석되지 않은 원시 입력입니다.

추가 정보 의견이 필요하면 답을 개선해 보겠습니다.

+0

나는 당신의 코멘트를 옮길 것입니다. 귀하의 답변에 - 덧글은 덧 없으며 대답은 적습니다. – Shepmaster