2012-02-28 33 views
8

Tôi đã làm việc với parsec và tôi gặp sự cố khi gỡ lỗi mã của mình. Ví dụ, tôi có thể thiết lập một breakpoint trong ghci, nhưng tôi không chắc chắn làm thế nào để xem có bao nhiêu đầu vào đã được tiêu thụ, hoặc những thứ như thế.Gỡ lỗi Parsec

Có các công cụ/nguyên tắc để giúp gỡ lỗi mã phân tích cú pháp không?

+2

Khi bạn chạy một phân tích cú pháp - nó sẽ trả về một 'Hoặc ParseError a' - in ParseError sẽ hiển thị bạn là vị trí nguồn và bất kỳ thông báo lỗi nào. Có đầu vào mẫu của bạn trong trình soạn thảo văn bản có lẽ là cách dễ nhất để xem vị trí nguồn tương ứng với, mặc dù bạn có thể viết hàm lỗi của riêng mình để nắm bắt phần còn lại của đầu vào và in nội dung ban đầu của nó ('getInput' trả về đầu vào còn lại). –

Trả lời

8

This trang có thể trợ giúp.

Debug.trace là bạn của bạn, cho phép bạn thực hiện một số sửa lỗi printf. Nó đánh giá và in đối số đầu tiên của nó và sau đó trả về giá trị thứ hai của nó. Vì vậy, nếu bạn có một cái gì đó giống như

foo :: Show a => a -> a 
foo = bar . quux 

Bạn có thể gỡ lỗi 'giá trị' của tham số foo bằng cách thay đổi foo như sau:

import Debug.Trace(trace) 

foo :: Show a => a -> a 
foo x = bar $ quux $ trace ("x is: " ++ show x) x 

foo bây giờ sẽ làm việc theo cách tương tự như nó đã làm trước đó, nhưng khi bạn gọi foo 1, bây giờ nó sẽ in x is: 1 thành tiêu chuẩn khi được đánh giá.

Để gỡ lỗi sâu hơn, bạn sẽ muốn sử dụng các lệnh gỡ lỗi của GHCI. Cụ thể, có vẻ như bạn đang tìm kiếm lệnh :force, điều này buộc đánh giá biến và in ra. (Giải pháp thay thế là lệnh :print, sẽ in nhiều biến số như đã được đánh giá, mà không đánh giá thêm nữa.)

hữu ích hơn trong việc tìm ra nội dung của biến, nhưng cũng có thể thay đổi ngữ nghĩa của chương trình của bạn (nếu chương trình của bạn phụ thuộc vào sự lười biếng).

Một vị tướng GHCI gỡ công việc trông giống như sau:

  • Sử dụng :break để đặt breakpoint
  • Sử dụng :list:show context để kiểm tra bạn đang ở đâu trong mã
  • Sử dụng :show bindings để kiểm tra các ràng buộc biến
  • Hãy thử sử dụng :print để xem những gì hiện đang bị ràng buộc
  • Sử dụng :force nếu cần thiết để kiểm tra các ràng buộc của bạn

Nếu bạn đang cố gắng để gỡ lỗi một vòng lặp vô hạn, nó cũng giúp sử dụng

  • :set -fbreak-on-error
  • :trace myLoopingFunc x y

Sau đó, bạn có thể nhấn Ctrl-C trong vòng lặp và sử dụng :history để xem vòng lặp là gì.

4

Bạn có thể sử dụng the <?> operator trong Text.Parsec.Prim để tạo các thông báo lỗi tốt hơn cho bạn và người dùng của bạn. Có một số examples trong thế giới thực Haskell. Nếu trình phân tích cú pháp của bạn có các phần con tốt thì bạn có thể thiết lập một vài thử nghiệm đơn giản (hoặc sử dụng HUnit) để đảm bảo chúng hoạt động riêng biệt như mong đợi.

+0

Vâng, tôi đoán tự do rắc ' 'có lẽ là tốt nhất tôi có thể làm. Hy vọng rằng sẽ có những công cụ được thiết kế đặc biệt để gỡ lỗi parsec. – Xodarap

0

Một lừa hữu ích:

_ <- many anyChar >>= fail này sẽ tạo ra một lỗi (Left) của:

unexpected end of input 
the remaining 'string'