F #

2011-03-09 11 views
9

में पार्सिंग के दौरान त्रुटियों को कैसे संभालें I F FXer और Parser के लिए fslex/fsyacc उपयोगिताओं का उपयोग कर रहा हूं। यदि इनपुट टेक्स्ट में गलत वाक्यविन्यास है, तो यह जानना जरूरी है कि यह कहां होता है।F #

यह Lexer में गलत शब्दिम (टोकन) का निर्धारण और यदि यह गलत प्रतीक या शब्द इस्तेमाल किया गया था एक अपवाद फेंकने के लिए संभव है:

rule token = parse 
      ...  
    | integer { INT (Int32.Parse(lexeme lexbuf)) } 
    | "*="  { failwith "Incorrect symbol" } 
    | eof  { EOF } 

सवाल पार्सर (fsyacc) के लिए और अधिक संबंधित है - अगर इनपुट पाठ सही टोकन हैं और Lexer द्वारा sucessfuly टोकननाइज्ड किया गया था, लेकिन पार्सिंग के दौरान त्रुटि हुई (उदाहरण के लिए, गलत टोकन ऑर्डर या नियम में कुछ अनुपस्थित टोकन)

मुझे पता है कि अपवाद पकड़ते हैं, यह स्थिति (रेखा और कॉलम) देता है, जहां पार्सिंग विफल:

try 
    Parser.start Lexer.token lexbuf 
with e -> 
    let pos = lexbuf.EndPos 
    let line = pos.Line 
    let column = pos.Column 
    let message = e.Message // "parse error" 
    ... 

लेकिन क्या यह संभव है (यदि हाँ - यह कैसे करें?) भी एएसटी कक्षा निर्धारित करने के लिए, जिसके लिए पार्सिंग विफल रही।

उदाहरण के लिए यह मेरे parser.fsy फ़ाइल में निम्न जैसा कुछ लिखने के लिए संभव है:

Expression1: 
    | INT   { Int $1 } 
    ... 
    | _   { failwith "Error with parsing in Expression1"} 

उत्तर

9

बस संघर्ष "_" एक बदलाव के लिए नेतृत्व चाहिए/कम करने लंघन। टोकन के एक छोटे से सेट के लिए, आप उन्हें सभी सूचीबद्ध कर सकते हैं। टोकन के एक बड़े सेट के लिए, यह अधिक समस्याग्रस्त है।

एफ # संकलक पहले नियमों का उपसर्गों को परिभाषित करते हुए कुछ ऐसा ही है, और एक त्रुटि राज्य सेट:

atomicPattern: 
    ... 
    | LPAREN parenPatternBody RPAREN 
     { let m = (lhs(parseState)) in SynPat.Paren($2 m,m) } 
    | LPAREN parenPatternBody recover 
     { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnmatchedParen()); $2 (rhs2 parseState 1 2) } 
    | LPAREN error RPAREN 
     { (* silent recovery *) SynPat.Wild (lhs(parseState)) } 
    | LPAREN recover 
     { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnmatchedParen()); SynPat.Wild (lhs(parseState))} 

recover: 
    | error { true } 
    | EOF { false } 

आप the repository में पूरी फ़ाइल देख सकते हैं। ocamlyacc/fsyacc में से निपटने त्रुटि पर

अधिक जानकारी OCaml manual (भाग III → Lexer और पार्सर जनरेटर → त्रुटि निवारण) में पाया जा सकता है।

+0

आपके उत्तर के लिए धन्यवाद - यह बहुत कुछ देता है। मेरे कोड – Vitaliy

+0

में समाधान जोड़ने का प्रयास कर रहे दोनों समाधान (रिक्त टोकन वाले नियमों में कुंजी और पुनर्प्राप्ति के साथ उदाहरण) मेरे लिए काम करता है, इसलिए फिर से धन्यवाद। मैं जवाब स्वीकार कर रहा हूँ – Vitaliy

संबंधित मुद्दे

 संबंधित मुद्दे