2013-06-06 3 views
2

brakets 오류 :구문 분석 파일을 내가 예를 들어, 중괄호로 구분 정보를 가진 파일을 구문 분석 할 필요가

testfile 
Continent 
^ 
Expected "{" (at char 0), (line:1, col:1) 

Traceback (most recent call last): 
    File "xxx.py", line 55, in <module> 
    test('testfile') 
    File "xxx.py", line 40, in test 
    return list 
UnboundLocalError: local variable 'list' referenced before assignment 

이 작업을하려면 어떻게해야합니까? pyparsing보다 나은 다른 파서가 있습니까?

+2

주제에서 벗어나지 만, 파이썬에서 예약되어 있으므로'list'를 변수 이름으로 사용하지 않는 것이 좋습니다 – oleg

+0

재귀 기반 알고리즘으로 You 솔루션을 제안 할 수 있습니다. 그것은 귀하의 요구 사항에 맞습니까 ('{'once와 rsplit '}'로 한 번 전체 데이터 분할. 외부 부분은 반환 된 사전에 대한 키 - 값으로 구문 분석되어야하고 내부 부분은 재귀 함수 자체에 전달되어야합니다. .) – oleg

+1

결과로 무엇이 좋을지 보여주십시오. –

답변

4

재귀문이 여기에 해당합니다. 그 주위에 뭔가를보십시오 :

def parse(it): 
    result = [] 
    while True: 
     try: 
      tk = next(it) 
     except StopIteration: 
      break 

     if tk == '}': 
      break 
     val = next(it) 
     if val == '{': 
      result.append((tk,parse(it))) 
     else: 
      result.append((tk, val)) 

    return result 

사용 사례 : 생산

import pprint  

data = """ 
Continent 
{ 
Name Europe 
Country 
{ 
Name UK 
Dog 
{ 
Name Fiffi 
Colour Gray 
} 
Dog 
{ 
Name Smut 
Colour Black 
} 
} 
} 
""" 

r = parse(iter(data.split())) 
pprint.pprint(r) 

(파이썬 2.6) :

[('Continent', 
    [('Name', 'Europe'), 
    ('Country', 
    [('Name', 'UK'), 
    ('Dog', [('Name', 'Fiffi'), ('Colour', 'Gray')]), 
    ('Dog', [('Name', 'Smut'), ('Colour', 'Black')])])])] 

로만 출발점이 걸릴 및 주시기 바랍니다 필요에 따라 코드를 무료로 개선 할 수 있습니다 (데이터에 따라 사전이 더 나은 선택 일 수 있습니다).가 pyparsing을 발견, 내가 시도 다음 :


편집 - (난 당신이 전체 테스트 커버리지를 할 것을 촉구 특히 추가 또는 } 누락) 또한, 샘플 코드가 제대로 병이 올바른 형식의 데이터를 처리하지 않습니다

import pprint 
from pyparsing import Word, Literal, Forward, Group, ZeroOrMore, alphas 

def syntax(): 
    lbr = Literal('{').suppress() 
    rbr = Literal('}').suppress() 
    key = Word(alphas) 
    atom = Word (alphas) 
    expr = Forward() 
    pair = atom | (lbr + ZeroOrMore(expr) + rbr) 
    expr << Group (key + pair) 

    return expr 

expr = syntax() 
result = expr.parseString(data).asList() 
pprint.pprint(result) 

는 생산 : 어떤 쉽게 특별한 요구 사항에 맞게 조정 (이상) (많이) 작업이 나타납니다 더있을 수

[['Continent', 
    ['Name', 'Europe'], 
    ['Country', 
    ['Name', 'UK'], 
    ['Dog', ['Name', 'Fiffi'], ['Colour', 'Gray']], 
    ['Dog', ['Name', 'Smut'], ['Colour', 'Black']]]]] 
+1

토큰을 분할하기 위해'split()'을 사용하면이 샘플 데이터에서 작동하지만, 모든 입력이 그렇게 형식이 틀린 것은 아닙니다. 예를 들어 후행 중괄호를 "}}}"로 입력하거나 따옴표로 묶은 문자열 안에 중괄호가 들어 있으면'split()'이 실패합니다. – PaulMcG

+0

올바른 @PaulMcGuire입니다. 초기 질문은 전적으로 입력 데이터의 형식을 지정하지 않습니다. 중괄호 주위의 공백에 관해서는 정규식이 트릭을 수행합니다. 문법이 더 복잡한 경우, 예를 들어 인용 된 따옴표가 들어있는 것처럼 -'pyparsing'은 여전히 ​​더 나은 선택이 될 것입니다. –

+0

좋은 결과, 이것은 nestedExpr을 사용하는 것보다 더 엄격한 파서입니다. 키 + 값 관계를 유지합니다. Pyparsing에 오신 것을 환영합니다, Sylvain! – PaulMcG

5

중첩 된 표현식은 매우 일반적이므로 구문 분석 라이브러리를 사용하지 않는 경우 일반적으로 재귀 구문 분석기 정의 또는 재귀 코드가 필요합니다. 이 코드는 초보자에게는 어려울 수 있으며 전문가에게는 오류가 발생하기 쉽기 때문에 nestedExpr 헬퍼를 pyparsing에 추가했습니다.

문제는 입력 문자열에 중첩 된 중괄호 표현식 이상이 있다는 것입니다. 파서를 처음 시도 할 때 테스트를 가능한 한 간단하게 유지하려고합니다. 예를 들어 파일에서 읽는 대신 샘플을 인라인합니다.

test = """\ 
Continent 
{ 
Name Europe 
Country 
{ 
Name UK 
Dog 
{ 
Name Fiffi 
Colour "light Gray" 
} 
Dog 
{ 
Name Smut 
Colour Black 
}}}""" 

from pyparsing import * 

expr = nestedExpr('{','}') 

print expr.parseString(test).asList() 

그리고 난 당신이 같은 구문 분석 오류 얻을 :

Traceback (most recent call last): 
    File "nb.py", line 25, in <module> 
    print expr.parseString(test).asList() 
    File "c:\python26\lib\site-packages\pyparsing-1.5.7-py2.6.egg\pyparsing.py", line 1006, in parseString 
    raise exc 
pyparsing.ParseException: Expected "{" (at char 1), (line:1, col:1) 

그래서, 대한 파싱은 주요 단어에 걸림돌입니다 (심지어는 자신의 디버깅 코드) 오류 메시지를보고 "대륙을 ",이 단어는 중괄호 안에 중첩 된 표현식의 시작이 아니기 때문에 예외 메시지에서 볼 수 있듯이 pyparsing은 '{'을 (를) 찾고 있습니다.

이 솔루션은 약간에 EXPR을 변경하여 소개 "대륙"라벨을 처리하는 파서를 수정하는 것입니다 : 영업에서 수행으로, 이제

expr = Word(alphas) + nestedExpr('{','}') 

pprint를 사용하여 목록 (로 결과를 인쇄 멋진 작품)은 다음과 같습니다.

['Continent', 
['Name', 
    'Europe', 
    'Country', 
    ['Name', 
    'UK', 
    'Dog', 
    ['Name', 'Fiffi', 'Colour', '"light Gray"'], 
    'Dog', 
    ['Name', 'Smut', 'Colour', 'Black']]]] 

중괄호와 일치해야합니다.

+0

필자는이 질문 덕분에 pyparsing을 발견했습니다. 온라인 설명서가 많지는 않았지만 실제로 흥미로운 모듈이었습니다. 중첩 목록 대신 사전을 생성하는 방법이 있습니까? –