मैं अपने फ्लेक्स में पार्स करने के लिए सी-शैली बहु लाइन टिप्पणी कोशिश कर रहा हूँ (.l) फ़ाइल:फ्लेक्स/बाइसन में बहु-पंक्ति टिप्पणियां इतनी उत्पीड़न क्यों हैं?
%s ML_COMMENT
%%
...
<INITIAL>"/*" BEGIN(ML_COMMENT);
<ML_COMMENT>"*/" BEGIN(INITIAL);
<ML_COMMENT>[.\n]+ { }
मैं किसी भी टोकन और मेरी व्याकरण (.y) टिप्पणियों को संबोधित नहीं करता वापस नहीं कर रहा हूँ किसी भी प्रकार।
जब मैं अपने निष्पादन योग्य चलाने के लिए, मैं एक पार्स त्रुटि मिलती है:
$ ./a.out
/*
abc
def
Parse error: parse error
$ echo "/* foo */" | ./a.out
Parse error: parse error
(मेरे yyerror समारोह एक printf (करता है "पार्स त्रुटि:% s \ n") है, जो जहां की पहली छमाही अनावश्यक त्रुटि संदेश से आता है)।
मैं देख सकता हूं कि दूसरा उदाहरण इनपुट की संपूर्णता क्यों विफल रहता है, और चूंकि व्याकरण द्वारा टिप्पणियों को अनदेखा किया जाता है, इसलिए कोई बयान नहीं है। इस प्रकार इनपुट एक वैध कार्यक्रम नहीं है। लेकिन इससे पहले कि मैं टिप्पणी खत्म करने से पहले पहला भाग एक पार्स त्रुटि फेंकता है।
भी भ्रामक:
$ ./a.out
/* foo */
a = b;
Parse error: parse error
इस मामले में, टिप्पणी से पहले वास्तविक मान्य इनपुट (जो, टिप्पणी के बिना, ठीक से पार्स) के लिए बंद है। विफलता वास्तव में "ए" को पार्स करने के बाद होती है, असाइनमेंट "ए = बी;" को पार्स करने का प्रयास करने के बाद नहीं। अगर मैं अपनी लाइन पर "ए" दर्ज करता हूं, तो यह अभी भी एक त्रुटि फेंकता है।
यह देखते हुए कि त्रुटि संदेश एक पार्सर त्रुटि है और स्कैनर त्रुटि नहीं है, क्या मेरे पास मेरी फ़ाइल में कुछ महत्वपूर्ण है? या क्या मैं अपने स्कैनर नियमों में कुछ गलत कर रहा हूं जो पार्सर साइड पर फैलता है?
संपादित करें: प्रति रूडी के सुझाव @, मैं डिबगिंग के बारे में बदल गया और पाया:
$ ./a.out
Starting parse
Entering state 0
Reading a token: /*
foo
Next token is 44 (IDENTIFER)
Shifting token 44 (IDENTIFER), Entering state 4
Reducing via rule 5 (line 130), IDENTIFER -> identifier
state stack now 0
Entering state 5
मैं डिबगिंग बंद कर दिया और पाया कि /* foo */ = bar;
वास्तव में foo = bar;
रूप में एक ही पार्स करता है। मैं फ्लेक्स 2.5.4 का उपयोग कर रहा हूँ; यह मुझे उन राज्यों के नियमों के बारे में कोई चेतावनी नहीं देता है जिन्हें मैं उपयोग करने का प्रयास कर रहा हूं।
मैं जीएनयू-फ्लेक्स के लिए फ्लेक्स retagged। आपके स्कैनर नियम ठीक दिखते हैं। पार्स त्रुटि पार्सर में अमान्य टोकन इनपुट इंगित करती है। आप कुछ संबंधित बाइसन नियम पोस्ट करना चाह सकते हैं। इसके अतिरिक्त, आपके बाइसन नियमों के अंदर printf() कथन डालना एक अच्छा विचार हो सकता है, इस प्रकार आप देख सकते हैं कि टोकन स्कैनिंग के दौरान पार्सर किस नियम का प्रयास कर रहा है। – Kizaru
अपने स्कैनर के लिए एक अलग परीक्षण दोहन बनाना भी एक अच्छा विचार होगा। इस तरह आप पार्सर दोषों से स्कैनर दोषों को अलग कर सकते हैं। कोई भी स्कैनर-पार्सर सिस्टम इतना जटिल है कि आपको एकीकरण परीक्षण करके अतिरिक्त जटिलता को इंजेक्ट करने की आवश्यकता नहीं है जब आप वास्तव में चाहते हैं कि यूनिट परीक्षण करना ... – bstpierre
जब आप अपने बाइसन में '--debug' ध्वज जोड़ते हैं 'yyparse()' कॉल से पहले 'yydebug = 1' सेट करें, फिर पार्सर लेक्सर से देखे गए प्रत्येक टोकन के लिए डीबग जानकारी निकाल देता है। – Rudi