2012-10-03 29 views
6

मैं एक साधारण मार्कअप भाषा बनाने के लिए जेसन (बाइसन) का उपयोग कर रहा हूं। मैं इसके लिए स्पष्ट रूप से नया हूं, लेकिन मामूली बदलाव बहुत अच्छी तरह से काम कर रहे हैं। मैं बस एस/आर संघर्ष के स्रोत को समझ में नहीं आता।व्याकरण का हल शिफ्ट/संघर्ष को कम करने

यह कोई फर्क नहीं पड़ता कि 'टेक्स्ट' दो लेजर क्रियाओं (विभिन्न प्रारंभ शर्तों के साथ) द्वारा वापस किया जाता है और मुझे यह पसंद है क्योंकि ऐसा लगता है कि व्याकरण के पास कम नियम हैं और क्योंकि उपयोगकर्ता को त्रुटि संदेश हैं संगत। मैंने संदर्भ के बावजूद 'टेक्स्ट' नियम को आम बनाने की कोशिश की है और मैंने प्रत्येक टोकन को एक अलग नाम देने का भी प्रयास किया है, लेकिन ऐसा लगता है कि यह सब एक साथ होने पर एस/आर संघर्षों पर कोई प्रभाव नहीं पड़ता है।

पार्सर को सादे-पाठ, उप-सरणी और विभिन्न विशेष नोड्स के साथ एक जेसन-ऑब्जेक्ट बनाने के लिए तैयार किया गया है।

विशिष्टता:

/* lexical grammar */ 
%lex 

%s bracketed 

%% 

<bracketed>(\\.|[^\\\,\[\]])+  { yytext = yytext.replace(/\\(.)/g, '$1'); return 'Text'; } 
<INITIAL>(\\.|[^\\\[])+    { yytext = yytext.replace(/\\(.)/g, '$1'); return 'Text'; } 
"["         { this.begin('bracketed'); return '['; } 
"]"         { this.popState(); return ']'; } 
","         return ',' 
<<EOF>>        return 'END' 

/lex 

%start template 

%%  

template 
    : sentence END 
    ; 

sentence 
    : /* empty */ 
    | sentence Text 
    | sentence '[' ']' 
    | sentence '[' dynamic ']' 
    ; 

dynamic 
    : sentence 
    /*| dynamic ',' sentence*/ 
    ; 

चेतावनियाँ:

Conflict in grammar: multiple actions possible when lookahead token is ] in state 5 
- reduce by rule: sentence -> 
- shift token (then go to state 6) 

States with conflicts: 
State 5 
    sentence -> sentence [ .] #lookaheads= END Text [ ] 
    sentence -> sentence [ .dynamic ] #lookaheads= END Text [ ] 
    dynamic -> .sentence #lookaheads= ] 
    sentence -> . #lookaheads= ] Text [ 
    sentence -> .sentence Text 
    sentence -> .sentence [ ] 
    sentence -> .sentence [ dynamic ] 

विभिन्न जनरेटर एल्गोरिदम कम या ज्यादा परेशानी है, लेकिन वे सभी मुसीबत है लगता है।

धन्यवाद!

उत्तर

14

संघर्ष इन दो नियमों से मौलिक रूप से आता है:

sentence: sentence '[' Text ']' 
     | sentence '[' sentenceList ']' 

कारण रहा है जो किसी sentence और एक [ देखकर और अगले टोकन Text जा रहा है देखने के बाद, पार्सर में जाना जाता है नहीं है शिफ्ट करने के लिए है कि क्या Text, पहले नियम से मिलान करना, या Text का इलाज sentenceList की शुरुआत के रूप में दूसरे नियम से मेल खाने की दिशा में जा रहा है।

अब यदि आपके पास एक पार्सर जेनरेटर है जो 2-टोकन लुकहेड का उपयोग करता है, तो यह कोई समस्या नहीं होगी, लेकिन बाइसन एलएएलआर (1) (1 एक टोकन लुकहेड है)।

वहाँ रहे हैं चीजों के एक जोड़े आप की कोशिश कर सकते:

  • lexer में अतिरिक्त अग्रदर्शी कर पाठ का पालन-दर-] से पाठ से नहीं-पीछा-दर-] के रूप में दो अलग-अलग टोकन अंतर करने के लिए फिर इन दोनों टोकन का उपयोग करने के लिए नियमों को फिर से लिखें।

  • जीएलआर पार्सर का उपयोग करने के लिए बाइसन की% glr-parser सुविधा का उपयोग करें। यह दोनों तरीकों से वाक्य को पर्स करेगा और बाद में

  • व्याकरण को दो-टोकन लुकहेड की आवश्यकता नहीं है।

एक रिफैक्टरिंग कि आपके मामले में काम करता है sentence नियम के पुनर्लेखन के लिए उन्हें बनाने के लिए किया जाएगा सब ठीक पुनरावर्ती बजाय बाएं पुनरावर्ती:

sentence: /* empty */ 
     | Text sentence 
     | '[' ']' sentence 
     | '[' Text ']' sentence 
     | '[' sentenceList ']' sentence 
     ; 

यह sentence होने से बचा जाता है (या किसी अन्य नियम जो sentence जैसे sentenceList से शुरू होता है) sentence: /*empty*/ नियम की शून्य कमी के साथ शुरू होता है। तो पार्सर समस्याग्रस्त मामले में Text को स्वतंत्र रूप से स्थानांतरित कर सकता है जब तक कि यह अगले टोकन को तब तक कम न हो।इसमें स्मृति उपयोग के प्रभाव होते हैं, हालांकि, इसके परिणामस्वरूप एक पार्सर होता है जो अनिवार्य रूप से पूरे इनपुट को पार्सर स्टैक पर स्थानांतरित कर देगा और फिर एक समय में एक वाक्य को कम करेगा।

एक और refactor आप [sentenceList] में [Text] और [] निर्माणों नियम के अंतर्गत होगा कर सकता है:

sentence: /* empty */ 
     | sentence Text 
     | sentence '[' sentenceList ']' 
     ; 

sentenceList: sentence 
      | sentenceList ',' sentence 

तो अब एक sentenceList एक या अधिक अल्पविराम (दो या अधिक के बजाय) द्वारा अलग वाक्य है, और sentence '[' sentenceList ']' नियम के लिए कार्रवाई में, आप यह देखने के लिए sentenceList देखेंगे कि यह दो या अधिक वाक्य था और उचित तरीके से कार्य करता है।

+0

ग्रेट उत्तर। और मुझे आपके द्वारा जोड़े गए सुझाव पसंद हैं - जिन्होंने उन कार्यों में अधिक प्रसंस्करण के लिए अपना दिमाग खोला, उस बारे में सोचा नहीं था। मैं अभी भी इसे सभी काम करने पर काम कर रहा हूं। नियम उपस्थिति का आदेश क्या मायने रखता है? –

+0

आपने मुझे यह भी महसूस करने में मदद की कि संघर्ष समाधान समाधानों के लिए कार्रवाई वास्तव में आवश्यक नहीं है। –

+0

मैंने व्याकरण को अपडेट किया - मैं अभी भी इसे नहीं देख सकता। –