현재 주제에 대한 개인 교육을위한 컴파일러 프런트 엔드를 작성 중이며 연산자 오버로딩을 통해 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. 나는 다양한 파서 생성기와 부스트를 알고있다.하지만 내 목표는 내 파서를 작성하는 것이다.