के लिए व्याकरण उलटे पांव लौटने के साथ पुनरावर्ती वंश पार्सर


10

कर सकते हैं किसी को समझाने के लिए मुझे क्यों कि उलटे पांव लौटने के साथ एक पुनरावर्ती वंश पार्सर की कोशिश करता है प्रस्तुतियों और एस एक एक (इसी क्रम में) व्याकरण द्वारा गठित भाषा को मान्यता नहीं देता एस एक एस एक | एक एकSaSaSaaSaSa | aa

यह केवल भाषा से शब्दों को पार्स करने के लिए प्रकट होता है {a2n | n1}

मैंने उत्पादन नियम के साथ इस एबीएनएफ पार्सर जेनरेटर का उपयोग करके इस तरह के पार्सर को उत्पन्न किया S = "a" S "a" / "aa"और पार्सर शब्द को पहचान नहीं पाता है aaaaaa, उदाहरण के लिए।

मैं यह उत्पादन का उपयोग करने के उम्मीद करेंगे जब तक 7 के साथ शुरू होता है बाएं से पार्स पेड़ के टर्मिनल नोड्स के संयोजन की, और फिर पार्स पेड़ ऊपर जाना उत्पादन चुनने एस एक एक के बजाय पेड़ दिखता है जब तक इस तरह:SaSaaSaa

   S 
 / | \
a  S  a
 / | \
a  S  a
  / \
 a   a

2
आपको क्या लगता है कि यह इस शब्द को पार्स नहीं कर सकता है?
युवल फिल्मस

@ यवुवल, मुझे लगता है कि उसे इसे पार्स करना चाहिए, इसलिए मुझे कुछ याद नहीं करना चाहिए।
विलय

आह, अब यह प्रश्न और अधिक समझ में आता है; संपादन के लिए धन्यवाद! यदि आप जो लिखते हैं वह सच है (मैंने जांच नहीं की) जनरेटर में बग है। (या यह आपके व्याकरण के लिए निर्दिष्ट नहीं है; मुझे लगता है कि यह संभावना नहीं है क्योंकि व्याकरण प्राथमिक और अस्पष्ट है।
राफेल

@ राफेल, मैंने प्रश्न को फिर से संपादित किया (उम्मीद है कि अर्थ बदले बिना)। मुझे वास्तव में यह समझाने का काम सौंपा जाता है कि ऐसे पार्सर शब्द को क्यों नहीं पहचानते हैं aaaaaa
विलय

वह पेड़ आपको कहां से मिला। मुझे उस ABNF पार्सर जनरेटर से बहुत कुछ नहीं मिलता है। आप जो पेड़ देते हैं, वह बहुत मायने नहीं रखता है। लेकिन स्ट्रिंग aaaaaaको पार्स करना चाहिए और नहीं करना चाहिए। लेकिन aaaaपार्स करता है। आप स्पष्ट रूप से 2 की शक्तियों के बारे में सही हैं। इस बात को कम करना चाहिए। यह केवल aaसाथ देता है S = "aa" / "a" [S] "a"। क्या आप पता लगा सकते हैं कि पार्सर क्या करता है?
बाबू

जवाबों:


6

यह बहुत जवाब नहीं है, लेकिन पार्स के पेड़ सामान्य टिप्पणियों के अनुरूप नहीं हैं।

SaSa | aaaaaaaa

लेकिन तोते के पेड़ के निम्नलिखित रूप हैं:

      S 
     /|\
    / S \
   / /|\ \
  / / S \ \
 / / / \ \ \
a a a   a a a

या यदि आप इस प्रस्तुति को पसंद करते हैं, तो विभिन्न लाइनों पर टर्मिनलों के साथ

     S 
   / | \
  a  S  a
   / | \
  a  S  a
    / \
   a   a

मैंने जाँच की कि ABNF पार्सर जनरेटर काम नहीं करता है, लेकिन मुझे नहीं पता कि यह कैसे पता लगाता है।

{a2n | n1}

छोटी गाड़ी के पार्सर के आसपास ऐसी विस्तृत साइट होना थोड़ा आश्चर्य की बात है, जो पूरी तरह से निर्बाध पार्स तकनीक का उपयोग करती है।


इसके बाद आगे देखें:

मुझे लगता है कि मुझे समस्या का एक स्रोत मिला। वर्गाकार कोष्ठक का अर्थ है वैकल्पिक

तो अपने व्याकरण लिखा जाना चाहिए या तो S = "a" S "a" / "aa" या S = "a" [S] "a"। तब यह सही ढंग से काम करने लगता है।

लेकिन अलग-अलग रूपों में दो बार एक ही नियम होने पर प्रणाली स्पष्ट रूप से खो जाती है। मुझे यकीन नहीं है कि क्यों

मुझे व्याकरण को निर्दिष्ट करने के लिए इन वाक्यात्मक मुद्दों को समझाने वाला पृष्ठ नहीं मिला।

मैं अभी भी उस छोटी गाड़ी पर विचार करता हूं।


1
आउच। हाँ। मुझे नहीं पता कि मैं क्या सोच रहा था जब मैंने उस पार्स ट्री को लिखा था। मैं अपना प्रश्न संपादित करूंगा और तुम्हारा पेस्ट करूंगा।
विलय

मैं एक पुनरावर्ती वंश मिला, डेमो एक साथ पार्सर जेनरेटर उलटे पांव लौटने ऑनलाइन यहाँ और यह इस नियम के साथ समान व्यवहार दिखाता है:S ::= 'a'<S>'a' | 'a''a'
meribold

यह अभी भी aaaaaaउपयोग करते समय पार्स नहीं करता है S = "a" S "a" / "aa", लेकिन आपको कोष्ठक के बारे में सही लगता है।
विलय

मैं पुनरावर्ती वंश की खोज करने के बिंदु को नहीं देखता, पीछे हटने वाला पार्सर।
बाबू

आप सही हैं S = "a" S "a" / "aa"... मैंने बहुत तेज़ी से परीक्षण किया, और पार्स के बजाय जेनरेट पर क्लिक किया।
बाबू

3

s1()SaSatrues()s2()Saa

शब्द पर aaaaaaदोबारा विचार करने पर विचार करें। एक बिंदु पर, पार्स पेड़ इस तरह दिखेगा:

   S 
 / | \
a  S  a
 / | \
a  S  a    <--
 / | \
a  S  a
  / \
 a   a

s()trueSSaa

   S 
 / | \
a  S  a
  / \
 a   a

मैं अपने कार्यान्वयन के साथ इस मुद्दे पर विचार करता हूं और सामान्य रूप से पुनरावर्ती वंश पार्सर को पीछे नहीं छोड़ता।

#include <iostream>

char* next;    
bool term(char token) {
    if (*next != '\0')
        return *next++ == token;
    else
        return false;
}

bool s();    
bool s1() {
    return term('a') && s() && term('a');
}    
bool s2() {
    return term('a') && term('a');
}    
bool s() {
    auto save = next;
    return s1() or (next = save, s2());
}    

int main(int argc, char* argv[]) {
    next = "aaaaaa";
    if (s() && *next == '\0') {
        std::cout << "match";
    }
    else
        std::cout << "no match";
}

2

यह एक बग नहीं एक सुविधा है

बैकट्रैकिंग कब और कहाँ होती है, इस पर करीब से नज़र डालें:

     1.           2.          3.          4.          5.          6.          7.          8.          9.          10.         11.         12.

     S            S           S           S           S           S           S           S           S           S           S           S      
   / | \        / | \       / | \       / | \       / | \       / | \       / | \       / | \       / | \       / | \       / | \       / | \
  a  S  a      a  S  a     a  S  a     a  S  a     a  S  a     a  S  a     a  S  a     a  S  a     a  S  a     a  S  a     a  S  a     a  S  a
                / | \       / | \       / | \       / | \       / | \       / | \       / | \       / | \       / | \       / | \       /   \
               a  S  a     a  S  a     a  S  a     a  S  a     a  S  a     a  S  a     a  S  a     a  S  a     a  S  a     a  S  a     a     a
                            / | \       / | \       / | \       / | \       / | \       / | \       / | \       / | \       / | \
                           a  S  a     a  S  a     a  S  a     a  S  a     a  S  a     a  S  a     a  S  a     a  S  a     a  S  a
                                        / | \       / | \       / | \       / | \       / | \       / | \       / | \       /   \
                                       a  S  a     a  S  a     a  S  a     a  S  a     a  S  a     a  S  a     a  S  a     a     a
                                                    / | \       / | \       / | \       / | \       / | \       /   \
                                                   a  S  a     a  S  a     a  S  a     a  S  a     a  S  a     a     a
                                                                / | \       / | \       / | \       /   \   
                                                               a  S  a     a  S  a     a  S  a     a     a
                                                                            / | \       /   \
                                                                           a  S  a     a     a



w[] = 'aaaaaa'  //input
l[] = ''        //current tree leafs


 1. tree:   The parser starts with the start symbol S and tries first alternative S->aSa:       Result: w[0]  = l[0]     w = aaaaaa    l = aSa
 |          -- S->aSa works                                                                         | |     | | 
 6. tree:   The parser matches a after a:                                                       Result: w[6]  = l[6]     w = aaaaaa    l = aaaaaaSaaaaaa
 7. tree:   The parser tries S->aSa again but there is no match!                                Result: w[7] != l[7]     w = aaaaaa    l = aaaaaaaSaaaaaaa 
 8. tree:   The parser tries S->aa but there is still no match!                                 Result: w[7] != l[7]     w = aaaaaa    l = aaaaaaaaaaaaaa
 9. tree:   Backtracking after the last symbol that matched => Backtracking at l[7]             Result: w[7] != l[7]     w = aaaaaa    l = aaaaaaaaaaaa
10. tree:   Backtracking after the last symbol that matched => Backtracking at l[7]             Result: w[7] != l[7]     w = aaaaaa    l = aaaaaaaaaa
11. tree:   Backtracking after the last symbol that matched => Backtracking at l[7]             Result: w[7] != l[7]     w = aaaaaa    l = aaaaaaaa
12. tree:   Backtracking after the last symbol that matched => Backtracking at l[7]             Result: w[7] != l[7]     w = aaaaaa    l = aaaa

यहाँ महत्वपूर्ण बिंदु यह है कि पार्सर स्थिति के बाद पीछे हट जाता है, जहां अंतिम मिलान वर्ण पाया गया था। इसीलिए यह पेड़ से 11 से l = आआआआआआआ आआआआआआ आआआआआआआआआआआआआआआआआआआआआआआआआआआआआआआआआआआआआ करके, साथ में आआआआआआआआआआआआआआआआआआआआआआआआआआआ करता है कि , मैं आ - आआआआ आआआआआआआआआआआआआआआआआआसससससस से लेकर - एस आआआआआआम एल [7] करके l = आआआआआआआआ


अंत में इसे संपादित करने का समय मिला! ;)
सेबबस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.