2017-12-17 27 views
0

사용 목적 :Lispian cond 매크로를 구현하는 방법은 무엇입니까?

cond! { 
    x > 5 => 0, 
    x < 3 => 1, 
    true => -1 
} 

가 확대 될 전망이다 : 그것은 포괄 else { ... } 접미사를 생성하지 않는다는

if x > 5 { 0 } else if x < 3 { 1 } else if true { -1 } 

참고.

내 시도 :

macro_rules! cond(
    ($pred:expr => $body:expr) => {{ 
     if $pred {$body} 
    }}; 
    ($pred:expr => $body:expr, $($preds:expr => $bodies:expr),+) => {{ 
     cond! { $pred => $body } else cond! { $($preds => $bodies),+ } 
    }}; 
); 

그러나, 컴파일러는 else 키워드에 대해 불평.

error: expected expression, found keyword `else` 
    --> src/main.rs:32:34 
    | 
32 |   cond! { $pred => $body } else cond! { $($preds => $bodies),+ } 
    |         ^^^^ 

답변

3

녹의 매크로는 C 전 처리기처럼 텍스트 대체를 수행하지 않습니다. 더욱이, 매크로의 결과는 이미 "파싱"되어 있으므로, 매크로가 확장되는 부분에 속한 매크로 호출 후에 무언가를 추가 할 수는 없습니다.

if 표현식을 컴파일러에서 이미 구문 분석했기 때문에 cond! 호출 이후에 else을 넣을 수 없습니다. ifelse을 함께 사용해야합니다. 마찬가지로 else 다음에 cond!을 다시 호출 할 때 else if 시퀀스는 중첩 된 if 표현식을 시작하지 않으므로 호출 주위에 중괄호를 추가해야합니다.

macro_rules! cond { 
    ($pred:expr => $body:expr) => { 
     if $pred { $body } 
    }; 
    ($pred:expr => $body:expr, $($preds:expr => $bodies:expr),+) => { 
     if $pred { $body } else { cond! { $($preds => $bodies),+ } } 
    }; 
} 

궁극적으로이 매크로는 거의 쓸모가 없습니다. else 절이없는 if 식의 형식은 항상 ()이라고 추측되는 형식이므로 모든 분기가 () (또는 발산)으로 평가되지 않는 한 확장 된 매크로는 형식 불일치 오류를 생성합니다.

+0

설명해 주셔서 감사합니다. –