Đối với khuôn khổ chút phân tích cú pháp rất riêng của tôi, tôi đang cố gắng để xác định (một cái gì đó tương tự) các chức năng sau:"bản sao cacbon" a c + + istream?
template <class T>
// with operator>>(std::istream&, T&)
void tryParse(std::istream& is, T& tgt)
{
is >> tgt /* , *BUT* store every character that is consumed by this operation
in some string. If afterwards, is.fail() (which should indicate a parsing
error for now), put all the characters read back into the 'is' stream so that
we can try a different parser. */
}
Sau đó, tôi có thể viết một cái gì đó như thế này: (có thể không phải là ví dụ tốt nhất)
/* grammar: MyData = <IntTriple> | <DoublePair>
DoublePair = <double> <double>
IntTriple = <int> <int> <int> */
class MyData
{ public:
union { DoublePair dp; IntTriple it; } data;
bool isDoublePair;
};
istream& operator>>(istream& is, MyData& md)
{
/* If I used just "is >> md.data.it" here instead, the
operator>>(..., IntTriple) might consume two ints, then hit an
unexpected character, and fail, making it impossible to read these two
numbers as doubles in the "else" branch below. */
tryParse(is, md.data.it);
if (!is.fail())
md.isDoublePair = false;
else
{
md.isDoublePair = true;
is.clear();
is >> md.data.dp;
}
return is;
}
Bất kỳ trợ giúp nào được đánh giá cao.
Luồng không phải là công cụ phù hợp cho điều này, do thiếu sự bỏ rơi phù hợp. Khi thiết kế các trình phân tích cú pháp nội tuyến đơn giản như thế này (nếu không, hãy cố gắng để 'tăng :: tinh thần'), các hàm phân tích cú pháp thực sự cần có một cặp các trình lặp. Nó trở nên dễ dàng để quay trở lại (chỉ cần lưu giá trị của trình lặp trước một trình phân tích cú pháp backtracking). –