2011-06-25 14 views
16

Tôi đang phân tích một biểu thức bằng Parsec và tôi muốn theo dõi các biến trong các biểu thức này bằng cách sử dụng trạng thái người dùng trong Parsec. Thật không may tôi không thực sự có được làm thế nào để làm điều đó.Trạng thái người dùng trong Parsec

Với đoạn mã sau:

import Data.Set as Set 
inp = "$x = $y + $z" 

data Var = V String 

var = do char '$' 
     n <- many1 letter 
     let v = Var n 
     -- I want to modify the set of variables here 
     return v 

parseAssignment = ... -- parses the above assignment 

run = case runIdentity $ runParserT parseAssignment Set.empty "" inp of 
        Left err -> ... 
        Right -> ... 

Vì vậy, u trong ParsecT s u m a sẽ Set.Set. Nhưng làm thế nào tôi sẽ tích hợp cập nhật trạng thái vào var?

Tôi đã thử một cái gì đó như modify $ Set.insert v, nhưng điều này không hiệu quả, vì Set.Set không phải là một đơn vị trạng thái.

Trả lời

16

Thật không may, Yuras' đề nghị của updateParserState không phải là tối ưu (bạn muốn sử dụng chức năng nếu bạn đang tìm kiếm để sửa đổi trạng thái nội Parsec của cũng); thay vào đó bạn phải vượt qua một chức năng hoạt động trên trạng thái người dùng tùy chỉnh của bạn (ví dụ: các loại u -> u) để modifyState, chẳng hạn như trong ví dụ này:

expr = do 
    x <- identifier 
    modifyState (+1) 
    --^in this example, our type u is Int 
    return (Id x) 

hoặc sử dụng bất kỳ sự kết hợp của các chức năng getStateputState. Trong trường hợp của bạn, bạn sẽ làm điều gì đó như:

modifyState (Set.insert v) 

Xem this link để biết thêm thông tin.

Để có thêm phần giới thiệu giống như hướng dẫn để làm việc với trạng thái người dùng trong Parsec, this document, mặc dù cũ, phải phù hợp.

+0

Cảm ơn! Đó là chính xác những gì tôi cần - có thể đã nhìn vào chức năng đó trước đó ... Tôi bằng cách nào đó nghĩ modifyState có liên quan đến sửa đổi từ Control.Monad.State. – bzn

+0

@ bzn: Nó có liên quan, mặc dù! Nếu bạn nghĩ rằng Parsec là một nhà nước duy nhất chỉ giữ trạng thái người dùng, họ cũng làm như vậy. Chúng chỉ khác nhau vì 'modifyState' bỏ qua trạng thái bên trong của Parsec. –

1

Bạn có thể sử dụng updateParserState

+0

cảm ơn, hoạt động, nhưng như Raeez Lorgat đã nói, modifyState có vẻ là hàm tôi cần. – bzn