2013-02-06 32 views
7

Trong LLVM tutorials có hướng dẫn cách viết trình biên dịch JIT đơn giản. Unfortunatelly, lexer và phân tích cú pháp trong hướng dẫn này được viết bằng tay. Tôi đã suy nghĩ, giải pháp như vậy là tốt cho mục đích học tập nhưng nó không thích hợp để viết các trình biên dịch phức tạp, sản xuất sẵn sàng. Dường như GCC và vài "trình biên dịch lớn" khác được viết tay. Nhưng tôi nghĩ, rằng tất cả các trình tạo phân tích cú pháp này tạo ra một sự thúc đẩy lớn khi viết trình biên dịch riêng (đặc biệt là khi bạn làm một mình, không có nhóm người).LLVM JIT Trình phân tích cú pháp bằng văn bản với Bison/Antlr/Packrat/Elkhound/

Có thể sử dụng bất kỳ trình tạo trình phân tích cú pháp hiện tại nào như Bison/Antlr/Packrat/Elkhound, vv cùng với LLVM để tạo trình biên dịch JIT không? Tôi muốn có thể "cung cấp" trình phân tích cú pháp liên tục (không phải một lần vào đầu) với các biểu thức và biên dịch chúng trong thời gian chạy.

Tôi đã tìm thấy rất nhiều câu hỏi về trình tạo phân tích cú pháp "tốt nhất, hiện đại" (như thế này: https://stackoverflow.com/questions/428892/what-parser-generator-do-you-recommend). Nếu có thể sử dụng các công cụ này để tạo trình biên dịch LLVM JIT, tôi sẽ biết ơn bất kỳ gợi ý bổ sung nào và đề xuất nào, công cụ nào sẽ là tốt nhất về hiệu suất và tính linh hoạt trong trường hợp cụ thể này.

+0

"Giải pháp như vậy là tốt cho mục đích học tập nhưng không phù hợp để viết các trình biên dịch phức tạp, sản xuất sẵn sàng" - Hm. Tôi luôn nghĩ GCC là một trình biên dịch phức tạp và sẵn sàng sản xuất. Bất cứ điều gì ... –

+0

GCC đã sử dụng bison vào đầu, nhưng bạn nói đúng - tôi đang sửa nó trong câu hỏi của tôi. Nhưng thực sự, tôi rất thích sử dụng một máy phát điện để đơn giản hóa nhiệm vụ này nếu có thể. –

+5

Nếu có, tôi sẽ nói ngược lại là đúng: yacc, Bison, et al, phù hợp cho mục đích học tập và như vậy, nhưng đối với công việc sản xuất nghiêm túc, một trình phân tích cú pháp viết tay có thể là cách duy nhất để đáp ứng các yêu cầu. –

Trả lời

9

Có rất nhiều lợi thế khi sử dụng trình tạo trình phân tích cú pháp như bison hoặc antlr, đặc biệt khi bạn đang phát triển ngôn ngữ. Bạn chắc chắn sẽ kết thúc việc thay đổi ngữ pháp khi bạn đi, và bạn sẽ muốn kết thúc với tài liệu về ngữ pháp cuối cùng. Các công cụ tạo ra một ngữ pháp tự động từ tài liệu này thực sự hữu ích. Chúng cũng có thể giúp bạn tự tin rằng ngữ pháp của ngôn ngữ là (a) bạn nghĩ nó là gì và (b) không mơ hồ.

Nếu ngôn ngữ của bạn (không giống như C++) thực sự là LALR (1) hoặc thậm chí tốt hơn, LL (1) và bạn đang sử dụng các công cụ LLVM để xây dựng AST và IR, thì bạn sẽ không cần phải làm nhiều hơn là viết ra ngữ pháp và cung cấp một vài hành động đơn giản để xây dựng AST. Điều đó sẽ giữ cho bạn đi một lúc.

Lý do thông thường mà mọi người chọn để xây dựng trình phân tích cú pháp của riêng họ, không phải là "người lập trình thực sự không sử dụng trình tạo phân tích cú pháp" thành kiến, không dễ dàng cung cấp chẩn đoán tốt cho lỗi cú pháp, đặc biệt với LR (1)) phân tích cú pháp. Nếu đó là một trong những mục tiêu của bạn, bạn nên cố gắng làm cho ngữ pháp của bạn LL (k) có thể phân tích được (nó vẫn không dễ cung cấp chẩn đoán tốt với LL (k), nhưng có vẻ dễ hơn một chút) và sử dụng LL (k) khuôn khổ như Antlr. Có một chiến lược khác, đầu tiên phân tích cú pháp văn bản chương trình theo cách đơn giản nhất có thể bằng cách sử dụng một trình phân tích cú pháp LALR (1), linh hoạt hơn LL (1), mà thậm chí không cố gắng cung cấp chẩn đoán. Nếu phân tích cú pháp không thành công, bạn có thể phân tích lại bằng cách sử dụng trình phân tích cú pháp chậm hơn, có thể thậm chí ngược lại, không biết cách tạo AST, nhưng theo dõi vị trí nguồn và cố gắng khôi phục các lỗi cú pháp. Phục hồi từ cú pháp cú pháp mà không làm mất hiệu lực AST thậm chí còn khó khăn hơn là chỉ tiếp tục phân tích cú pháp, do đó, có rất nhiều điều để nói không cố gắng. Ngoài ra, việc theo dõi vị trí nguồn thực sự chậm và không hữu ích nếu bạn không phải tạo chẩn đoán (trừ khi bạn cần thêm chú thích gỡ lỗi), vì vậy bạn có thể tăng tốc độ phân tích cú pháp lên một chút bằng cách không làm phiền theo dõi vị trí.

Cá nhân, tôi thiên về phân tích cú pháp gói, vì không rõ ngôn ngữ thực tế được phân tích cú pháp bằng PEG là gì. Những người khác không quan tâm đến điều này rất nhiều, và YMMV.

+1

Tại sao "không rõ" ngôn ngữ thực sự là gì? PEG được xác định rõ, ngay cả với tất cả các hacks mát mẻ mà packrat cho phép để làm (phân tích thứ tự cao và như vậy). –

+1

@ SK-logic: được xác định rõ ràng không giống như rõ ràng. Trình phân tích cú pháp thủ công được viết bằng C++ được xác định rõ. Một máy Turing được xác định rõ. Có, PEG được xác định rõ. Nhưng đối với tất cả chúng, cách duy nhất để xem liệu một chuỗi ký tự có trong ngôn ngữ đó là để thực thi mã. (Trong ba lựa chọn đó, PEG ít nhất là xấu. Nhưng tôi vẫn thích ngữ pháp ngữ pháp tự do hơn. Tuy nhiên, như tôi đã nói, những người khác như PEG, và bất cứ điều gì làm việc cho bạn đều mát mẻ với tôi.) – rici

+0

Từ kinh nghiệm thực tế của tôi , PEG là các ngữ pháp rõ ràng và dễ đọc nhất. Tôi có thể dịch một spec ngôn ngữ thẳng vào một PEG với rất ít sửa đổi. Nó có thể làm xáo trộn nó, tất nhiên, nhưng tôi chưa thấy một ngữ pháp thực sự xấu. Trong khi có rất nhiều không thể đọc được vượt quá bất kỳ ngữ pháp Yacc hy vọng. –

Các vấn đề liên quan