2010-11-10 21 views
9

मैं वीसीडी (वैल्यू चेंज डंप) फ़ाइलों को पार्स करने के लिए पाइपर्सिंग का उपयोग कर रहा हूं। अनिवार्य रूप से, मैं फ़ाइलों में पढ़ना चाहता हूं, इसे एक आंतरिक शब्दकोश में पार्स करना चाहता हूं, और मानों में हेरफेर करना चाहता हूं।पाइपर्सिंग, फॉरवर्ड, और रिकर्सन

संरचना पर विवरण में जाने के बिना, मेरी समस्या नेस्टेड श्रेणियों की पहचान करने के साथ होता है।

वीसीडी फ़ाइलों में, आप 'स्कोप' जो तारों और संभवतः कुछ गहरी (नेस्टेड) ​​शामिल है scopes। उनके स्तर के बारे में सोचो।

मेरी फाइल में

तो, मेरे पास है:

$scope module toplevel $end 
$scope module midlevel $end 
$var wire a $end 
$var wire b $end 
$upscope $end 
$var wire c $end 
$var wire d $end 
$var wire e $end 
$scope module extralevel $end 
$var wire f $end 
$var wire g $end 
$upscope $end 
$var wire h $end 
$var wire i $end 
$upscope $end 

तो 'उच्चस्तरीय' सब कुछ शामिल हैं (एक - मैं), 'midlevel' है (a - b), 'extralevel' है (च - छ)

scope_header = Group(Literal('$scope') + Word(alphas) + Word(alphas) + \ 
        Literal('$end')) 

wire_map = Group(Literal('$var') + Literal('wire') + Word(alphas) + \ 
       Literal('$end')) 

scope_footer = Group(Literal('$upscope') + Literal('$end')) 

scope = Forward() 
scope << (scope_header + ZeroOrMore(wire_map) + ZeroOrMore(scope) + \ 
      ZeroOrMore(wire_map) + scope_footer) 

अब, मैं क्या सोचा होता है कि के रूप में यह प्रत्येक गुंजाइश मारता है, यह प्रत्येक स्तर का ट्रैक रखने होता है:, आदि

यहाँ इस खंड पार्स करने के लिए मेरे कोड (स्निपेट) है ' और मैं नेस्टेड स्कॉप्स वाली संरचना के साथ समाप्त हो जाऊंगा। हालांकि, यह

$scope module extralevel $end 

पर बाहर त्रुटियों और कहा कि यह उम्मीद '$ upscope'।

तो मैं जानता हूँ कि मैं सही ढंग से प्रत्यावर्तन का उपयोग नहीं कर रहा हूँ। क्या कोई मेरी मदद कर सकता है? अगर मुझे और जानकारी प्रदान करने की ज़रूरत है तो मुझे बताएं।

धन्यवाद !!!!

उत्तर

9

अपनी परिभाषा के अनुसार, एक गुंजाइश एक और गुंजाइश है, कुछ नक्शे के बाद, एक और गुंजाइश के बाद नहीं हो सकते।

पार्सर ने एक डीबग मोड जहां यह अपने पार्स पेड़ प्रिंट है, तो आप इस तुरंत देखने के लिए सक्षम हो जाएगा। लेकिन संक्षेप में, आप कह रहे हैं कि शून्य या अधिक मानचित्र हैं, इसके बाद शून्य या अधिक स्कॉप्स हैं, इसके बाद शून्य या अधिक मानचित्र हैं, इसलिए यदि कोई गुंजाइश है, तो मानचित्र के बाद, आप पहले ही स्कोप फ़ील्ड पास कर चुके हैं, इसलिए कोई और स्कोप अमान्य हैं। pyparsing समर्थन द्वारा प्रयुक्त भाषा "या" आप इस्तेमाल कर सकते हैं, तो:

scope << (scope_header + ZeroOrMore((wire_map | scope)) + scope_footer) 
+1

अच्छा अंतर्ज्ञान! पाइपर्सिंग वास्तव में "या" का समर्थन करता है, और सटीक वाक्यविन्यास के साथ आपने अनुमान लगाया है। – PaulMcG

+0

वाह, इतना आसान !!! यह एक सम्मोहन की तरह काम करता है!!!!! बहुत बहुत धन्यवाद! – RaytheonLiszt

+0

यह हमेशा अच्छा होता है जब आप इसे देखने के बिना वाक्यविन्यास का अनुमान लगा सकते हैं। अधिभार आपको $$ में काट सकता है, बूस्ट स्पिरिट (सी ++ के लिए पाइपरसे के बराबर) का उपयोग करके प्रोग्राम को डीबग करने का प्रयास करें। यह सी ++ डीबग करने का मजाक है, लेकिन हर विधि कॉल बीस ओवरलोडेड ऑपरेटर गहरे हैं। –

6

कृपया चुनें @ सही एक के रूप में ZackBloom का जवाब, वह इसे सही बंद आभास हो, यहां तक ​​कि pyparsing की वाक्य रचना को जानने के बिना।

बस कुछ टिप्पणी/अपने व्याकरण पर सुझाव:

जवाब ऊपर पोस्ट के साथ

, आप नेस्टिंग ParseResults पर pprint और pyparsing के asList() पद्धति का उपयोग करके कल्पना कर सकते हैं:

res = scope.parseString(vcd) 

from pprint import pprint 
pprint(res.asList()) 

देते:

[[['$scope', 'module', 'toplevel', '$end'], 
    [['$scope', 'module', 'midlevel', '$end'], 
    ['$var', 'wire', 'a', '$end'], 
    ['$var', 'wire', 'b', '$end'], 
    ['$upscope', '$end']], 
    ['$var', 'wire', 'c', '$end'], 
    ['$var', 'wire', 'd', '$end'], 
    ['$var', 'wire', 'e', '$end'], 
    [['$scope', 'module', 'extralevel', '$end'], 
    ['$var', 'wire', 'f', '$end'], 
    ['$var', 'wire', 'g', '$end'], 
    ['$upscope', '$end']], 
    ['$var', 'wire', 'h', '$end'], 
    ['$var', 'wire', 'i', '$end'], 
    ['$upscope', '$end']]] 

तो अब आपके पास अच्छी तरह से संरचित परिणाम हैं। लेकिन आप चीजों को थोड़ा सा साफ कर सकते हैं। एक बात के लिए, अब आपके पास संरचना है, आपको वास्तव में उन सभी $scope, $end, आदि टोकन की आवश्यकता नहीं है। जब आप पार्स किए गए परिणामों के माध्यम से नेविगेट करते हैं तो आप निश्चित रूप से उन पर कदम उठा सकते हैं, लेकिन आप पाइपर्सिंग को पार्स आउटपुट से भी छोड़ सकते हैं (क्योंकि परिणाम अब संरचित हैं, आप वास्तव में कुछ भी खो नहीं रहे हैं)।(समूह scope_footer आवश्यकता नहीं है - कि अभिव्यक्ति में सब कुछ दबा दिया जाता है, तो Group केवल आपके एक खाली सूची देना होगा।)

SCOPE, VAR, UPSCOPE, END = map(Suppress, 
           "$scope $var $upscope $end".split()) 
MODULE, WIRE = map(Literal, "module wire".split()) 

scope_header = Group(SCOPE + MODULE + Word(alphas) + END) 
wire_map = Group(VAR + WIRE + Word(alphas) + END) 
scope_footer = (UPSCOPE + END) 

और अब आप अधिक स्पष्ट रूप से देख सकते हैं: करने के लिए आप पार्सर निर्धारण न तो बदल वास्तव में महत्वपूर्ण बिट्स:

[[['module', 'toplevel'], 
    [['module', 'midlevel'], ['wire', 'a'], ['wire', 'b']], 
    ['wire', 'c'], 
    ['wire', 'd'], 
    ['wire', 'e'], 
    [['module', 'extralevel'], ['wire', 'f'], ['wire', 'g']], 
    ['wire', 'h'], 
    ['wire', 'i']]] 

बहुत ज्यादा समूहीकरण के जोखिम पर, मैं भी सुझाव है कि Group अपने scope अभिव्यक्ति की सामग्री ing, इस तरह:

scope << Group(scope_header + 
       Group(ZeroOrMore((wire_map | scope))) + 
       scope_footer) 

जो इन परिणाम देता है: मॉड्यूल शीर्ष लेख, और तार या subscopes की एक सूची:

[[['module', 'toplevel'], 
    [[['module', 'midlevel'], [['wire', 'a'], ['wire', 'b']]], 
    ['wire', 'c'], 
    ['wire', 'd'], 
    ['wire', 'e'], 
    [['module', 'extralevel'], [['wire', 'f'], ['wire', 'g']]], 
    ['wire', 'h'], 
    ['wire', 'i']]]] 

अब हर गुंजाइश परिणाम 2 उम्मीद के मुताबिक तत्व है।

res = scope.parseString(vcd) 
def dumpScope(parsedTokens, indent=''): 
    module,contents = parsedTokens 
    print indent + '- ' + module[1] 
    for item in contents: 
     if item[0]=='wire': 
      print indent + ' wire: ' + item[1] 
     else: 
      dumpScope(item, indent+' ') 
dumpScope(res[0]) 

जो बाहर की तरह लग रही आता है: अनुमानित यह बहुत आसान पुनरावर्ती कोड है कि परिणाम पर ले जाएगा, लिखने के लिए कर देगा

- toplevel 
    - midlevel 
    wire: a 
    wire: b 
    wire: c 
    wire: d 
    wire: e 
    - extralevel 
    wire: f 
    wire: g 
    wire: h 
    wire: i 

अच्छा पहला सवाल, अतः करने के लिए और pyparsing स्वागत करते हैं!

+0

इस पॉल के लिए आपको बहुत बहुत धन्यवाद !! यह वास्तव में मुझे अपने व्याकरण को साफ करने में मदद करेगा और मैं परिणामों का उपयोग कैसे करूंगा, और अब मैं समझ रहा हूं कि क्या हो रहा है। और मुझे बस इतना जोड़ना है कि पाइपर्सिंग कमाल है! :) – RaytheonLiszt

1

मुझे पता है कि यह एक पुराना सवाल है जिसका उत्तर पहले ही दिया जा चुका है, लेकिन मैंने सोचा कि मैं एक पायथन वीसीडी पार्सिंग पैकेज के लिए एक उपयोगी लिंक जोड़ूंगा जो आपके वीसीडी को मूल पायथन डेटा संरचना में डाल सकता है।

Verilog_VCD 1.0

+0

धन्यवाद @ स्कॉट चिन! उपयोगी लग रहा है। – RaytheonLiszt