C gibi bir metin formatıyla (braces and semicolons ve tüm bunların dışında) bazı oldukça büyük metin dosyalarını ayrıştırmak için PyParsing kullanıyorum.PyParsing ile artımlı ama eksiksiz ayrıştırma?
PyParsing sadece büyük çalışır, ancak yavaş ve bağlı benim dosyaların boyutuna bellek çok büyük miktarda tüketir.
Bu nedenle, kaynak dosyanın üst düzey öğelerini tek tek ayrıştırdığım bir artımsal ayrıştırma yaklaşımını uygulamak istedim. Püskürtme işleminin scanString
yöntemi, bunu yapmanın açık yolu gibi görünüyor. Ancak, scanString
tarafından ayrıştırılan bölümler arasında geçersiz/ayrıştırılamaz metin olmadığından emin olmak istiyorum ve bunu yapmak için iyi bir yol bulamıyor.
İşte problemi yaşıyorum gösteren basitleştirilmiş bir örnek:
sample="""f1(1,2,3); f2_no_args();
# comment out: foo(4,5,6);
bar(7,8);
this should be an error;
baz(9,10);
"""
from pyparsing import *
COMMENT=Suppress('#' + restOfLine())
SEMI,COMMA,LPAREN,RPAREN = map(Suppress,';,()')
ident = Word(alphas, alphanums+"_")
integer = Word(nums+"+-",nums)
statement = ident("fn") + LPAREN + Group(Optional(delimitedList(integer)))("arguments") + RPAREN + SEMI
p = statement.ignore(COMMENT)
for res, start, end in p.scanString(sample):
print "***** (%d,%d)" % (start, end)
print res.dump()
Çıktı: scanString
tarafından döndürülen
***** (0,10)
['f1', ['1', '2', '3']]
- arguments: ['1', '2', '3']
- fn: f1
***** (11,25)
['f2_no_args', []]
- arguments: []
- fn: f2_no_args
***** (53,62)
['bar', ['7', '8']]
- arguments: ['7', '8']
- fn: bar
***** (88,98)
['baz', ['9', '10']]
- arguments: ['9', '10']
- fn: baz
aralıkları aralarında çözümlenmemiş metni ((0 dolayı boşluklar var, 10), (11,25), (53,62), (88,98)). Bu boşluklardan ikisi, bir hatayı tetiklememesi gereken, boşluk veya yorumlardır, ancak bunlardan biri (this should be an error;
) yakalamak istediğim ayrılmaz bir metin içerir.
Tüm girdinin belirtilen ayrıştırıcı dilbilgisi ile ayrıştırılabildiğinden emin olmakla birlikte, bir dosyayı aşamalı olarak ayrıştırmak için pıhtılaşmayı kullanmanın bir yolu var mı?