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
, Sequence
및 Alternation
의 몸을 구현해야합니다. pyparsing에서 바로 값 목록을 얻지는 않을 것이고, 대신이 객체 유형 중 하나를 되 찾을 것입니다. 위의 예제 에서처럼 asList()
을 호출하는 대신 generate
또는 makeGenerator
과 같은 것을 호출하여 해당 개체에서 생성기를 가져옵니다. 그런 다음 생성기를 호출하여 객체가 서로 다른 결과를 생성하도록합니다.
나는 나머지 연습 문제를 남겨두고 있습니다.
- 폴
','및 '|' 연산자로서, 당신은'infixNotation' 메쏘드로 아주 짧은 순서로 이것을 파싱 할 수 있어야합니다. 구문 분석이 끝나면 이러한 용어를 통해 다양한 경로 조합을 생성하기 위해 결과를 재귀 적으로 처리해야합니다. pyparsing wiki의 invRegex 예제에서 이것이 어떻게 수행되는지보십시오. – PaulMcG
이 방법이 있다는 것을 알았습니다. 답장을 보내 주셔서 감사합니다;) 그것을 조사하십시오. – israkir