2015-04-11 13 views
5

Bất cứ khi nào tôi gọi yyparse() với một tệp hợp lệ, tôi nhận được lỗi seg là có vẻ là gây ra bởi dòng này (khoảng dòng 1789) mã:Trình phân tích cú pháp được tạo bởi GNU Bison ném lỗi phân đoạn 11 khi được cung cấp một tệp không rỗng

if (yyss + yystacksize - 1 <= yyssp){ 

Tôi đã đến kết luận này bằng cách in thông báo gỡ lỗi trước và sau dòng mã này. Các tin nhắn trước khi dòng này được in nhưng những dòng sau dòng này thì không.

Điều lạ lùng là nếu tôi gọi yyparse() với một tệp trống, lỗi không được ném nhưng nó được ném nếu tệp có ít nhất một ký tự trong đó.

Bản thân trình phân tích cú pháp đã được biên dịch mà không có bất kỳ lỗi nào. Điều gì có thể là lý do/s đằng sau lỗi seg này?

Các tập tin phân tích cú pháp: https://gist.github.com/SamTebbs33/bffb72517f174af679ef

gỡ lỗi mã tin nhắn:

cout << "before if" << endl; 
if (yyss + yystacksize - 1 <= yyssp){ 
    cout << "after if" << endl; 
    cout.flush(); 

Thông điệp debug đầu tiên được in 3 lần trước khi lỗi được ném.

Edit: Các lỗi thực sự bị ném trong câu lệnh switch khi 55 mã thông báo là phù hợp trong yyreduce nhãn:

case 55: 
    #line 219 "grammar/grammar.y" /* yacc.c:1661 */ 
    { 
    cout << "processing token 55" << endl; 
    (yyval.id) = new TIdentifier(*(yyvsp[0].string)); 
    cout << "processed token 55" << endl; 
    } 
    #line 2228 "grammar/parser.cpp" /* yacc.c:1661 */ 
    break; 

Trước câu lệnh switch được đạt tới, tôi in các giá trị số nguyên của biến được chuyển đổi và giá trị của nó là 55, do đó mã sai phải nằm trong mã trên, vì "mã thông báo được xử lý 55" không được in nhưng "mã thông báo xử lý 55" được in. Dưới đây là mã cho TIdentifier constructor:

TIdentifier(std::string name) : name(name) { 
} 

Điều này có nghĩa rằng lỗi phải được tạo ra khi dereferencing (yyvsp[0].string)

+1

Không có lý do gì (tôi có thể nghĩ) số học con trỏ và so sánh có thể gây ra lỗi phân đoạn. Có lẽ bạn có thể chạy chương trình thông qua 'valgrind' để biết thêm chi tiết về cách nó thất bại. – Diego

+1

Khó tin rằng dòng gây ra lỗi seg. Bạn đã fflush() đầu ra hoặc chạy nó trong gdb? –

+1

Bạn có sử dụng 'endl' ở cuối mỗi' cout' không?Nếu không, hãy xem xét đầu ra bạn nhìn thấy khi bạn nhận được lỗi seg có thể sai, như một cái gì đó vẫn còn trong bộ đệm, chờ đợi để được in cho thực, nhưng sau đó chương trình bị treo và những dòng không bao giờ được in. Nói cách khác: nếu bạn không chắc chắn xóa bộ đệm thì có thể chương trình của bạn đã bị treo ** sau ** dòng bạn đã xác định. Sau bao nhiêu, rất khó để nói, nhưng chỉ sử dụng 'endl' và bạn sẽ biết nó thực sự ở đâu. –

Trả lời

0

(Answered by the OP in a question edit. Converted to a community wiki answer, which is more appropriate to the Q&A format of StackOverflow).

Các OP đã viết:

Sau khi gỡ lỗi hơn nữa, tôi đã nhận ra rằng ngữ pháp flex của tôi đã không được lưu chuỗi tìm thấy trong các tập tin như mong muốn và đã cố gắng để truy cập vào một yếu tố không tồn tại trong yylval và trình phân tích cú pháp hiện hoạt động!

Tuy nhiên, nó sẽ tốt hơn rằng các tài liệu corect đã được đưa vào câu hỏi như ghi nhận của @rici:

Nó sẽ hữu ích hơn (hoặc ít nhất là dễ dàng hơn) để xem đầu vào bò rừng bizon của bạn tệp (.y), chứ không phải là trình phân tích cú pháp được tạo.

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