2011-12-12 4 views
0

에서 식 트리로 파싱 나는 파일로 식 트리를 인쇄하는 유전자 프로그램이 (쉽게 전환 할 수 있습니다를 사전/사후 /에 - 수정) 그것은 것 같다파이썬

사전에 수정이 될 것입니다 가장 쉬운 구문 분석 그래서 나는 현재 그것을 사용하고 있습니다.

파이썬 2.7을 사용하여이 문자열을 구문 분석하면 어떻게 될까요? 예를 들어, 내가 어떻게 문자열 + (* (2,1), * (4,3)) 2 * 약의 1 + 4 * 3

f = open('expression_tree.txt', 'r') 
input = f.read() 
root_node_operator = input[0] 

까지 그대로 ~~~~ 구문 분석 나는 갔다. 나는 파싱에 익숙하지 않다. 감사!

나는 표현 트리 데이터 구조를 인쇄하는 하나의 파이썬 프로그램을 가지고 있으며, 다음 파이썬 프로그램에서이를 구문 분석하고 평가하려고합니다.

또는 표현 트리 개체를 다음 python 프로그램에 전달하여 구문 분석이 필요하지 않은 방법이 있습니까? GP.py에서는 test_tree라는 트리를 가지고 있습니다. 내 다른 파일 인 MyBot.py에서 어떻게 든 얻을 수 있습니까?

+0

출력에 숫자와 기본 연산 외에 다른 것이 포함되어 있습니까? 그렇다면 유전자 프로그램의 이름은 무엇입니까? (혹시 유전자 프로그램을 의미 했습니까?) – Matt

+0

"표현 트리 데이터 구조"는 어떻게 생겼습니까? 처음부터 파서를 만들거나 더 강력한 라이브러리를 사용하고 싶습니까? 왜 파싱과 평가를 두 파일로 나누고 싶습니까? – poke

답변

2

scheme

$ echo '+(*(2,1),*(4,3))' | sed 's/\(.\)(/(\1 /g; s/,/ /g' | scheme | sed -n '/;Value: /s///p' 

에 다음 파이프, (+ (* 2 1) (* 4 3))으로 +(*(2,1),*(4,3)) 교체 pyparsing을 시도하십시오.

+0

파이프 란 무엇을 의미합니까? – SwimBikeRun

+0

@ user1018733 : 기호'|'는 명령 행에 사용되는 유닉스'pipe' 심볼입니다. 유닉스 명령만으로도 강력하지만, 두 명령을 결합하면 복잡한 작업을 쉽게 수행 할 수 있습니다. Windows'cmd'도'pipe'를 가지고 있지만 사람들은 항상 Windows에서 GUI 도구를 사용합니다. – kev

3

접두어 표기법은 괄호를 필요로하지 않습니다. 문자열의 요소 순서 만 사용하여 작업의 우선 순위를 제어합니다. 예를 들어 2*(1+4)*3을 대신 사용하려는 경우 접두사 표현식은 "* * 2 + 1 4 3"이됩니다.

2*1+4*3"+ * 2 1 * 4 3"이됩니다. split()을 사용하면 연산자 및 피연산자 목록 인 ['+', '*', '2', '1', '*', '4', '3']을 얻을 수 있습니다. 이렇게하면 공백을 무시합니다. 그런 다음이를 평가하려면 재귀 적으로 목록을 살펴보십시오. 연산자를 찾으면 현재 위치에서 시작하여 목록에서 다음 두 개의 피연산자를 가져옵니다. 상수를 발견하면 그것을 반환하십시오. 목록에서 항목을 가져올 때마다 현재 위치를 전진하십시오. 당신이 python를 사용하려면

opns = { 
    '+' : lambda a,b: a+b, 
    '-' : lambda a,b: a-b, 
    '*' : lambda a,b: a*b, 
    '/' : lambda a,b: a/b, 
    } 

def prefix_eval(expr, posn=0): 
    # save current element from expression 
    current = expr[posn] 

    # advance parsing position 
    posn += 1 

    if current in ['+','-','*','/']: 
     # binary operator, get next two operands 
     op1,posn = prefix_eval(expr, posn) 
     op2,posn = prefix_eval(expr, posn) 

     # evaluate operation from current, on operands 
     return opns[current](op1,op2), posn 
    else: 
     # not an operator, must be a numeric value 
     return float(current),posn 

print prefix_eval("+ * 2 1 * 4 3".split())[0] 
print prefix_eval("* * 2 + 1 4 3".split())[0] 

인쇄

14.0 
30.0