2009-07-15 14 views
5

Tôi đang sử dụng Flex và Bison cho trình tạo trình phân tích cú pháp, nhưng gặp sự cố với trạng thái bắt đầu trong máy quét của tôi.Trạng thái bắt đầu bằng Lex/Flex

Tôi đang sử dụng quy tắc độc quyền để đối phó với bình luận, nhưng ngữ pháp này dường như không phù hợp với thẻ trích dẫn:

%x COMMENT 

//     { BEGIN(COMMENT); } 
<COMMENT>[^\n]  ; 
<COMMENT>\n   { BEGIN(INITIAL); } 

"=="     { return EQUALEQUAL; } 

.      ; 

Trong ví dụ đơn giản này dòng:

// a == b 

isn' t khớp hoàn toàn với tư cách nhận xét, trừ khi tôi bao gồm quy tắc này:

<COMMENT>"=="    ; 

Làm cách nào để tôi nhận được vòng này withou t phải thêm tất cả các mã thông báo vào quy tắc độc quyền của tôi?

Trả lời

9

Matching comments C-style trong Lex/Flex hoặc bất cứ điều gì cũng được ghi chép lại:

in the documentation, cũng như các biến khác nhau trên Internet.

Đây là một biến thể trên được tìm thấy trong các tài liệu Flex:

<INITIAL>{ 
    "//"    BEGIN(IN_COMMENT); 
    } 
    <IN_COMMENT>{ 
    \n  BEGIN(INITIAL); 
    [^\n]+ // eat comment 
    "/"  // eat the lone/
    } 
+0

Tôi không muốn sử dụng các trạng thái bao gồm nếu có thể tránh được vì tôi có nhiều quy tắc. Vấn đề là quy tắc 'ăn bình luận' này dường như không khớp với các thẻ với nhiều hơn một ký tự (chẳng hạn như ==). – Dan

+0

Sau đó, tôi nghĩ rằng bạn có thể làm điều gì đó sai trái. Bạn cần phải tạo 'trình phân tích cú pháp phụ' cho các nhận xét, không phù hợp với mã thông thường của bạn. –

+0

Giả sử, bạn muốn lưu trữ dòng của mỗi đầu vào, sau đó điều này sẽ cung cấp cho bạn số dòng không chính xác? –

2

Hãy thử thêm một "+" sau khi [^ n] Quy tắc. Tôi không biết tại sao nhà nước độc quyền vẫn chọn '==' ngay cả trong một trạng thái độc quyền, nhưng rõ ràng là vậy. Flex thường sẽ khớp với quy tắc phù hợp với hầu hết văn bản và thêm "+" ít nhất sẽ làm cho hai quy tắc liên kết theo chiều dài. Đặt quy tắc COMMENT đầu tiên sẽ làm cho nó được sử dụng trong trường hợp của một tie.

0

Các đầu mối là:

Vấn đề là 'ăn bình luận' quy tắc này dường như không phù hợp với thẻ với hơn một ký tự

nên thêm một * để phù hợp với zero hoặc nhiều dòng mới hơn. Bạn muốn Zero nếu không một bình luận trống sẽ không khớp.

%x COMMENT 

//     { BEGIN(COMMENT); } 
<COMMENT>[^\n]*  ; 
<COMMENT>\n   { BEGIN(INITIAL); } 

"=="     { return EQUALEQUAL; } 

.      ; 
+0

Một bình luận trống sẽ không kích hoạt một kết hợp cho quy tắc đó, hoặc cũng không cần. – Darryl

+0

Đúng, đúng, dòng dưới đây bắt được nó. vì vậy bạn an toàn để thay đổi * thành + –