2013-05-11 1 views
3

정수, 부동 소수점, 연산자, 함수, 변수 및 괄호로 구성된 문자열을 토큰 화하고 싶습니다.복잡한 수학 표현을위한 고급 토크 나이저

현재 상태 :

String infix = 4*x+5.2024*(Log(x,y)^z)-300.12 

원하는 상태 :

String tokBuf[0]=4 
String tokBuf[1]=* 
String tokBuf[2]=x 
String tokBuf[3]=+ 
String tokBuf[4]=5.2024 
String tokBuf[5]=* 
String tokBuf[6]=( 
String tokBuf[7]=Log 
String tokBuf[8]=( 
String tokBuf[9]=x 
String tokBuf[10]=, 
String tokBuf[11]=y 
String tokBuf[12]=) 
String tokBuf[13]=^ 
String tokBuf[14]=z 
String tokBuf[15]=) 
String tokBuf[16]=- 
String tokBuf[17]=300.12 

모든 팁과 솔루션을 주시면 감사하겠습니다 다음의 예는 문제의 본질을 밝게한다. 알고리즘

+2

사용 무언가 (http://www.antlr.org/) 요의 문법을 정의하는 ur 표현식을 생성하고 파서를 생성합니다. –

+0

yacc이 좋은 도구입니다. 대부분 배열보다는 기호의 그래프가 필요합니다. –

+0

표현식 평가기를 만들려면 전에 GNU libmatheval 또는 muParse를 시도하십시오. –

답변

5

자바 스트림 토크 나이저를 사용하십시오. 인터페이스는 약간 이상하다 그러나 사람은 그것에 사용됩니다 :

http://docs.oracle.com/javase/7/docs/api/java/io/StreamTokenizer.html

(당신은 아마 직접 토크 나이를 사용하거나 당신이 할 수 있도록 적어도 개체 목록을 사용하려면 요청 된 문자열 목록에 구문 분석

예제 코드 직접 두 번 같은 상점 수) :

public static List<String> tokenize(String s) throws IOException { 
    StreamTokenizer tokenizer = new StreamTokenizer(new StringReader(s)); 
    tokenizer.ordinaryChar('-'); // Don't parse minus as part of numbers. 
    tokenizer.ordinaryChar('/'); // Don't treat slash as a comment start. 
    List<String> tokBuf = new ArrayList<String>(); 
    while (tokenizer.nextToken() != StreamTokenizer.TT_EOF) { 
    switch(tokenizer.ttype) { 
     case StreamTokenizer.TT_NUMBER: 
     tokBuf.add(String.valueOf(tokenizer.nval)); 
     break; 
     case StreamTokenizer.TT_WORD: 
     tokBuf.add(tokenizer.sval); 
     break; 
     default: // operator 
     tokBuf.add(String.valueOf((char) tokenizer.ttype)); 
    } 
    } 
    return tokBuf; 
} 

테스트 실행 : [ANTLR] 같은

System.out.println(tokenize("4*x+5.2024*(Log(x,y)^z)-300.12")); 
[4.0, *, x, +, 5.2024, *, (, Log, (, x, ,, y,), ^, z,), -, 300.12] 
+0

p.s. github의 내 표현 파서에 관심이있을 수 있습니다 : https://github.com/stefanhaustein/expressionparser –

+0

tokenizer.ordinaryChar ('/')를 추가하고 싶습니다. '/'는 EOF로 처리되고 루프는 조기에 종료됩니다 슬래시 연산자가있는 경우. –

+0

완료. C++ 주석을 인식하면이 기능이 해제됩니까? 대신 reset()을 사용하고 모든 것을 명시 적으로 설정하는 것이 가장 안전 할 수 있습니다 ... –

1

http://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_Form
http://en.wikipedia.org/wiki/Compilers:_Principles,_Techniques,_and_Tools
예 :
1 단계 : 비 NUM 기호에 도달 할 때까지 판독 '4'=> 숫자 토큰 => 읽기 문자 (즉, '*'임)한다. 처음 읽은 것, tokBuf [0]은 숫자 토큰입니다.
2 단계 : 읽기 '*'=> 토큰은 2 진수 연산자를 나타냅니다.
3 단계 : 'x'를 읽습니다. 아마도 함수 기호 => 다음 토큰을 var 토큰으로 표시 할 수 있습니다.
등등.
다음 단계는 평가일까요? 역 폴란드어 표기법이나 구문 트리가 도움이 될 것입니다 ...

관련 문제