2011-06-27 19 views
5

Vì vậy, tôi đang cố gắng để thực hiện một ngữ pháp khá đơn giản để báo cáo một dòng:Sự mơ hồ về ngữ pháp: tại sao? (Vấn đề là: "(a)" vs "(az)")

# Grammar 

    c   : Character c  [a-z0-9-] 
    (v)  : Vowel    (= [a,e,u,i,o]) 
    (c)  : Consonant 
    (?)  : Any character (incl. number) 
    (l)  : Any alpha char  (= [a-z]) 
    (n)  : Any integer  (= [0-9]) 
    (c1-c2) : Range from char c1 to char c2 
    (c1,c2,c3) : List including chars c1, c2 and c3 

    Examples: 
    h(v)(c)no(l)(l)jj-k(n) 
    h(v)(c)no(l)(l)(a)(a)(n) 
    h(e-g)allo 
    h(e,f,g)allo 
    h(x,y,z)uul 
    h(x,y,z)(x,y,z)(x,y,z)(x,y,z)uul 

Tôi đang sử dụng máy phát điện mừng phân tích cú pháp (http : //www.haskell.org/happy/) nhưng vì một số lý do có vẻ như có một số vấn đề mơ hồ.

Các thông báo lỗi là: "sự thay đổi/giảm xung đột: 1"

Tôi nghĩ rằng sự nhập nhằng là với hai dòng sau:

| lBracket char rBracket    { (\c -> case c of 
               'v' -> TVowel 
               'c' -> TConsonant 
               'l' -> TLetter 
               'n' -> TNumber) $2 } 
    | lBracket char hyphen char rBracket { TRange $2 $4    } 

Một trường hợp ví dụ là: "(a)" vs "(az)"

các lexer sẽ cung cấp sau đây cho hai trường hợp:

(a) : [CLBracket, CChar 'a', CRBracket] 
(a-z) : [CLBracket, CChar 'a', CHyphen, CChar 'z', CRBracket] 

Điều tôi không hiểu là làm thế nào điều này có thể mơ hồ với trình phân tích cú pháp LL [2].

Trong trường hợp nó giúp ở đây là toàn bộ hạnh phúc định nghĩa ngữ pháp:

{ 

module XHappyParser where 

import Data.Char 
import Prelude hiding (lex) 
import XLexer 
import XString 

} 

%name parse 
%tokentype { Character } 
%error  { parseError } 

%token 
    lBracket     { CLBracket } 
    rBracket     { CRBracket } 
    hyphen     { CHyphen  } 
    question     { CQuestion } 
    comma      { CComma  } 
    char      { CChar $$ } 

%% 

xstring : tokens       { XString (reverse $1)  } 

tokens : token        { [$1]      } 
     | tokens token      { $2 : $1     } 

token : char        { TLiteral $1    } 
     | hyphen        { TLiteral '-'    } 
     | lBracket char rBracket    { (\c -> case c of 
                'v' -> TVowel 
                'c' -> TConsonant 
                'l' -> TLetter 
                'n' -> TNumber) $2 } 
     | lBracket question rBracket   { TAny      } 
     | lBracket char hyphen char rBracket { TRange $2 $4    } 
     | lBracket listitems rBracket   { TList $2     } 

listitems : char       { [$1]      } 
      | listitems comma char   { $1 ++ [$3]    } 

{ 

parseError :: [Character] -> a 
parseError _ = error "parse error" 

} 

Cảm ơn bạn!

Trả lời

4

Dưới đây là sự nhập nhằng:

token : [...] 
     | lBracket char rBracket 
     | [...] 
     | lBracket listitems rBracket 

listitems : char 
      | [...] 

phân tích cú pháp của bạn có thể chấp nhận (v) như cả TString [TVowel]TString [TList ['v']], chưa kể đến các nhân vật mất tích trong đó case biểu.

Một cách có thể giải quyết nó là sửa đổi ngữ pháp của bạn để danh sách có ít nhất hai mục hoặc có ký hiệu khác cho nguyên âm, phụ âm, v.v.

+0

Cảm ơn ... đã giải quyết được sự cố (danh sách có một mục là vô ích trong trường hợp này, vì vậy tôi đã xóa chúng). Nhưng bạn có ý gì với tuyên bố trường hợp? – o1iver

+0

@ o1iver: Chỉ có bạn có thể muốn thêm trường hợp mặc định vào nó để xử lý các ký tự đơn không phải là một trong 'v, c,?, L, n' để báo hiệu lỗi có ý nghĩa hơn" Các mẫu không đầy đủ trong trường hợp biểu hiện". – hammar

+0

vâng tôi đã làm điều đó trước đây, nhưng tôi không chắc chắn. Tôi nghĩ rằng tôi sẽ chỉ ném một lỗi nếu điều đó xảy ra ... Mặc dù tôi đoán tôi sẽ phải có một cái nhìn tốt hơn về các tài liệu Happy liên quan đến xử lý lỗi nói chung! Cảm ơn một lần nữa ... – o1iver

3

Vấn đề có vẻ là:

| lBracket char rBracket 
... 
| lBracket listitems rBracket 

hoặc trong cú pháp sạch hơn:

(c) 

Có thể là một TVowel, TConsonant, TLetter, TNumber (như bạn đã biết) hoặc một singleton TList.

Như hướng dẫn sử dụng hạnh phúc, thay đổi giảm thường không phải là vấn đề. Bạn có thể ưu tiên cho chúng tôi để buộc hành vi/xóa cảnh báo nếu bạn muốn.

+0

Cảm ơn! Tôi đang nhìn nhầm chỗ. Vấn đề thực sự có vẻ là danh sách singleton so với các ký tự đặc biệt ("(v)", "(n)", v.v ...). Cảm ơn bạn! – o1iver