2011-01-10 4 views
4

Qi와 Karma를 사용하여 몇 가지 작은 언어로 일부 처리를 수행했습니다. 문법의 대부분은 매우 작습니다 (20-40 규칙). 전 autorules를 거의 독점적으로 사용할 수 있었기 때문에 구문 분석 트리는 완전히 변형, 구조체 및 std :: vectors로 구성됩니다.
1)), 일 (치)을 분석
2) 파스 트리 (방문자에 약간의 조작을하고,
3) 출력 뭔가 (카르마) :Boost :: Spirit :: Qi autorules - AST 데이터 구조 반복 복사 방지.

이 설정은 일반적인 경우 위대한 작품.

그러나 큰 하위 트리를 움직이는 것처럼 구문 구조 트리를 복잡하게 구조적으로 변경하려면 어떻게 될지 걱정됩니다. ...

autorules를 사용하여 S-EXPR 스타일의 논리적 표현을위한 문법 ...

// Inside grammar class; rule names match struct names... 
pexpr %= pand | por | var | bconst; 
pand %= lit("(and ") >> (pexpr % lit(" ")) >> ")"; 
por %= lit("(or ") >> (pexpr % lit(" ")) >> ")"; 
pnot %= lit("(not ") >> pexpr >> ")"; 

...이처럼 보이는 나무 표현을 구문 분석 리드 다음 장난감의 예를 살펴

 pand 
    /... \ 
    por  por 
/\ /\ 
var var var var 

(T :

struct var { 
    std::string name; 
}; 
struct bconst { 
    bool val; 
}; 

struct pand; 
struct por; 
struct pnot;        

typedef boost::variant<bconst, 
         var, 
         boost::recursive_wrapper<pand>, 
         boost::recursive_wrapper<por>, 
         boost::recursive_wrapper<pnot> > pexpr; 
struct pand { 
    std::vector<pexpr> operands;      
}; 

struct por { 
    std::vector<pexpr> operands;      
}; 

struct pnot { 
    pexpr victim; 
}; 

// Many Fusion Macros here 

나는 이런 식으로 뭔가를 보이는 파스 트리가 있다고 가정 그는 'pand 비슷한 모양의 더 많은 아이들.'수단을 줄임표)

을 이제 최종 결과가되도록 내가의 por 각 노드를 부정한다고 가정 :

 pand 
    /... \ 
    pnot  pnot 
    |  | 
    por  por 
/\ /\ 
var var var var 

직접 접근 것 각 por 서브 트리를 들면, :
- 생성 pnot 노드
(복사 건설 por);
pand 노드
(pnot 노드와 해당 por 하위 트리)에 적절한 벡터 슬롯을 다시 할당하십시오.

또는 별도의 벡터를 구성한 다음 pand 벡터를 교체 (교체)하여 두 번째 복사를 생략 할 수있었습니다.

이 모든 것은 기존 노드를 복사하지 않고 pnot 노드를 삽입 할 수있는 포인터 기반 트리 표현과 비교하면 복잡해 보입니다. 내 질문 :

자동 치료 호환 데이터 구조로 복사량이 많은 트리 조작을 피할 수있는 방법이 있습니까? 글 머리 기호를 물고 포인터 기반 AST (예 : http://boost-spirit.com/home/2010/03/11/s-expressions-and-variants/)를 만들기 위해 비 autorules를 사용해야합니까?

답변

3

recursive_variant는 본질적으로 shared_ptr을 감싸는 래퍼이기 때문에 하위 트리를 복사하는 것은 비용이 많이 들지 않습니다. 나는 그것이 최선 일뿐만 아니라 가장 쉬운 해결책이라고 믿습니다.

+1

귀하의 통찰력에 감사드립니다. 나는 변종 구현에 많은 관심을 기울이지 않았다.복사 작업을 확인하는 간단한 실험을 실행했습니다. - 두 개의 기존 노드 사이에 노드를 삽입하면 복사 작업 수가 일정하게됩니다 (삽입 아래에 하위 트리의 크기가 커지지 않음). - 대부분의 복사는 벡터 크기 조정으로 인해 발생합니다. 이렇게 말하면 풀이 할당 된 포인터 기반 AST 노드에 대해 디렉터를 지원하는 것이 좋을 수 있습니다. 그 설정의 한 가지 좋은 특성은 노드 주소를 저렴한 고유 해시로 사용할 수 있다는 것입니다. – phooji

관련 문제