2011-02-03 2 views
9

필요한 것은 문자열이 유효한 수학 표현식인지 여부를 파이썬을 사용하여 확인하는 것입니다.수학 구문 검사기가 파이썬으로 작성된 경우

단순화를 위해 숫자와 중첩 된 괄호로 + - * / 연산자 (+ -도 단항으로) 만 필요하다고 가정 해 봅시다. 또한 완성을 위해 간단한 변수 이름을 추가합니다. 나는 pyparsing 그러나 다만 시도하는 예를 시도

test("-3 * (2 + 1)") #valid 
test("-3 * ")  #NOT valid 

test("v1 + v2")  #valid 
test("v2 - 2v")  #NOT valid ("2v" not a valid variable name) 

:

그래서 나는이 방법으로 테스트 할 수 있습니다 내가 잘못된 코드를 통과하고 또한 내가 항상 잘못된 구문이 예외를 발생시키지 않고 구문 분석 얻을 그것을 해결하기 위해 노력 얻을 "simple algebraic expression parser, that performs +,-,*,/ and ^ arithmetic operations"

단지 시도 :

>>>test('9', 9) 
9 qwerty = 9.0 ['9'] => ['9'] 
>>>test('9 qwerty', 9) 
9 qwerty = 9.0 ['9'] => ['9'] 

시험 패스 모두 ... 오 _O

어떤 조언이 필요합니까?

답변

3

이것은 pyparsing 코드가 기능을 허용하기 때문입니다.은 (그건 그렇고, 당신이 스택을 만들고 해당 평가, 즉 필요한 것보다 더 많은 작업을 수행합니다.) 우선 들어

, 내가 바로 누락 다른 piident (그리고 아마도 뭔가를 제거 할 수 있습니다 지금) 코드에서 문자를 허용하지 않습니다.

이유가 다릅니다. PyParsing 파서는 기본적으로 전체 입력을 사용하지 않습니다. + StringEnd()을 추가하고 expr 끝까지 입력해야만 전체 입력을 구문 분석 할 수 없으면 실패합니다. 이 경우 pyparsing.ParseException가 발생합니다. (출처 : http://pyparsing-public.wikispaces.com/FAQs)

약간의 파싱을 배우려면 신경 쓰지 않으면 서 괜찮은 구문 분석 라이브러리 (예 : LEPL)를 사용하면 필요한 것은 30 줄 미만으로 구축 할 수 있습니다.

+0

왜냐하면'pi'는'pi'이고'querty'가 아니고 ident는 단지 괄호 뒤에옵니다. 물론 유효한 구문 검사기로 작동하도록 pyparsing을 얻을 수 있다면 나는 그것을 원합니다. . 나는 LEPL에게도 기회를 줄 것이다. – neurino

+0

@neuriono : 그럼 소스 코드가 오해의 소지가 있고 문법이 실제로 달라 지거나 pyparsing이 깨졌습니다 (편집 : 내가 생각할 수있는 한 가지 설명, "pyparsing is broken"카테고리에 속할 것입니다.). 전체 문자열이 아니라 오히려 종료하고 나머지 입력이 구문 분석에 실패한 경우 지금까지 구문 분석 한 결과를 반환합니다. – delnan

+0

이것은 꽤 분명하지만, 파서 (def BNF())를 작성하는 코드 부분을 보면 매우 간단하고 심지어 _exponentiation_ 부분을 제거하는 것조차도 더 간단하다. 그래서 pyparsing이 좋지 않을 것이라고 생각한다. 문법 검사 중. – neurino

1

왜 그냥 평가하고 구문 오류를 잡을 까? 이 원유 eval보다 약간 더 작업을해야하므로

> print validSyntax('a+b-1') # a, b are undefined, so a NameError arises. 
> False 

> print validSyntax('1 + 2') 
> True 

> print validSyntax('1 - 2') 
> True 

> print validSyntax('1/2') 
> True 

> print validSyntax('1 * 2') 
> True 

> print validSyntax('1 +/ 2') 
> False 

> print validSyntax('1 + (2') 
> False 

> print validSyntax('import os') 
> False 

> print validSyntax('print "asd"') 
> False 

> print validSyntax('import os; os.delete("~\test.txt")') 
> False # And the file was not removed 

그것은 단지 수학 연산에 제한 것 :

from math import * 

def validateSyntax(expression): 
    functions = {'__builtins__': None} 
    variables = {'__builtins__': None} 

    functions = {'acos': acos, 
       'asin': asin, 
       'atan': atan, 
       'atan2': atan2, 
       'ceil': ceil, 
       'cos': cos, 
       'cosh': cosh, 
       'degrees': degrees, 
       'exp': exp, 
       'fabs':fabs, 
       'floor': floor, 
       'fmod': fmod, 
       'frexp': frexp, 
       'hypot': hypot, 
       'ldexp': ldexp, 
       'log': log, 
       'log10': log10, 
       'modf': modf, 
       'pow': pow, 
       'radians': radians, 
       'sin': sin, 
       'sinh': sinh, 
       'sqrt': sqrt, 
       'tan': tan, 
       'tanh': tanh} 

    variables = {'e': e, 'pi': pi} 

    try: 
    eval(expression, variables, functions) 
    except (SyntaxError, NameError, ZeroDivisionError): 
    return False 
    else: 
    return True 

는 여기에 몇 가지 샘플입니다.

+2

이것은 처음 (지금 삭제 된) 답변보다 훨씬 나쁩니다. 적어도 답이 숫자와 연산자로만 구성되어 있는지 확인해야합니다. 너는 abritary code를 허용한다 : ( – delnan

+0

내 업데이트를 확인하십시오. – Blender

+0

수학 연산자와 괄호를 허용하고 싶다면'literal_eval'은 대답이 아닙니다. – delnan

1

산술 표현식의 문자열을 토큰 화하고 트리가 유효하면 잎을 모든 피연산자로, 내부 노드를 모두 연산자로 사용하여 간단하게 파서를 작성하여 표현식 트리를 만들 수 있습니다. 표현이 유효하다는 것.

기본 개념은 파서를 만들기위한 몇 가지 도우미 함수를 만드는 것입니다.당신은 문자 사이에 공백을 보장 할 수있는 경우
get_expression()
get_next_token()

또는 다음 문자를 확인 할 공백이없는 경우

def extract()
def peek() 추출 비슷하지만 사용되는 표현에서 다음 문자를 얻을 것이다 당신 모든 토큰 화 작업을 수행하려면 split()을 사용할 수 있습니다.

그런 다음 당신은 당신의 나무를 구축하고 올바르게

구조화 대한 추가 정보를 원하시면이 취해야 평가 : http://effbot.org/zone/simple-top-down-parsing.htm

+0

이 모든 것을 직접 작성하는 것은 지난 세기의 sooo ... 요즘은 모든 불쾌한 관료주의를 처리하는 파싱 라이브러리를 사용합니다. – delnan

+0

@delnan 공백 문자가 있으면 split()을 사용할 수 있고 필요에 따라 라이브러리가없는 경우 (기능적이지만 너무 크지 않은 등 ...), 그 다음에 무엇을 할 수 있습니까? – Jordan

+0

@ Yoel : 그럼 너는 운이 없으며 propably 너무 높은 기준을 가지고있어. – delnan

1

발리에이 파서 변환됩니다 parseString에 전화로 parseAll=True 추가.

+1

글쎄, 조금 늦었 어. 어쨌든 고마워. – neurino

0

유효성 검사기가되도록 Python으로 작성된 사용자 정의 수학 평가 엔진을 수정하려면 Evaluator 2.0 (Python 3.x) 및 Math_Evaluator (Python 2.x)으로 시작할 수 있습니다. 그들은 기성품 솔루션은 아니지만 읽기 쉬운 Python 코드를 사용하여 정확히 무엇을 하려는지 완전히 사용자 정의 할 수 있습니다. "및"& "또는"는 운영자로 취급됩니다.

관련 문제