Tôi hỏi ông Sweeney qua email và nhận được câu trả lời này:
C++ đang sử dụng các lớp mẫu tôi đã viết rằng thực hiện bộ phối hợp phân tích cú pháp. Ý tưởng là bắt đầu với một số trình phân tích cú pháp cơ bản, chẳng hạn như literals nơi PLit < 'A'> phân tích cú pháp một ký tự chữ 'A', PAny <> phân tích bất kỳ ký tự nào nhưng không thành công nếu kết thúc thất bại, PEof bị lỗi trừ khi chúng tôi không ở cuối tập tin, vv Và sau đó chúng ta kết hợp chúng thành các cây tùy ý bằng cách sử dụng các bộ phối hợp như PAnd phân tích cú pháp a và b, và chỉ thành công nếu cả hai thành công - nếu không nó sẽ không có điểm phân tích. Và nếu nó thành công, kết quả là một cấu trúc chứa hai trường, một cho kết quả của một và một cho kết quả của b. Và cứ thế. Việc triển khai thực hiện lộn xộn trong C++ vì một số lý do, bao gồm các mẫu đó không hỗ trợ các tham số tùy ý variadic và không có lambdas hạng nhất, chúng tôi không thể dễ dàng xử lý các kết quả trực tiếp với trình phân tích cú pháp.
Dưới đây là một số đoạn mã mẫu, từ đó bạn có thể tìm hiểu chi tiết của khuôn khổ.
// Parses a literal item.
UBOOL LiteralEvaluate (UClass* C,class FParseInBase& In,class FParseOutBase& Out)
{
FParseInMark M(In);
NNode* e = In.GetNextSource();
if (e && e->IsA(C))
{
Out.Callback(e);
return 1;
}
M.Restore(In);
return 0;
}
// Optional item of the specified type.
template <class U> struct Optional
{
static UBOOL Evaluate (class FParseInBase& In,FParseOutBase& Out)
{
U::Evaluate(In,Out);
return 1;
}
};
// Ignore items by absorbing them; retains boolean logic but not callback.
template <class T> struct Ignore
{
static UBOOL Evaluate (class FParseInBase& In,FParseOutBase& Out)
{
return T::Evaluate(In,GIgnore);
}
};
// Zero or more items of the specified type.
template <class T> struct ZeroOrMore
{
static UBOOL Evaluate (class FParseInBase& In,FParseOutBase& Out)
{
while (T::Evaluate(In,Out));
return 1;
}
};
// One or more items of the specified type.
template <class T> struct OneOrMore
{
static UBOOL Evaluate (class FParseInBase& In,FParseOutBase& Out)
{
for(INT i=0; T::Evaluate(In,Out); i++);
return i>0;
}
};
// Always fails.
struct RFalse
{
static UBOOL Evaluate (class FParseInBase& In,FParseOutBase& Out)
{
return 0;
}
};
// Always succeeds.
struct RTrue
{
static UBOOL Evaluate (class FParseInBase& In,FParseOutBase& Out)
{
return 1;
}
};
// Parses the first matching items of the specified subtypes of T.
template <class A,class B=RFalse,class C=RFalse,class D=RFalse > struct Or
{
static UBOOL Evaluate (class FParseInBase& In,FParseOutBase& Out)
{
return A::Evaluate(In,Out) || B::Evaluate(In,Out) || C::Evaluate(In,Out) || D::Evaluate(In,Out);
}
};
// Parses all the specified items.
template <class A,class B=RTrue,class C=RTrue,class D=RTrue> struct And
{
static UBOOL Evaluate (class FParseInBase& In,FParseOutBase& Out)
{
FParseInMark Mark(In);
Conjunction<NNode> Q;
if(A::Evaluate(In,Q) && B::Evaluate(In,Q) && C::Evaluate(In,Q) && D::Evaluate(In,Q))
{
Q.Forward(Out);
return 1;
}
Mark.Restore(In);
return 0;
}
};
// A separated list.
template <class A,class B> class SeparatedList : public Or<And<A,B,SeparatedList>,A> {};
// Integer comparison.
template <INT A,INT B> struct IsAtLeast
{
static UBOOL Evaluate (class FParseInBase& In,FParseOutBase& Out)
{
return A>=B;
}
};
Test.ae là ngôn ngữ kịch bản thử nghiệm mà tôi đã triển khai trong giai đoạn 1999-2001 - phối màu đó là hợp thời trang, tôi xin thề. :-)
Mã được hiển thị xác định siêu dữ liệu cho cấu trúc ngôn ngữ. Ngôn ngữ đã đi một chặng đường dài trên con đường Smalltalk "mọi thứ là một đối tượng", đối phó với metaclasses hạng nhất và các vấn đề liên quan, nhưng cuối cùng tôi đã từ bỏ nó khi tôi trở nên quen thuộc với hệ thống kiểu tiên tiến làm việc trong Haskell, Cayenne, Coq và ngôn ngữ.
Ngày nay -
Tôi không phải là một fan hâm mộ thực hiện phân tích cú pháp hoặc các trình biên dịch C++, vì mã có xu hướng được cồng kềnh bằng 70-80% so với thực hiện tương tự trong một ngôn ngữ chức năng hiện đại như Haskell. Đọc trên các bộ phối hợp trình phân tích cú pháp Haskell để biết thêm chi tiết - kết quả đơn giản và trực tiếp là mẫu mực và nó được thực hiện theo cách an toàn, an toàn.
Tôi nghĩ chủ đề/màu sắc gây sốc. Nếu không, câu hỏi thú vị. – ChristopheD
@ChristopheD Haha yeah. Tôi đã là một fan hâm mộ vào thời điểm đó mặc dù tôi đã thay đổi máy tính để bàn của tôi là như nhau - nó phải có được như thế nào * thực * lập trình làm việc! Tôi luôn tự hỏi liệu anh ta có đang đùa hay không. Và hình ảnh tôi đăng được cắt, đây là toàn bộ: http://praeclarum.org/so/sweeney-full.png –
Có thể anh ấy đang làm việc trên phiên bản thế hệ tiếp theo của ZZT-OOP ... :) http : //en.wikipedia.org/wiki/ZZT-oop –