2010-04-19 12 views
8

मैं जीएनयू बाइसन 2.4.2 का उपयोग कर रहा हूं ताकि एक नई भाषा के लिए व्याकरण लिख सकूं और मैं एक प्रश्न पूछूं। जब मैं एक नियम निर्दिष्ट, मान लें:, तो मैं शासन पर एक बदलाव हैबाइसन: एक नियम में वैकल्पिक टोकन

statement : T_CLASS T_IDENT '{' T_CLASS_MEMBERS '}' { 
      // create a node for the statement ... 
} 

उदाहरण के लिए

statement : T_CLASS T_IDENT T_EXTENDS T_IDENT_LIST '{' T_CLASS_MEMBERS '}' { 
      // create a node for the statement ... 
} 

कहाँ (फ्लेक्स स्कैनर नियमों से):

"class"      return T_CLASS; 
"extends"     return T_EXTENDS; 
[a-zA-Z\_][a-zA-Z0-9\_]* return T_IDENT; 

(और T_IDENT_LIST अल्पविराम से अलग पहचानकर्ताओं के लिए एक नियम है)।

क्या यह सब केवल एक नियम में निर्दिष्ट करने का कोई तरीका है, किसी भी तरह से "T_EXTENDS T_IDENT_LIST" को वैकल्पिक रूप से सेट करना? मैं पहले से ही

T_CLASS T_IDENT (T_EXTENDS T_IDENT_LIST)? '{' T_CLASS_MEMBERS '}' { 
    // create a node for the statement ... 
} 

साथ की कोशिश की है लेकिन बाइसन मुझे एक त्रुटि दे दी है।

धन्यवाद

उत्तर

9

एक लंबी कहानी कम करने के लिए, नहीं। बाइसन केवल एलएएलआर (1) व्याकरण से संबंधित है, जिसका अर्थ है कि यह केवल लुकहेड के प्रतीक का उपयोग करता है। आपको इसकी आवश्यकता कुछ है:

statement: T_CLASS T_IDENT extension_list '{' ... 

extension_list: 
       | T_EXTENDS T_IDENT_LIST 
       ; 

अन्य पार्सर जेनरेटर हैं जो अधिक सामान्य व्याकरण के साथ काम करते हैं। यदि स्मृति कार्य करता है, तो उनमें से कुछ अपेक्षाकृत सीधे वैकल्पिक तत्वों का समर्थन करते हैं जैसे आप पूछ रहे हैं।

+0

यह केवल एक नियम लिखने का समाधान था। :) धन्यवाद! –

+0

इसका एलएएलआर (1) होने के साथ कुछ लेना देना नहीं है, क्योंकि दोनों एलएएलआर (1) हैं। इसका कारण यह है कि इनपुट सिंटैक्स बीएनएफ ईबीएनएफ नहीं है। –

+1

@ChrisDodd: क्षमा करें, लेकिन गलत है। यहां समस्या यह है कि जैसे ही उन्होंने लिखा था, उनके पार्सर को टीआईएलएलएसएस और टी_आईडीएनटी में तीन प्रतीकों को देखना होगा, यह देखने के लिए कि अगला प्रतीक '{'या T_EXTENDS था, जो देखने के लिए' कथन 'भिन्नता है। वह एलएएलआर (1) का उल्लंघन कर रहा है। ईबीएनएफ मेरे लिए एक पूर्ण लाल-हेरिंग जैसा दिखता है - मुझे कुछ भी नहीं दिखता है जो प्रश्न में कहीं भी ईबीएनएफ जैसा दिखता है। –

0

मुझे लगता है कि सबसे आप कर सकते हैं

statement : T_CLASS T_IDENT '{' T_CLASS_MEMBERS '}' 
    | T_CLASS T_IDENT T_EXTENDS T_IDENT_LIST '{' T_CLASS_MEMBERS '}' { 
} 
0

है आप क्यों नहीं बस उन्हें पसंद (|) ऑपरेटर का उपयोग विभाजित नहीं है?

statement: 
    T_CLASS T_IDENT T_EXTENDS T_IDENT_LIST '{' T_CLASS_MEMBERS '}' 
    | T_CLASS T_IDENT '{' T_CLASS_MEMBERS '}' 

मुझे नहीं लगता कि आप यह कर सकते हैं सिर्फ इसलिए कि यह एक LALR (1) नीचे-ऊपर पार्सर है, तो आप कुछ अलग की आवश्यकता होगी एक डालूँगा (के) (ANTLR?) तुम क्या चाहते करने के लिए की तरह करने के लिए ..

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