Có một định lý dân gian nói rằng C rất khó để phân tích cú pháp, và C ++ về cơ bản là không thể.
Nó không đúng.
Điều đúng là C và C ++ khá khó để phân tích cú pháp bằng cách sử dụng bộ phân tích cú pháp LALR (1) mà không cần đến máy móc phân tích cú pháp và làm rối trong dữ liệu bảng ký hiệu. Trên thực tế, GCC đã sử dụng để phân tích cú pháp chúng, sử dụng YACC và các phương thức hack bổ sung như thế này, và vâng, nó thật tệ. Giờ đây, GCC sử dụng các trình phân tích cú pháp viết tay, nhưng vẫn với hack bảng biểu tượng. Người Clang chưa bao giờ cố gắng sử dụng các trình tạo phân tích cú pháp tự động; AFAIK trình phân tích cú pháp Clang luôn được mã hóa thủ công gốc đệ quy.
Điều đúng là C và C ++ tương đối dễ phân tích cú pháp với các trình phân tích cú pháp được tạo tự động mạnh hơn, ví dụ: trình phân tích cú pháp GLR và bạn không cần bất kỳ bản hack nào. Bộ phân tích cú pháp Elsa C ++ là một ví dụ về điều này. Giao diện người dùng C ++ của chúng tôi là một giao diện khác (cũng như tất cả các giao diện người dùng "trình biên dịch" của chúng tôi, GLR là công nghệ phân tích cú pháp khá tuyệt vời).
Giao diện người dùng C ++ của chúng tôi không nhanh bằng GCC và chắc chắn chậm hơn Elsa; chúng tôi đã dành ít năng lượng để điều chỉnh nó một cách cẩn thận bởi vì chúng tôi có những vấn đề cấp bách khác (tuy nhiên nó đã được sử dụng trên hàng triệu dòng mã C ++). Elsa có thể chậm hơn GCC đơn giản vì nó chung chung hơn. Với tốc độ của bộ xử lý ngày nay, những khác biệt này có thể không quan trọng nhiều trong thực tế.
Nhưng các "trình biên dịch thực sự" được phân phối rộng rãi ngày nay có nguồn gốc từ các trình biên dịch của 10, 20 năm trước hoặc hơn. Sau đó, sự kém hiệu quả còn quan trọng hơn nhiều, và chưa ai nghe nói về trình phân tích cú pháp GLR, vì vậy mọi người đã làm những gì họ biết cách làm. Clang chắc chắn là gần đây hơn, nhưng sau đó các định lý dân gian vẫn giữ được "sức thuyết phục" của chúng trong một thời gian dài.
Bạn không cần phải làm theo cách đó nữa. Bạn rất có thể sử dụng hợp lý GLR và các trình phân tích cú pháp khác làm giao diện người dùng, với sự cải thiện về khả năng bảo trì trình biên dịch.
Sự thật là như thế nào, là khó có được một ngữ pháp phù hợp với hành vi của trình biên dịch hàng xóm thân thiện của bạn. Trong khi hầu như tất cả các trình biên dịch C ++ đều triển khai (hầu hết) tiêu chuẩn ban đầu, chúng cũng có xu hướng có nhiều phần mở rộng góc tối, ví dụ: thông số kỹ thuật DLL trong trình biên dịch MS, v.v. Nếu bạn có một công cụ phân tích cú pháp mạnh, bạn có thể dành thời gian cố gắng lấy ngữ pháp cuối cùng để phù hợp với thực tế, thay vì cố gắng bẻ cong ngữ pháp của bạn để phù hợp với những hạn chế của trình phân tích cú pháp của bạn.
CHỈNH SỬA Tháng 11 năm 2012: Kể từ khi viết câu trả lời này, chúng tôi đã cải thiện giao diện người dùng C ++ của mình để xử lý C ++ 11 đầy đủ, bao gồm các phương ngữ biến thể ANSI, GNU và MS. Mặc dù có rất nhiều thứ bổ sung, chúng tôi không cần phải thay đổi công cụ phân tích cú pháp của mình; chúng tôi vừa sửa đổi các quy tắc ngữ pháp. Chúng tôi đã phải thay đổi phân tích ngữ nghĩa; C ++ 11 rất phức tạp về mặt ngữ nghĩa và công việc này làm tiêu hao nỗ lực để trình phân tích cú pháp chạy.
CHỈNH SỬA Tháng 2 năm 2015: ... hiện xử lý đầy đủ C ++ 14. (Xem lấy AST có thể đọc được của con người từ mã c ++ để phân tích cú pháp GLR của một đoạn mã đơn giản và "phân tích cú pháp khó chịu nhất" khét tiếng của C ++).
CHỈNH SỬA Tháng 4 năm 2017: Bây giờ xử lý (bản nháp) C ++ 17.