2011-06-27 19 views
5

तो मैं एक पंक्ति का बयान के लिए एक बहुत सरल व्याकरण को लागू करने की कोशिश कर रहा हूँ:व्याकरण अस्पष्टता: क्यों? (समस्या है: "(क)" बनाम "(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 

मैं खुश पार्सर जेनरेटर का उपयोग कर रहा (http : //www.haskell.org/happy/) लेकिन किसी कारण से कुछ अस्पष्टता समस्या प्रतीत होती है।

त्रुटि संदेश है: "पाली/संघर्ष को कम करने: 1"

मुझे लगता है कि अस्पष्टता इन दो पंक्तियों के साथ है:

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

एक उदाहरण मामला है: "(क)" बनाम "(AZ)"

lexer देना होगा दो मामलों के लिए निम्नलिखित:

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

जो मुझे समझ में नहीं आता है यह है कि यह एलएल [2] पार्सर के साथ संदिग्ध कैसे हो सकता है।

{ 

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" 

} 

धन्यवाद:

मामले इसे यहाँ मदद करता है में पूरी की शुभकामनाएं व्याकरण परिभाषा है!

उत्तर

4

यहाँ अस्पष्टता है:

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

listitems : char 
      | [...] 

आपका पार्सर (v)TString [TVowel] और TString [TList ['v']] दोनों के रूप में स्वीकार कर सकता है, न कि case अभिव्यक्ति में लापता पात्रों का उल्लेख।

आदि, को सुलझाने इसे अपने व्याकरण को बदलें ताकि सूचियों कम से कम दो आइटम हैं, या स्वर, व्यंजन के लिए कुछ अलग अंकन किया जाएगा

+0

धन्यवाद ... जिसने समस्या हल की है (वैसे भी एक आइटम के साथ सूचियां इस मामले में बेकार हैं, इसलिए मैंने उन्हें हटा दिया)। लेकिन केस स्टेटमेंट के साथ आपका क्या मतलब है? – o1iver

+0

@ o1iver: केवल वही अक्षर जो आप 'v, c,?, L, n' में से एक नहीं हैं, को संभालने के लिए एक डिफ़ॉल्ट केस जोड़ना चाहते हैं, "मामले में गैर-संपूर्ण पैटर्न की तुलना में अधिक अर्थपूर्ण त्रुटि सिग्नल करने के लिए अभिव्यक्ति "। – hammar

+0

हाँ मेरे पास पहले ऐसा था, लेकिन मुझे यकीन नहीं था। मुझे लगता है कि अगर ऐसा होता है तो मैं सिर्फ एक त्रुटि फेंक दूंगा ... हालांकि मुझे लगता है कि मुझे सामान्य रूप से त्रुटि प्रबंधन से संबंधित हैप्पी दस्तावेज़ों पर एक बेहतर नज़र रखना होगा! एक बार फिर धन्यवाद... – o1iver

3

समस्या लगती है:

| lBracket char rBracket 
... 
| lBracket listitems rBracket 

या क्लीनर वाक्य रचना में:

(c) 

एक TVowel, TConsonant, TLetter, TNumber (जैसा कि आप जानते) या एक सिंगलटन TList हो सकता है।

जैसा कि खुश मैनुअल कहता है, शिफ्ट कम करना आमतौर पर कोई मुद्दा नहीं है। यदि आप चाहें तो चेतावनी को नियंत्रित करने/चेतावनी को हटाने के लिए आप हमें प्राथमिकता दे सकते हैं।

+0

धन्यवाद में से एक संभव तरीका! मैं गलत जगह पर देख रहा था। समस्या वास्तव में सिंगलटन सूची विशेष वर्ण ("(v)", "(n)", आदि ... बनाम प्रतीत होती है)। धन्यवाद! – o1iver