Tôi đang cố gắng để phân tích bình luận C-style đa dòng trong flex của tôi (.l) file:Tại sao các nhận xét nhiều dòng trong flex/bison lại dễ dàng như vậy?
%s ML_COMMENT
%%
...
<INITIAL>"/*" BEGIN(ML_COMMENT);
<ML_COMMENT>"*/" BEGIN(INITIAL);
<ML_COMMENT>[.\n]+ { }
Tôi không trả lại bất kỳ dấu hiệu và ngữ pháp của tôi (.y) không đề cập đến ý kiến bằng mọi cách.
Khi tôi chạy thực thi của tôi, tôi nhận được một lỗi phân tích cú pháp:
$ ./a.out
/*
abc
def
Parse error: parse error
$ echo "/* foo */" | ./a.out
Parse error: parse error
(chức năng yyerror My hiện một printf ("Parse error:% s \ n"), là nơi mà các nửa đầu thông báo lỗi dư thừa xuất phát từ).
Tôi có thể thấy lý do tại sao ví dụ thứ hai không thành công do toàn bộ dữ liệu nhập là nhận xét và vì các chú thích bị bỏ qua bởi ngữ pháp, không có câu lệnh nào. Do đó đầu vào không phải là một chương trình hợp lệ. Nhưng phần đầu tiên ném lỗi phân tích cú pháp trước khi tôi hoàn thành nhận xét.
Cũng khó hiểu:
$ ./a.out
/* foo */
a = b;
Parse error: parse error
Trong trường hợp này, những nhận xét được đóng trước khi đầu vào có giá trị thực tế (trong đó, nếu không có sự bình luận, phân tích tốt). Sự thất bại thực sự xảy ra sau khi phân tích cú pháp "a", không phải sau khi cố gắng phân tích cú pháp nhiệm vụ "a = b;". Nếu tôi nhập "a" trên dòng riêng của nó, nó vẫn ném một lỗi.
Cho rằng thông báo lỗi là lỗi phân tích cú pháp và không phải là lỗi máy quét, có điều gì đó quan trọng mà tôi bị thiếu trong tệp .y của mình không? Hoặc tôi đang làm điều gì đó sai trái trong các quy tắc của tôi quét mà truyền bá sang phía phân tích cú pháp?
EDIT: mỗi @ đề nghị Rudi, tôi bật gỡ lỗi và tìm thấy:
$ ./a.out
Starting parse
Entering state 0
Reading a token: /*
foo
Next token is 44 (IDENTIFER)
Shifting token 44 (IDENTIFER), Entering state 4
Reducing via rule 5 (line 130), IDENTIFER -> identifier
state stack now 0
Entering state 5
Tôi tắt gỡ lỗi và phát hiện ra rằng /* foo */ = bar;
thực sự phân tích giống như foo = bar;
. Tôi đang sử dụng flex 2.5.4; nó không cho tôi bất kỳ cảnh báo nào về các quy tắc nhà nước mà tôi đang cố gắng sử dụng.
Tôi đã gắn lại flex thành gnu-flex. Quy tắc máy quét của bạn trông ổn. Lỗi phân tích cú pháp cho biết đầu vào mã thông báo không hợp lệ cho trình phân tích cú pháp. Bạn có thể muốn đăng một số quy tắc Bison tương ứng. Ngoài ra, bạn nên đặt các câu lệnh printf() bên trong các quy tắc bison của bạn, theo cách này bạn có thể thấy những gì mà trình phân tích cú pháp đang thử trong quá trình quét mã thông báo. – Kizaru
Bạn cũng nên tạo một bộ kiểm tra riêng cho máy quét của mình. Bằng cách đó bạn có thể tách biệt các lỗi máy quét khỏi các lỗi phân tích cú pháp. Bất kỳ hệ thống trình phân tích cú pháp nào cũng đủ phức tạp đến mức bạn không cần phải chèn thêm độ phức tạp bằng cách thực hiện kiểm tra tích hợp khi bạn thực sự muốn thực hiện kiểm tra đơn vị ... – bstpierre
Khi bạn thêm cờ '--debug' vào bison của bạn gọi và đặt 'yydebug = 1' trước cuộc gọi' yyparse() ', khi đó trình phân tích cú pháp phát ra thông tin gỡ lỗi cho mỗi mã thông báo mà nó thấy từ lexer. – Rudi