2013-10-14 6 views
1

내가 이러한 조건으로 중첩 된 괄호가있는 문자열을 구문 분석하고 싶습니다 결과 :중첩 된 괄호 구문 분석의 경우는

  • 요소는 쉼표 ,로 구분 또는 | 바있다.
  • 중첩 괄호 요소는 하나의 영숫자 또는 다른 중첩 괄호 일 수 있습니다.
  • 막대로 연결되는 각 중첩 괄호 요소 | 리터럴은 이전 시퀀스 요소와 쉼표 ,으로 연결된 전달 요소를 해당 중첩 괄호 외부에 결합하는 새로운 시퀀스를 생성합니다.

    (a, b, c)가 반환해야합니다 : a, b, c

    (a, (b | c))가 반환해야합니다 : a, ba, c

    나 그들이 반환해야합니다 입력 문자열과 결과의 예를 줄 수 있도록, 명확히하기 위해

(a, b, (c | (d, e)), f)이 반환해야합니다. a, b, c, fa, b, d, e, f

(a, b, (c | (d, e) | f), g)은 반환해야합니다 : a, b, c, ga, b, d, e, g

(a, b, c, ((d, (e | f)) | (g, h)), i)a, b, f, g은 반환해야합니다 : a, b, c, d, e, ia, b, c, d, f, i

((a | b), c)a, b, c, g, h, i은 반환해야합니다 : a, c과 (파싱보기 위키에서)

+0

','및 '|' 연산자로서, 당신은'infixNotation' 메쏘드로 아주 짧은 순서로 이것을 파싱 할 수 있어야합니다. 구문 분석이 끝나면 이러한 용어를 통해 다양한 경로 조합을 생성하기 위해 결과를 재귀 적으로 처리해야합니다. pyparsing wiki의 invRegex 예제에서 이것이 어떻게 수행되는지보십시오. – PaulMcG

+0

이 방법이 있다는 것을 알았습니다. 답장을 보내 주셔서 감사합니다;) 그것을 조사하십시오. – israkir

답변

2

b, c 당신이 얻을 수있는 infixNotation (이전에는 operatorPrecedence으로 알려짐)을 사용하여 구문 분석 된 문자열입니다. | '' ','보다 우선 순위를 가지고 있다고 가정처럼,이 보일 것이다 :

tests = [ 
    ("(a, b, c)", ["abc"]), 
    ("(a, b | c)", ["ab", "c"]), 
    ("((a, b) | c)", ["ab", "c"]), 
    ("(a, (b | c))", ["ab", "ac"]), 
    ("(a, b, (c | (d, e)), f)", ["abcf","abdef"]), 
    ("(a, b, (c | (d, e) | f), g)", ["abcg", "abdeg", "abfg"]), 
    ("(a, b, c, ((d, (e | f)) | (g, h)), i)", 
     ["abcdei", "abcdfi", "abcghi"]), 
    ("((a | b), c)", ["ac", "bc"]), 
    ] 

for test,expected in tests: 
    # if your expected values *must* be lists and not strings, then 
    # add this line 
    # expected = [list(ex) for ex in expected] 
    result = expr.parseString(test) 
    print result[0].asList() 

:

variable = oneOf(list(alphas.lower())) 
expr = infixNotation(variable, 
      [ 
      (',', 2, opAssoc.LEFT), 
      ('|', 2, opAssoc.LEFT), 
      ]) 

조금 테스트 프레임 워크에 테스트 케이스를 변환, 우리는 적어도 파싱 부분을 테스트 할 수 있습니다

문자열을 파싱하고 결과 구조에 반영된 연산자 우선 순위를 얻는 것이 쉬운 부분입니다. 당신이 정규식 인버터의 예를 따른다면 지금, 당신은 다음과 같이 각각의 분석 비트에 어떤 객체를 첨부해야합니다

class ParsedItem(object): 
    def __init__(self, tokens): 
     self.tokens = tokens[0] 
class Var(ParsedItem): 
    """ TBD """ 
class BinaryOpn(ParsedItem): 
    def __init__(self, tokens): 
     self.tokens = tokens[0][::2] 
class Sequence(BinaryOpn): 
    """ TBD """ 
class Alternation(BinaryOpn): 
    """ TBD """ 

variable = oneOf(list(alphas.lower())).setParseAction(Var) 
expr = infixNotation(variable, 
      [ 
      (',', 2, opAssoc.LEFT, Sequence), 
      ('|', 2, opAssoc.LEFT, Alternation), 
      ]) 

지금 당신이 Var, SequenceAlternation의 몸을 구현해야합니다. pyparsing에서 바로 값 목록을 얻지는 않을 것이고, 대신이 객체 유형 중 하나를 되 찾을 것입니다. 위의 예제 에서처럼 asList()을 호출하는 대신 generate 또는 makeGenerator과 같은 것을 호출하여 해당 개체에서 생성기를 가져옵니다. 그런 다음 생성기를 호출하여 객체가 서로 다른 결과를 생성하도록합니다.

나는 나머지 연습 문제를 남겨두고 있습니다.

- 폴