2012-05-07 27 views
13

Các tài liệu cho Parsec.Expr.buildExpressionParser nói:Parsec.Expr lặp đi lặp lại Prefix/Postfix điều hành không được hỗ trợ

Tiền tố và hậu tố các nhà khai thác trong những ưu tiên tương tự chỉ có thể xảy ra một lần (tức là --2 không được phép nếu - là tiền tố phủ nhận).

và thực sự, điều này đang cắn tôi, vì ngôn ngữ tôi đang cố gắng phân tích cho phép lặp lại tùy ý tiền tố và toán tử postfix (nghĩ biểu thức C như **a[1][2]).

Vì vậy, tại sao Parsec thực hiện giới hạn này và cách tôi có thể giải quyết vấn đề này?

Tôi nghĩ rằng tôi có thể di chuyển các trình phân tích tiền tố/mã bưu điện của mình xuống trình phân tích cú pháp term vì chúng có mức ưu tiên cao nhất.

tức

**a + 1 

được phân tách như

(*(*(a)))+(1) 

nhưng những gì có thể tôi đã làm nếu tôi muốn nó để phân tích như

*(*((a)+(1))) 

nếu buildExpressionParser đã những gì tôi muốn, tôi có thể chỉ đơn giản là sắp xếp thứ tự các toán tử trong bảng.

Note Xem here cho một giải pháp tốt hơn

Trả lời

13

Tôi giải quyết nó bản thân mình bằng cách sử dụng chainl1:

prefix p = Prefix . chainl1 p $ return  (.) 
postfix p = Postfix . chainl1 p $ return (flip (.)) 

Những combinators sử dụng chainl1 với một phân tích cú pháp op luôn thành công, và chỉ cần soạn các chức năng quay trở lại bởi trình phân tích cú pháp term theo thứ tự từ trái sang phải hoặc từ phải sang trái. Chúng có thể được sử dụng trong bảng buildExprParser; nơi bạn sẽ đã làm điều này:

exprTable = [ [ Postfix subscr 
       , Postfix dot 
       ] 
      , [ Prefix pos 
       , Prefix neg 
       ] 
      ] 

bây giờ bạn làm điều này:

theo cách này, buildExprParser vẫn có thể được sử dụng để thiết lập điều hành được ưu tiên, nhưng bây giờ chỉ nhìn thấy một đơn Prefix hoặc Postfix điều hành tại mỗi ưu tiên. Tuy nhiên, toán tử đó có khả năng slurp lên nhiều bản sao của chính nó như nó có thể, và trả về một hàm làm cho nó trông như thể chỉ có một toán tử duy nhất.

+0

Tôi thấy câu trả lời của bạn cực kỳ hữu ích, nhưng tôi đã gặp phải một vấn đề khác, chi tiết [ở đây] (http://stackoverflow.com/questions/11174775) và tôi đánh giá cao nếu bạn có thể xem, trên cơ hội bạn có một giải pháp. –

+0

Cảm ơn câu trả lời hữu ích. Tôi đang gặp một chút khó khăn với sự khái quát hóa vấn đề này. Nếu bạn có bất kỳ đề xuất nào, chúng sẽ rất được hoan nghênh (xem http://stackoverflow.com/questions/33214163/parsec-expr-repeated-prefix-with-different-priority/33217888#33217888) – BartBog

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