2012-11-21 3 views
1

현재 주제에 대한 개인 교육을위한 컴파일러 프런트 엔드를 작성 중이며 연산자 오버로딩을 통해 C++에서 BNF 정의를 처리하는 방식과 관련된 문제가 발생했습니다.스택에서 객체 파손 처리

Rule.h :

class Rule 
{ 
public: 
    ChainRule operator>>(Rule& right); 
    OrRule operator|(Rule& right); 
    KleeneRule operator*(); 
    OptionalRule Rule::operator+(); 

    virtual bool parse(TokenList::iterator& begin, TokenList::iterator end) = 0; 
}; 

Rule.cpp을 다음과 같이

현재 내 설정이다

연쇄 법칙은, OrRule, KleeneRule, OptionalRule 및 EmptyRule이처럼 하찮게 정의
ChainRule Rule::operator>>(Rule& right) { 
    return ChainRule(this, &right); 
} 

OrRule Rule::operator|(Rule& right) { 
    return OrRule(this, &right); 
} 

KleeneRule Rule::operator*() { 
    return KleeneRule(this); 
} 

OptionalRule Rule::operator+() { 
    return OptionalRule(this); 
} 

그래서 :

class ChainRule : public Rule 
{ 
private: 
    Rule* next; 
    Rule* _this; 

public: 
    ChainRule(); 
    ChainRule(Rule* _this, Rule* right); 

    bool parse(TokenList::iterator& begin, TokenList::iterator end) override; 
}; 

규칙의 각 하위 클래스는 parse()의 resonable 구현을 분명히 정의합니다. 다음과 같이 내 문법을 정의 할 수 있습니다 이러한 클래스를 사용 :

OrRule assignment_exp = logical_or_exp 
         | unary_exp >> StringRule("=") >> assignment_exp 
         ; 

하는 것은 이제 문제는 여기에있다 : 각 오버로드 된 연산자 값에 의해 새로운 개체를 반환합니다. 즉, 연산자 >> 또는 연산자를 사용할 때마다 | Rule 클래스에서 연산자 >> 또는 연산자에 대한 호출에서 돌아 오면이 포인터는 쓰레기가됩니다. 스택이 정리되고 객체가 사라지기 때문입니다.

재귀 문법을 정의 할 수 없으므로 내 규칙 하위 클래스의 생성자에서 값 전달을 사용할 수 없습니다.

그래서 값으로 개체를 전달할 옵션이없고 포인터로 개체를 전달할 수있는 옵션이 없습니다. 아무도 나를 그렇게 내 문법을 정의하도록 강요하지 않을 솔루션을 가리킬 수 있습니까?

StringRule s = StringRule("="); 
OrRule assignment_exp; 
ChainRule temp1 = s >> assignment_exp; 
ChainRule temp2 = unary_exp >> temp1; 
assignment_exp = logical_or_exp | temp2; 

P. 나는 다양한 파서 생성기와 부스트를 알고있다.하지만 내 목표는 내 파서를 작성하는 것이다.

답변

1

반환 객체를 (공장을 통해) 힙에 할당하고 참조로 반환 할 수 있습니다. 공장에서 누출되지 않도록 추적 할 수 있습니다. 구문에 관해서는 값으로 반환 할 때와 동일하게 작동합니다.

1

Rule* (연산자에 과부하가 걸리지 않는다는 문제가있는)을 래퍼 객체로 바꾸면이 문제를 해결할 수 있습니다. 나는. ChainRuleRule * next 등 대신 RuleRef next을 포함하고 모든 연산자는 RuleRef으로 정의됩니다. RuleRef은 단순히 Rule*을 포함 할 것이며 Rule*에서 생성 가능해야합니다. 메모리 처리를 쉽게하기 위해 스마트 포인터 클래스에서 상속받을 수 있습니다.