2017-03-31 8 views
2

pyparsing 라이브러리를 사용하여 표현식에서 산술적 우선 순위에 따라 괄호를 만드는 파서를 만드는 방법은 무엇입니까? 예를 들어 *+보다 높은 우선 순위를 갖습니다.산술 우선 순위에 따라 괄호를 만드는 파이썬 파서

그것은 다음과 같이 수행해야합니다

»> print(wholeexp.parseString('3+5-2')) 
[[['3', '+', '5'], '-', '2']] 
»> print(wholeexp.parseString('3+(5-2)')) 
[['3', '+', ['5', '-', '2']]] 
»> print(wholeexp.parseString('3+5-2*4')) 
[[['3', '+', '5'], '-', ['2', '*', '4']]] 

나는 다음을 시도했지만 그것은 아주 잘 작동하지 않습니다. 내가 많이 알고 있지만 "토큰 클래스 생성을 간소화"섹션의 하단으로 스크롤 Simple Top-Down Parsing in Python 당신은 행동에 표시됩니다

from pyparsing import * 

numb = Word(nums) 
leftpar = Suppress('(') 
rightpar = Suppress(')') 

expr = Forward() 
expr << Or([numb, 
    Group(leftpar + expr + "+" + expr + rightpar), 
    Group(leftpar + expr + "-" + expr + rightpar), 
    Group(leftpar + expr + "*" + expr + rightpar)]) 

wholeexp = expr + StringEnd() 
+0

[이 문서] (https://pyparsing.wikispaces.com/file/view/SimpleCalc.py)를 확인 했습니까? –

+0

recursive descent parser가 도움이 될 것입니다 : https://en.wikipedia.org/wiki/Recursive_descent_parser. 또는 Shunting-yard 알고리즘 : https://en.wikipedia.org/wiki/Shunting-yard_algorithm. 하지만 우선이 질문을보고 선택할 선택을하십시오. http://stackoverflow.com/questions/28256/equation-expression-parser-with-precedence. – rajah9

답변

0

이 문서에서는 유망한 보인다 : 우리는 어떻게 EXPR 여기 변경해야합니다. 나는 개인적으로 오류로 인해 작동하지 않을 수 있었다 : AttributeError: 'generator' object has no attribute 'next'하지만 나는 다음 메소드가 파이썬 3.0에서 변경되었다는 사실과 꽤 관련이 있다고 확신한다. 코드가 문제를 이해하고 해결하는 데 복잡하기는하지만 운이 더 좋을 수도 있습니다.

편집 : 파이썬 2.7에서 실행하고 작동했습니다. 이전 버전의 Python에서 실행하거나 코드를 통해 수정 해보십시오.

+0

다른 변형? – parYosef

1

귀하의 접근 방식은이 pyparsing 예에서 사용 된 것과 비슷합니다 : http://pyparsing.wikispaces.com/file/view/fourFn.py. 그러나 operatorPrecedence를 소개 대한 파싱의 최신 버전은 최근 infixNotation 이름을 변경하고 4 기능 산술 표현식 파서는 다음과 같습니다

여기
import pyparsing as pp 

integer = pp.pyparsing_common.integer() 

four_fn_arith_expr = pp.infixNotation(integer, 
            [ 
             # leading sign 
             (pp.oneOf("+ -"), 1, pp.opAssoc.RIGHT,), 
             # multiplication and division 
             (pp.oneOf("* /"), 2, pp.opAssoc.LEFT,), 
             # addition and subtraction 
             (pp.oneOf("+ -"), 2, pp.opAssoc.LEFT,), 
            ]) 

테스트 케이스는이 파서 실행됩니다

tests = """ 
    3+5-2 
    3+(5-2) 
    3+5--2 
    3+5-2*4 
    """ 
four_fn_arith_expr.runTests(tests, fullDump=False) 

제공 :

3+5-2 
[[3, '+', 5, '-', 2]] 

3+(5-2) 
[[3, '+', [5, '-', 2]]] 

3+5--2 
[[3, '+', 5, '-', ['-', 2]]] 

3+5-2*4 
[[3, '+', 5, '-', [2, '*', 4]]] 
+0

파서는 왼쪽에서 오른쪽으로 그리고 산술 연산 후에 필요합니다. 우선 순위에 따라 괄호를 만들 것이다. »print (wholeexp.parseString ('3 + 5-2')) [인쇄용 (wholeexp)] [[[ '3', '+', '5']] . ('3', '+', [ '5', '-', '2']]] »print (wholeexp.parseString (' 3 + 5-2 * 4 ')) print (expr (3 + 5-2 * 4')) .parseString ('3 + 5-4-2')) [[[[ '3', '+', '5'], '-', '4'], '-', '2']] 전달 기능 및 특정 기능 사용. 도와주세요, 고마워요! – parYosef

+0

이 나머지 변형은 OP의 연습 문제로 남습니다. – PaulMcG