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