2009-10-28 47 views
5

Cách tốt nhất để xử lý nhiều trình phân tích cú pháp Flex/Bison bên trong một dự án là gì?Nhiều trình phân tích cú pháp flex/bison

Tôi đã viết một trình phân tích cú pháp và bây giờ tôi cần một trình phân tích cú pháp thứ hai trong cùng một dự án. Cho đến nay trong phần thứ ba của parser1.y Tôi đã chèn phương thức main(..) và được gọi là yyparse từ đó.

Những gì tôi muốn có được là có hai phân tích cú pháp khác nhau (parser1.yparser2.y) và có thể sử dụng chúng từ một chức năng bên ngoài (chúng ta hãy giả main trong main.cpp).

Tôi nên sử dụng biện pháp phòng ngừa nào để xuất các hàm yyparse bên ngoài .y tệp và tôi nên xử lý hai trình phân tích cú pháp như thế nào?

PS. Tôi đang sử dụng g + + để biên dịch nhưng không phải là phiên bản C++ của Flex và Bison và tôi muốn giữ nó theo cách này (để tránh đóng gói bộ phân tích cú pháp bên trong một đối tượng).

Trả lời

7

Lưu ý rằng Bison cung cấp tùy chọn '-p zz' cho các ký hiệu tiền tố có 'zz' thay vì 'yy'.

Tương tự, Flex cung cấp tùy chọn '-P zz' cho các ký hiệu tiền tố có 'zz' thay vì 'yy'. Nó sử dụng '-p' để báo cáo hiệu suất. 'Thật đáng tiếc là họ không nhất quán với nhau.

+0

Khi tôi làm điều này, từ khoá và trình phân tích cú pháp của tôi có rất nhiều tham chiếu đến YYTYPE và YYSTYPE, v.v. và việc biên dịch không thành công. Tại sao những người không được chuyển đổi? Tôi đang làm gì sai ?? Tôi không muốn một trình phân tích cú pháp reentrant, tôi chỉ muốn một trình phân tích cú pháp một lần gọi một trong hai trình phân tích cú pháp, sau đó chương trình thoát ra. – TimeHorse

+0

@TimeHorse: Với khoảng thời gian từ khi câu hỏi này được trả lời và bình luận/câu hỏi của bạn, tôi nghĩ bạn nên đặt một câu hỏi mới, minh họa vấn đề bạn gặp phải với hai ví dụ nhỏ/ngữ pháp nhỏ (MCVE - [MCVE ]) và hiển thị quá trình xây dựng bạn đang sử dụng và các thông báo lỗi bạn đang nhận được. Nếu bạn không có cơ hội để cung cấp thông tin đó, mà bạn nhận được với một câu hỏi mới, tôi không thể thực sự đưa ra câu trả lời. Bằng mọi cách, hãy quay lại và để lại bình luận ở đây yêu cầu tôi xem xét câu hỏi mới của bạn; hãy xem xét bao gồm cả liên kết đến câu hỏi này trong câu hỏi của bạn. –

10

Ngoài câu trả lời Leffler, tôi muốn cung cấp cách tiếp cận khác ở đây:

Trong tập tin .lex bạn có thể sử dụng %option prefix="PREFIX", và trong file .y bạn có thể sử dụng %define api.prefix PREFIX, mà làm điều tương tự như đi qua -p PREFIX tới Bison và -P PREFIX để Flex.

Thông báo sau khi trọng của tiền tố mặc định yy, bạn có thể truy cập vào tên nội bộ thông qua cả hai bản gốc yy* và bạn ghi đè PREFIX*, trong khi rõ ràng cho tên bên ngoài bạn PHẢI sử dụng của bạn PREFIX* để truy cập chúng.

+0

Lưu ý rằng trong các phiên bản bison hiện đại, bạn cần phải thực hiện '% define api.prefix {PREFIX}' hoặc bạn nhận được cảnh báo –

5

Nếu bạn sử dụng Bison 3.0 hoặc cao hơn, sau đó có một cái nhìn tại %define api.prefix {foo_}, thay thế tất cả yyYY tiền tố với foo_FOO_.

Xem Documentation about Multiple Parsers.

Giữa Bison 2.6 và 3.0, không có dấu ngoặc đơn: %define api.prefix foo_.

-1

Ngoài những gì đã được nêu, nếu bạn sử dụng '% define api.prefix {PREFIX}', nó cũng sẽ đổi tên yytext & & yyparse thành PREFIXtext và PREFIXparse. Đừng quên {} xung quanh tiền tố!
Điều tương tự cũng áp dụng cho '% prefix prefix = "PREFIX"' trong lex, từ khoá của bạn sẽ được đổi tên thành PREFIXlex.

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