2017-02-03 11 views
4

현재 일부 Perl6에서 손이 더러워졌습니다. 특히 내가 테스트 목적으로 문법을 기반으로 포트란 파서합니다 (Fortran::Grammar 모듈)Perl6 : JSON- 직렬화 가능 해시로 일치 개체 변환

을 쓰기 위해 노력하고 있어요, 내가 JSON 직렬화 HashMatch 개체를 변환 할 수있는 possiblity를가하고자합니다.

Google 검색/official Perl6 documentation 도움이되지 않았습니다. 내가 간과한다면 사과드립니다.

내 시도 지금까지이 :

  • 나는 하나 $m.hash를 통해 HashMatch $m을 변환 할 수 있습니다 것을 알고있다. 그러나이 객체는 중첩 된 Match 객체를 유지합니다. 이것은 단지 재귀를 통해 풀수 수을 가지고 있기 때문에
  • , 나는 시도했지만 분명 최고의 make를 통해 수행됩니다 Match 객체의 내용을 다루기 여기
  • 간단한/기존 솔루션의 실존에 대한 첫 번째 질문에 찬성 포기/made. 나는 간단하게 Actions 수퍼 객체를 가지고 싶습니다. .parse기본값 메쏘드가 있습니다. 모든 일치는 기본적으로 make $/.hash 같은 것입니다. 난 그냥 기본 방법을 지정하는 방법에 대해 잘 모르겠습니다.

답변

5

여기 내 Perl 6 프로젝트 중 하나 인 액션 클래스 메소드가 설명하는 것을 수행합니다.

거의 크리스토프 게시 된 내용과 동일하지 않습니다,하지만 더 자세하게 기록 (내가 쉽게 이해할 수 있도록 주석의 풍부한 양을 추가 한) :

#| Fallback action method that produces a Hash tree from named captures. 
method FALLBACK ($name, $/) { 

    # Unless an embedded { } block in the grammar already called make()... 
    unless $/.made.defined { 

     # If the Match has named captures, produce a hash with one entry 
     # per capture: 
     if $/.hash -> %captures { 
      make hash do for %captures.kv -> $k, $v { 

       # The key of the hash entry is the capture's name. 
       $k => $v ~~ Array 

        # If the capture was repeated by a quantifier, the 
        # value becomes a list of what each repetition of the 
        # sub-rule produced: 
        ?? $v.map(*.made).cache 

        # If the capture wasn't quantified, the value becomes 
        # what the sub-rule produced: 
        !! $v.made 
      } 
     } 

     # If the Match has no named captures, produce the string it matched: 
     else { make ~$/ } 
    } 
} 

주 :

  • 이것은 위치 캡쳐 (문법 내에 ()으로 만들어진 캡쳐)를 완전히 무시합니다. 해시 트리를 만들기 위해 명명 된 캡쳐 (예 : <foo> 또는 <foo=bar>) 만 사용됩니다. 당신이 그들과 함께하고 싶은 것에 따라 그것들을 다루기 위해 수정 될 수도 있습니다.다음을 유의하십시오.
    • $/.hashMap으로 명명 된 캡처를 제공합니다.
    • $/.list은 위치 캡처를 List으로 제공합니다.
    • $/.caps (또는 $/.pairs)은 name=>submatch 및/또는 index=>submatch 쌍의 시퀀스로 명명 된 캡처와 위치 캡처를 모두 제공합니다.
  • 그것은, 또는 방법을 추가하여 당신이 중 하나를 (당신이 결코 의도적으로 make에 정의되지 않은 값을 원하는 없다고 가정) 문법의 규칙 내부 { make ... } 블록을 추가하여 특정 규칙에 대한 AST 생성을 대체 할 수 있습니다 액션 클래스의 룰의 이름.
+2

'.caps'와'.pairs'의 차이점은 전자는 같은 키에 해당하는 서브 쿼리를 다른 항목으로 나열하는 반면, 후자는 키를 반복하지 않고 배열에 서브 쿼리를 배치한다는 것입니다 필요한 – Christoph

3

기본 방법을 지정하는 방법에 대해서는 알지 못합니다.

메소드 이름 FALLBACK은이 용도로 예약되어 있습니다. 당신의 행동 클래스에이

method FALLBACK($name, $/) { 
    make $/.pairs.map(-> (:key($k), :value($v)) { 
     $k => $v ~~ Match ?? $v.made !! $v>>.made 
    }).hash || ~$/; 
} 

같은

추가 뭔가 작업을해야합니다.

명시 적 작업 방법이없는 각 명명 된 규칙의 경우 해당 서브 규칙 (명명 된 것 또는 위치 캡쳐)을 포함하는 해시 또는 규칙이 '원자'이고 일치하는 문자열의 하위 규칙이없는 경우 make이됩니다.