java에서 계산기 만들기
https://javacc.java.net/
https://java.net/projects/javacc/downloads/directory/releases/Release%206.1.2
구문 분석에 관련 참고
http://crystalcube.co.kr/149
javacc받아서 압축풀어서 설치
계산기 jj 파일 검색해서 받았습니다.
이걸 바탕으로 수정해나가도록 하겠습니다.
http://read.pudn.com/downloads197/sourcecode/compiler/927244/%E7%A8%8B%E5%BA%8F%E6%BA%90%E7%A0%81%E5%8F%8A%E7%94%9F%E6%88%90%E7%9A%84java%E5%92%8Cclass%E6%96%87%E4%BB%B6/calculator.jj__.htm
makepath.bat 의 내용
set PATH=%PATH%;C:\Program Files\Java\jdk1.8.0_25\bin
build.bat
java -classpath javacc-6.1.2.jar javacc allcalc.jj
javac calculator.java
java calculator
D:\work\개인\Work\android\allcalc>build.bat D:\work\개인\Work\android\allcalc>java -classpath javacc-6.1.2.jar javacc allcal c.jj Java Compiler Compiler Version 6.1_2 (Parser Generator) (type "javacc" with no arguments for help) Reading from file allcalc.jj . . . File "TokenMgrError.java" is being rebuilt. File "ParseException.java" is being rebuilt. File "Token.java" is being rebuilt. File "SimpleCharStream.java" is being rebuilt. Parser generated successfully. D:\work\개인\Work\android\allcalc>javac calculator.java D:\work\개인\Work\android\allcalc>java calculator This is an advanced calculator based on the prior .jj embeded in eclipse Enter an expression like "2.0+3.4 " we support +,-,*,\,(),sin(),cos(),and number with fraction:10+34 44.0 0.1231*23123 2846.4413 231+!2312 Oops. Lexical error at line 3, column 5. Encountered: "!" (33), after : ""
jj파일 중 일부 token 정의 하는 부분이있는데 #표시에 대한 설명
| < NUMBER : <DIGITS> | <DIGITS> "." <DIGITS> | <DIGITS> "." | "."<DIGITS> >
| < #DIGITS : (["0"-"9"])+ >
| < NUMBER : <DIGITS> | <DIGITS> "." <DIGITS> | <DIGITS> "." | "."<DIGITS> >
| < #DIGITS : (["0"-"9"])+ >
When the "#" is present, the regular expression is referred to as a "private regular expression".
private으로 사용하는 토큰이 됩니다. 즉 어디서나 사용못하고 다른 토큰의 정의를 표현할때 사용한다는 의미입니다.
long 처리
http://www.tutorialspoint.com/java/lang/long_parselong_radix.htm
private으로 사용하는 토큰이 됩니다. 즉 어디서나 사용못하고 다른 토큰의 정의를 표현할때 사용한다는 의미입니다.
long 처리
http://www.tutorialspoint.com/java/lang/long_parselong_radix.htm
날짜처리 관련
http://www.yunsobi.com/blog/325
정규식
http://regexr.com/
http://regexr.com/
java 용 변환
http://www.regexplanet.com/advanced/java/index.html
" 처리
http://stackoverflow.com/questions/24156948/javacc-quote-with-escape-character
http://stackoverflow.com/questions/11878392/parsing-strings-with-javacc
지금까지 작업된 소스는 아래와 같습니다.
java에서 testcase로 개발한 소스
주된 내용은 DLValue라는 class 입니다.
float형과 long형의 리턴값을 하나로 관리하기 위한 클래스 입니다.
지금까지 작업된 소스는 아래와 같습니다.
java에서 testcase로 개발한 소스
주된 내용은 DLValue라는 class 입니다.
float형과 long형의 리턴값을 하나로 관리하기 위한 클래스 입니다.
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.TimeZone; import junit.framework.TestCase; public class CalcTest extends TestCase{ public class DLValue { double floatValue; long intValue; boolean bIsFloat; boolean bIsDate; boolean bIsError; boolean bIsBitOverflow; String errorString; public DLValue() { init(); } public DLValue(long value) { set(value); } public DLValue(int value) { set(value); } public DLValue(float value) { set(value); } public DLValue(double value) { set(value); } public void init() { floatValue = 0.0; intValue = 0; bIsFloat = true; bIsDate = false; bIsError = false; errorString = ""; bIsBitOverflow = false; } public void setLong(boolean value) { bIsFloat = value; } public void set(long value) { intValue = value; bIsFloat = false; } public void set(int value) { intValue = (long)value; bIsFloat = false; } public void set(float value) { floatValue = (double)value; bIsFloat = true; } public void set(double value) { floatValue = value; bIsFloat = true; } public boolean getIsFloat() { return bIsFloat; } public void sync() { if( !bIsFloat ){ floatValue = intValue; }else{ intValue = (long)floatValue; } } public void upSync() { sync(); if( !bIsFloat ){ bIsFloat = true; bIsDate = false; } } public void up() { bIsDate = false; bIsFloat = true; } public void down() { bIsFloat = false; } public double getFloatValue() { return floatValue; } public long getIntValue() { return intValue; } public void print() { if( bIsError ){ System.out.println("Error:"+errorString); return; } if( bIsBitOverflow ){ System.out.println("Overflow:"+errorString); } if( bIsFloat ){ System.out.println(getFloatValue()); }else{ System.out.println(getIntValue()); if( bIsDate ){ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); dateFormat.setTimeZone(TimeZone.getTimeZone( "GMT+0" )); Date date = new Date(getIntValue()); String strDate = dateFormat.format(date); System.out.println(strDate); } } } public DLValue parse(String str) { long valuelong = 0; double valuedouble = 0.0; int radix = 10; String newstr = str; if(str.length() > 2 && str.charAt(0)=='0' && str.charAt(1)=='x' ){ newstr = str.substring(2,str.length()); radix = 16; newstr = newstr.trim().replaceAll(" ", ""); newstr = newstr.replaceAll("\\p{Z}", ""); }else if(str.length()>1 && str.charAt(str.length()-1)=='b'){ // remove a last 'b' char newstr = str.substring(0,str.length()-1); radix = 2; newstr = newstr.trim().replaceAll(" ", ""); newstr = newstr.replaceAll("\\p{Z}", ""); } if( radix == 10 ){ try{ valuelong = Long.parseLong(newstr, radix); set(valuelong); return new DLValue(valuelong); }catch(NumberFormatException nfe){ try{ valuedouble = Double.parseDouble(newstr); }catch(NumberFormatException nfe2){ errorString = "NumberFormatException"; bIsError = true; return new DLValue(0); } set(valuedouble); return new DLValue(valuedouble); } }else{ try{ valuelong = Long.parseLong(newstr, radix); }catch(NumberFormatException nfe2){ errorString = "NumberFormatException"; bIsError = true; return new DLValue(0); } set(valuelong); return new DLValue(valuelong); } } public DLValue function(String type, String input1, String input2) { if("date".equals(type)){ SimpleDateFormat dateFormat = new SimpleDateFormat(input1, java.util.Locale.getDefault()); dateFormat.setTimeZone(TimeZone.getTimeZone( "GMT+0" )); Date date; try { date = dateFormat.parse(input2); } catch (Exception e) { errorString = "date function Error"; bIsError = true; return this; } set(date.getTime()); bIsDate = true; } return this; } public long getFactorial(long number) { long factorial = 1; for (long i = 1; i <= number; ++i) { factorial *= i; } return factorial; } public DLValue function(String type) { if("PI".equals(type)){ up(); floatValue = Math.PI; }else if("E".equals(type)){ up(); floatValue = Math.E; }else if("~".equals(type)){ if( bIsFloat ){ errorString = "overflow"; bIsError = true; return this; } intValue = ~intValue; }else if("!".equals(type)){ if( bIsFloat || (intValue > 20)){ errorString = "overflow"; bIsError = true; return this; } intValue = getFactorial(intValue); } return this; } public DLValue function(String type, DLValue input1, DLValue input2) { sync(); input1.sync(); input2.sync(); if("pow".equals(type)){ up(); input1.up(); input2.up(); floatValue = Math.pow(input1.getFloatValue(),input2.getFloatValue()); }else if("atan2".equals(type)){ up(); input1.up(); input2.up(); floatValue = Math.atan2( input1.getFloatValue(),input2.getFloatValue()); }else if("max".equals(type)){ floatValue = Math.max( input1.getFloatValue(),input2.getFloatValue()); intValue = Math.max( input1.getIntValue(),input2.getIntValue() ); }else if("min".equals(type)){ floatValue = Math.min( input1.getFloatValue(),input2.getFloatValue()); intValue = Math.min( input1.getIntValue(),input2.getIntValue() ); }else if("hypot".equals(type)){ up(); input1.up(); input2.up(); floatValue = Math.hypot( input1.getFloatValue(),input2.getFloatValue()); } if( !bIsFloat ) { // Integer if( floatValue - intValue > 1.0E-16 ) { // If difference is greater than 1d, must change type to the float up(); } } return this; } public DLValue function(String type, DLValue input1) { boolean isFloat = bIsFloat | input1.getIsFloat(); boolean onlyInt = false; sync(); input1.sync(); if( isFloat ) { upSync(); input1.upSync(); } if("+".equals(type)){ floatValue = floatValue + input1.getFloatValue(); intValue = intValue + input1.getIntValue(); }else if("-".equals(type)){ floatValue = floatValue - input1.getFloatValue(); intValue = intValue - input1.getIntValue(); }else if("*".equals(type)){ floatValue = floatValue * input1.getFloatValue(); intValue = intValue * input1.getIntValue(); }else if("/".equals(type)){ floatValue = floatValue / input1.getFloatValue(); intValue = intValue / input1.getIntValue(); }else if("sin".equals(type)){ up(); floatValue = Math.sin( input1.getFloatValue() ); }else if("cos".equals(type)){ up(); floatValue = Math.cos( input1.getFloatValue() ); }else if("tan".equals(type)){ up(); floatValue = Math.tan( input1.getFloatValue() ); }else if("asin".equals(type)){ up(); floatValue = Math.asin( input1.getFloatValue() ); }else if("acos".equals(type)){ up(); floatValue = Math.acos( input1.getFloatValue() ); }else if("atan".equals(type)){ up(); floatValue = Math.atan( input1.getFloatValue() ); }else if("toRadians".equals(type)){ up(); floatValue = Math.toRadians( input1.getFloatValue() ); }else if("toDegrees".equals(type)){ up(); floatValue = Math.toDegrees( input1.getFloatValue() ); }else if("exp".equals(type)){ up(); floatValue = Math.exp( input1.getFloatValue() ); }else if("log".equals(type)){ up(); floatValue = Math.log( input1.getFloatValue() ); }else if("log10".equals(type)){ up(); floatValue = Math.log10( input1.getFloatValue() ); }else if("sqrt".equals(type)){ up(); floatValue = Math.sqrt( input1.getFloatValue() ); }else if("cbrt".equals(type)){ up(); floatValue = Math.cbrt( input1.getFloatValue() ); }else if("ceil".equals(type)){ up(); floatValue = Math.ceil( input1.getFloatValue() ); }else if("floor".equals(type)){ up(); floatValue = Math.floor( input1.getFloatValue() ); }else if("rint".equals(type)){ up(); floatValue = Math.rint( input1.getFloatValue() ); }else if("abs".equals(type)){ floatValue = Math.abs( input1.getFloatValue() ); intValue = Math.abs( input1.getIntValue() ); }else if("signum".equals(type)){ up(); floatValue = Math.signum( input1.getFloatValue() ); }else if("sinh".equals(type)){ up(); floatValue = Math.sinh( input1.getFloatValue() ); }else if("cosh".equals(type)){ up(); floatValue = Math.cosh( input1.getFloatValue() ); }else if("tanh".equals(type)){ up(); floatValue = Math.tanh( input1.getFloatValue() ); }else if("|".equals(type)){ if( bIsFloat ){ errorString = "float type is not support"; bIsError = true; return this; } intValue = intValue | input1.getIntValue(); onlyInt = true; }else if("^".equals(type)){ if( bIsFloat ){ errorString = "float type is not support"; bIsError = true; return this; } intValue = intValue ^ input1.getIntValue(); onlyInt = true; }else if("&".equals(type)){ if( bIsFloat ){ errorString = "float type is not support"; bIsError = true; return this; } intValue = intValue & input1.getIntValue(); onlyInt = true; }else if(">>".equals(type)){ if( bIsFloat ){ errorString = "float type is not support"; bIsError = true; return this; } intValue = intValue >> input1.getIntValue(); onlyInt = true; }else if("<<".equals(type)){ if( bIsFloat ){ errorString = "float type is not support"; bIsError = true; return this; } intValue = intValue << input1.getIntValue(); floatValue = floatValue * Math.pow( 2, input1.getIntValue()); if( floatValue - intValue > 1.0E-20 ) { // If difference is greater than 1d, must change type to the float bIsBitOverflow = true; errorString = "<<"; } onlyInt = true; }else if("%".equals(type)){ if( bIsFloat ){ errorString = "float type is not support"; bIsError = true; return this; } intValue = intValue % input1.getIntValue(); onlyInt = true; } if( !isFloat && !onlyInt ) { // Integer if( floatValue - intValue > 1.0E-20 ) { // If difference is greater than 1d, must change type to the float up(); } } return this; } } public void testDLValue() throws ParseException { DLValue dlValue; dlValue = new DLValue(1); assertEquals(dlValue.getIsFloat(),false); dlValue.function("+", new DLValue(1.1)); assertEquals(dlValue.getIsFloat(),true); assertEquals(dlValue.getFloatValue(),2.1d); dlValue = new DLValue(1); dlValue.function("+", new DLValue(100)); assertEquals(dlValue.getIsFloat(),false); assertEquals(dlValue.getIntValue(),101l); dlValue = new DLValue(100000000000000000l); dlValue.function("*", new DLValue(100000000000000000l)); assertEquals(dlValue.getIsFloat(),true); assertEquals(dlValue.getFloatValue(),1.0E34); dlValue = new DLValue(6); dlValue.function("/", new DLValue(3)); assertEquals(dlValue.getIsFloat(),false); assertEquals(dlValue.getIntValue(),2l); dlValue = new DLValue(); dlValue.function("sin", new DLValue(3.141592)); assertEquals(dlValue.getIsFloat(),true); assertTrue(dlValue.getFloatValue()<0.1d); dlValue = new DLValue(); dlValue.function("PI"); assertEquals(dlValue.getIsFloat(),true); assertEquals(dlValue.getFloatValue(),Math.PI); dlValue.function("pow", new DLValue(2), new DLValue(10)); assertEquals(dlValue.getIsFloat(),true); assertEquals(dlValue.getFloatValue(),1024d); dlValue.parse("0xff"); assertEquals(dlValue.getIsFloat(),false); assertEquals(dlValue.getIntValue(),255); dlValue.parse("0xffffffff"); assertEquals(dlValue.getIsFloat(),false); assertEquals(dlValue.getIntValue(),4294967295l); dlValue.parse("0xffffffffff"); assertEquals(dlValue.getIsFloat(),false); assertEquals(dlValue.getIntValue(),0xffffffffffl); dlValue.parse("0x7fffffffffffffff"); assertEquals(dlValue.getIsFloat(),false); assertEquals(dlValue.getIntValue(),0x7fffffffffffffffl); dlValue.parse("0x7f ff ff ff ff ff ff ff"); assertEquals(dlValue.getIsFloat(),false); assertEquals(dlValue.getIntValue(),0x7fffffffffffffffl); dlValue.parse("1111 1111b"); assertEquals(dlValue.getIsFloat(),false); assertEquals(dlValue.getIntValue(),0xffl); dlValue.parse("1111 1111 1111 b"); assertEquals(dlValue.getIsFloat(),false); assertEquals(dlValue.getIntValue(),0xfffl); dlValue.function("date","yyyy-MM-dd HH:mm:ss","1970-01-01 00:00:00"); assertEquals(dlValue.getIsFloat(),false); assertEquals(dlValue.getIntValue(),0l); dlValue.set(10); dlValue.function("~"); assertEquals(dlValue.getIsFloat(),false); assertEquals(dlValue.getIntValue(),~10l); dlValue.set(10); dlValue.function("!"); assertEquals(dlValue.getIsFloat(),false); assertEquals(dlValue.getIntValue(),3628800); dlValue.set(20); dlValue.function("!"); assertEquals(dlValue.getIsFloat(),false); assertEquals(dlValue.getIntValue(),2432902008176640000l); dlValue.set(20); dlValue.function("<<",new DLValue(2)); assertEquals(dlValue.getIsFloat(),false); assertEquals(dlValue.getIntValue(),20<<2); dlValue.set(20); dlValue.function("%",new DLValue(3)); assertEquals(dlValue.getIsFloat(),false); assertEquals(dlValue.getIntValue(),20%3); } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub } }
지금 까지 작업된 완성된 jj 소스를 공개합니다.
// http://read.pudn.com/downloads197/sourcecode/compiler/927244/%E7%A8%8B%E5%BA%8F%E6%BA%90%E7%A0%81%E5%8F%8A%E7%94%9F%E6%88%90%E7%9A%84java%E5%92%8Cclass%E6%96%87%E4%BB%B6/calculator.jj__.htm options { STATIC = false; UNICODE_INPUT = true; } PARSER_BEGIN(calculator) import java.text.SimpleDateFormat; import java.util.Date; import java.util.TimeZone; import java.io.PrintStream ; public class calculator { public class DLValue { double floatValue; long intValue; boolean bIsFloat; boolean bIsDate; boolean bIsError; boolean bIsBitOverflow; String errorString; public DLValue() { init(); } public DLValue(long value) { set(value); } public DLValue(int value) { set(value); } public DLValue(float value) { set(value); } public DLValue(double value) { set(value); } public void init() { floatValue = 0.0; intValue = 0; bIsFloat = true; bIsDate = false; bIsError = false; errorString = ""; bIsBitOverflow = false; } public void setLong(boolean value) { bIsFloat = value; } public void set(long value) { intValue = value; bIsFloat = false; } public void set(int value) { intValue = (long)value; bIsFloat = false; } public void set(float value) { floatValue = (double)value; bIsFloat = true; } public void set(double value) { floatValue = value; bIsFloat = true; } public boolean getIsFloat() { return bIsFloat; } public void sync() { if( !bIsFloat ){ floatValue = intValue; }else{ intValue = (long)floatValue; } } public void upSync() { sync(); if( !bIsFloat ){ bIsFloat = true; bIsDate = false; } } public void up() { bIsDate = false; bIsFloat = true; } public void down() { bIsFloat = false; } public double getFloatValue() { return floatValue; } public long getIntValue() { return intValue; } public void print() { if( bIsError ){ System.out.println("Error:"+errorString); return; } if( bIsBitOverflow ){ System.out.println("Overflow:"+errorString); } if( bIsFloat ){ System.out.println(getFloatValue()); }else{ System.out.println(getIntValue()); if( bIsDate ){ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); dateFormat.setTimeZone(TimeZone.getTimeZone( "GMT+0" )); Date date = new Date(getIntValue()); String strDate = dateFormat.format(date); System.out.println(strDate); } } } public DLValue parse(String str) { long valuelong = 0; double valuedouble = 0.0; int radix = 10; String newstr = str; if(str.length() > 2 && str.charAt(0)=='0' && str.charAt(1)=='x' ){ newstr = str.substring(2,str.length()); radix = 16; newstr = newstr.trim().replaceAll(" ", ""); newstr = newstr.replaceAll("\\p{Z}", ""); }else if(str.length()>1 && str.charAt(str.length()-1)=='b'){ // remove a last 'b' char newstr = str.substring(0,str.length()-1); radix = 2; newstr = newstr.trim().replaceAll(" ", ""); newstr = newstr.replaceAll("\\p{Z}", ""); } if( radix == 10 ){ try{ valuelong = Long.parseLong(newstr, radix); set(valuelong); return new DLValue(valuelong); }catch(NumberFormatException nfe){ try{ valuedouble = Double.parseDouble(newstr); }catch(NumberFormatException nfe2){ errorString = "NumberFormatException"; bIsError = true; return new DLValue(0); } set(valuedouble); return new DLValue(valuedouble); } }else{ try{ valuelong = Long.parseLong(newstr, radix); }catch(NumberFormatException nfe2){ errorString = "NumberFormatException"; bIsError = true; return new DLValue(0); } set(valuelong); return new DLValue(valuelong); } } public DLValue function(String type, String input1, String input2) { if("date".equals(type)){ SimpleDateFormat dateFormat = new SimpleDateFormat(input1, java.util.Locale.getDefault()); dateFormat.setTimeZone(TimeZone.getTimeZone( "GMT+0" )); Date date; try { date = dateFormat.parse(input2); } catch (Exception e) { errorString = "date function Error"; bIsError = true; return this; } set(date.getTime()); bIsDate = true; } return this; } public long getFactorial(long number) { long factorial = 1; for (long i = 1; i <= number; ++i) { factorial *= i; } return factorial; } public DLValue function(String type) { if("PI".equals(type)){ up(); floatValue = Math.PI; }else if("E".equals(type)){ up(); floatValue = Math.E; }else if("~".equals(type)){ if( bIsFloat ){ errorString = "overflow"; bIsError = true; return this; } intValue = ~intValue; }else if("!".equals(type)){ if( bIsFloat || (intValue > 20)){ errorString = "overflow"; bIsError = true; return this; } intValue = getFactorial(intValue); } return this; } public DLValue function(String type, DLValue input1, DLValue input2) { sync(); input1.sync(); input2.sync(); if("pow".equals(type)){ up(); input1.up(); input2.up(); floatValue = Math.pow(input1.getFloatValue(),input2.getFloatValue()); }else if("atan2".equals(type)){ up(); input1.up(); input2.up(); floatValue = Math.atan2( input1.getFloatValue(),input2.getFloatValue()); }else if("max".equals(type)){ floatValue = Math.max( input1.getFloatValue(),input2.getFloatValue()); intValue = Math.max( input1.getIntValue(),input2.getIntValue() ); }else if("min".equals(type)){ floatValue = Math.min( input1.getFloatValue(),input2.getFloatValue()); intValue = Math.min( input1.getIntValue(),input2.getIntValue() ); }else if("hypot".equals(type)){ up(); input1.up(); input2.up(); floatValue = Math.hypot( input1.getFloatValue(),input2.getFloatValue()); } if( !bIsFloat ) { // Integer if( floatValue - intValue > 1.0E-16 ) { // If difference is greater than 1d, must change type to the float up(); } } return this; } public DLValue function(String type, DLValue input1) { boolean isFloat = bIsFloat | input1.getIsFloat(); boolean onlyInt = false; sync(); input1.sync(); if( isFloat ) { upSync(); input1.upSync(); } if("+".equals(type)){ floatValue = floatValue + input1.getFloatValue(); intValue = intValue + input1.getIntValue(); }else if("-".equals(type)){ floatValue = floatValue - input1.getFloatValue(); intValue = intValue - input1.getIntValue(); }else if("*".equals(type)){ floatValue = floatValue * input1.getFloatValue(); intValue = intValue * input1.getIntValue(); }else if("/".equals(type)){ floatValue = floatValue / input1.getFloatValue(); intValue = intValue / input1.getIntValue(); }else if("sin".equals(type)){ up(); floatValue = Math.sin( input1.getFloatValue() ); }else if("cos".equals(type)){ up(); floatValue = Math.cos( input1.getFloatValue() ); }else if("tan".equals(type)){ up(); floatValue = Math.tan( input1.getFloatValue() ); }else if("asin".equals(type)){ up(); floatValue = Math.asin( input1.getFloatValue() ); }else if("acos".equals(type)){ up(); floatValue = Math.acos( input1.getFloatValue() ); }else if("atan".equals(type)){ up(); floatValue = Math.atan( input1.getFloatValue() ); }else if("toRadians".equals(type)){ up(); floatValue = Math.toRadians( input1.getFloatValue() ); }else if("toDegrees".equals(type)){ up(); floatValue = Math.toDegrees( input1.getFloatValue() ); }else if("exp".equals(type)){ up(); floatValue = Math.exp( input1.getFloatValue() ); }else if("log".equals(type)){ up(); floatValue = Math.log( input1.getFloatValue() ); }else if("log10".equals(type)){ up(); floatValue = Math.log10( input1.getFloatValue() ); }else if("sqrt".equals(type)){ up(); floatValue = Math.sqrt( input1.getFloatValue() ); }else if("cbrt".equals(type)){ up(); floatValue = Math.cbrt( input1.getFloatValue() ); }else if("ceil".equals(type)){ up(); floatValue = Math.ceil( input1.getFloatValue() ); }else if("floor".equals(type)){ up(); floatValue = Math.floor( input1.getFloatValue() ); }else if("rint".equals(type)){ up(); floatValue = Math.rint( input1.getFloatValue() ); }else if("abs".equals(type)){ floatValue = Math.abs( input1.getFloatValue() ); intValue = Math.abs( input1.getIntValue() ); }else if("signum".equals(type)){ up(); floatValue = Math.signum( input1.getFloatValue() ); }else if("sinh".equals(type)){ up(); floatValue = Math.sinh( input1.getFloatValue() ); }else if("cosh".equals(type)){ up(); floatValue = Math.cosh( input1.getFloatValue() ); }else if("tanh".equals(type)){ up(); floatValue = Math.tanh( input1.getFloatValue() ); }else if("|".equals(type)){ if( bIsFloat ){ errorString = "float type is not support"; bIsError = true; return this; } intValue = intValue | input1.getIntValue(); onlyInt = true; }else if("^".equals(type)){ if( bIsFloat ){ errorString = "float type is not support"; bIsError = true; return this; } intValue = intValue ^ input1.getIntValue(); onlyInt = true; }else if("&".equals(type)){ if( bIsFloat ){ errorString = "float type is not support"; bIsError = true; return this; } intValue = intValue & input1.getIntValue(); onlyInt = true; }else if(">>".equals(type)){ if( bIsFloat ){ errorString = "float type is not support"; bIsError = true; return this; } intValue = intValue >> input1.getIntValue(); onlyInt = true; }else if("<<".equals(type)){ if( bIsFloat ){ errorString = "float type is not support"; bIsError = true; return this; } intValue = intValue << input1.getIntValue(); floatValue = floatValue * Math.pow( 2, input1.getIntValue()); if( floatValue - intValue > 1.0E-20 ) { // If difference is greater than 1d, must change type to the float bIsBitOverflow = true; errorString = "<<"; } onlyInt = true; }else if("%".equals(type)){ if( bIsFloat ){ errorString = "float type is not support"; bIsError = true; return this; } intValue = intValue % input1.getIntValue(); onlyInt = true; } if( !isFloat && !onlyInt ) { // Integer if( floatValue - intValue > 1.0E-20 ) { // If difference is greater than 1d, must change type to the float up(); } } return this; } } DLValue previousValue; public static void main(String args[]) throws ParseException { calculator parser = new calculator(System.in); while (true) { System.out.println("This is an advanced calculator based on the prior .jj embeded in eclipse"); System.out.print("Enter an expression like \"2.0+3.4 \" we support +,-,*,\\,(),sin(),cos(),and number with fraction:"); try { parser.Start(System.out); } catch (Exception e) { System.out.println("NOK."); System.out.println(e.getMessage()); parser.ReInit(System.in); } catch (Error e) { System.out.println("Oops."); System.out.println(e.getMessage()); break; } } } } /* ORDER () , function, ~, +, - : Primary * / % : 승제 term + - : 가감 sum << >> : shift bit & : and bit ^ : xor bit | : or bit */ PARSER_END(calculator) SKIP : { " " } TOKEN : /* OPERATORS */ { < OR_BIT: "|" > | < XOR_BIT: "^" > | < AND_BIT: "&" > | < RSHIFT_BIT: ">>" > | < LSHIFT_BIT: "<<" > | < PLUS: "+" > | < MINUS: "-" > | < MULTIPLY: "*" > | < DIVIDE: "/" > | < MOD: "%" > | < NOT: "~" > | < LPAREN : "("> | < RPAREN : ")"> | < INTEGER_NUMBER : <DIGITS> > | < FLOATING_NUMBER : <DIGITS> "." <DIGITS> | <DIGITS> "." | "."<DIGITS> | <FLOATING_POINT> > | < #DIGITS : (["0"-"9"])+ > | < SIN: "sin" | "SIN" > | < COS: "cos" | "COS" > | < TAN: "tan" | "TAN" > | < ASIN: "asin" | "ASIN" > | < ACOS: "acos" | "ACOS" > | < ATAN: "atan" | "ATAN" > | < TORADIANS: "toradians" | "TORADIANS" > | < TODEGREES: "todegrees" | "TODEGREES" > | < EXP: "exp" | "EXP" > | < LOG: "log" | "LOG" > | < LOG10: "log10" | "LOG10" > | < SQRT: "sqrt" | "SQRT" > | < CBRT: "cbrt" | "CBRT" > | < CEIL: "ceil" | "CEIL" > | < FLOOR: "floor" | "FLOOR" > | < RINT: "rint" | "RINT" > | < ABS: "abs" | "ABS" > | < SIGNUM: "signum" | "SIGNUM" > | < SINH: "sinh" | "SINH" > | < COSH: "cosh" | "COSH" > | < TANH: "tanh" | "TANH" > | < POW: "pow" | "POW" > | < ATAN2: "atan2" | "ATAN2" > | < MAX: "max" | "MAX" > | < MIN: "min" | "MIN" > | < HYPOT: "hypot" | "HYPOT" > | < PI: "pi" | "PI" > | < MATH_E: "math_e" | "MATH_E" > | < DATE: "date" | "DATE" > | < FDATE: "fdate" | "FDATE" > | < COMMA: "," > | < HEX_NUMBER : "0x"(["0"-"9","A"-"F","a"-"f"," "])+ > | < BIN_NUMBER : (["1","0"])+(["1","0"," "])*"b" > | < STRING : "\"" ( "\\" ~[] //any escaped character | //or ~["\"","\\"] //any character except quote or backslash )* "\"" > | < #FLOATING_POINT : (["0"-"9"])+ "." (["0"-"9"])* (<EXPONENT>)? (["f","F","d","D"])? | "." (["0"-"9"])+ (<EXPONENT>)? (["f","F","d","D"])? | (["0"-"9"])+ <EXPONENT> (["f","F","d","D"])? | (["0"-"9"])+ (<EXPONENT>)? ["f","F","d","D"] > | < #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ > | < EOL : "\n" | "\r" | "\r\n" > } void Start(PrintStream printStream) : {} { ( previousValue = or_bit() <EOL> { previousValue.print(); previousValue.init(); } )* <EOF> } DLValue or_bit() : { DLValue i; DLValue value; } { value=xor_bit() ( <OR_BIT>i=xor_bit(){value.function("|",i);} )* {return value;} } DLValue xor_bit() : { DLValue i; DLValue value; } { value=and_bit() ( <XOR_BIT>i=and_bit(){value.function("^",i);} )* {return value;} } DLValue and_bit() : { DLValue i; DLValue value; } { value=shift_bit() ( <AND_BIT>i=shift_bit(){value.function("&",i);} )* {return value;} } DLValue shift_bit() : { DLValue i; DLValue value; } { value=sum() ( <RSHIFT_BIT>i=sum(){value.function(">>",i);} | <LSHIFT_BIT>i=sum(){value.function("<<",i);} )* {return value;} } DLValue sum() : { DLValue i; DLValue value; } { value=term() ( <PLUS>i=term(){value.function("+",i);} | <MINUS>i=term(){value.function("-",i); } )* {return value;} } DLValue term() : { DLValue i; DLValue value; } { value = Primary()(<MULTIPLY>i = Primary(){ value.function("*",i); } | <DIVIDE>i = Primary(){ value.function("/",i); } | <MOD>i = Primary(){ value.function("%",i); })* { return value ;} } String string() : { Token t ; } { t=<STRING> { return new String(t.image); } } DLValue Primary() : { Token t ; String a,b ; DLValue value,value2; } { t=<BIN_NUMBER> { return new DLValue().parse(t.image); } | t=<HEX_NUMBER> { return new DLValue().parse(t.image); } | t=<INTEGER_NUMBER> { return new DLValue().parse(t.image); } | t=<FLOATING_NUMBER>{ return new DLValue(Double.parseDouble( t.image )) ; } | <PI>{ return new DLValue().function("PI"); } | <MATH_E>{ return new DLValue().function("E"); } | <LPAREN> value=or_bit() <RPAREN>{ return value ; } | <NOT> value=Primary() { return value.function("~"); } | <PLUS> value=Primary(){ return value; } | <MINUS> value=Primary(){ return value.function("*",new DLValue(-1)) ; } | <SIN><LPAREN>value=or_bit()<RPAREN>{ return value.function("sin",value); } | <COS><LPAREN>value=or_bit()<RPAREN>{ return value.function("cos",value); } | <TAN><LPAREN>value=or_bit()<RPAREN>{ return value.function("tan",value); } | <ASIN><LPAREN>value=or_bit()<RPAREN>{ return value.function("asin",value); } | <ACOS><LPAREN>value=or_bit()<RPAREN>{ return value.function("acos",value); } | <ATAN><LPAREN>value=or_bit()<RPAREN>{ return value.function("atan",value); } | <TORADIANS><LPAREN>value=or_bit()<RPAREN>{ return value.function("toRadians",value); } | <TODEGREES><LPAREN>value=or_bit()<RPAREN>{ return value.function("toDegrees",value); } | <EXP><LPAREN>value=or_bit()<RPAREN>{ return value.function("exp",value); } | <LOG><LPAREN>value=or_bit()<RPAREN>{ return value.function("log",value); } | <LOG10><LPAREN>value=or_bit()<RPAREN>{ return value.function("log10",value); } | <SQRT><LPAREN>value=or_bit()<RPAREN>{ return value.function("sqrt",value); } | <CBRT><LPAREN>value=or_bit()<RPAREN>{ return value.function("cbrt",value); } | <CEIL><LPAREN>value=or_bit()<RPAREN>{ return value.function("ceil",value); } | <FLOOR><LPAREN>value=or_bit()<RPAREN>{ return value.function("floor",value); } | <RINT><LPAREN>value=or_bit()<RPAREN>{ return value.function("rint",value); } | <ABS><LPAREN>value=or_bit()<RPAREN>{ return value.function("abs",value); } | <SIGNUM><LPAREN>value=or_bit()<RPAREN>{ return value.function("signum",value); } | <SINH><LPAREN>value=or_bit()<RPAREN>{ return value.function("sinh",value); } | <COSH><LPAREN>value=or_bit()<RPAREN>{ return value.function("cosh",value); } | <TANH><LPAREN>value=or_bit()<RPAREN>{ return value.function("tanh",value); } | <POW><LPAREN>value=or_bit()<COMMA>value2=or_bit()<RPAREN>{ return value.function("pow",value,value2); } | <ATAN2><LPAREN>value=or_bit()<COMMA>value2=or_bit()<RPAREN>{ return value.function("atan2",value,value2); } | <MAX><LPAREN>value=or_bit()<COMMA>value2=or_bit()<RPAREN>{ return value.function("max",value,value2); } | <MIN><LPAREN>value=or_bit()<COMMA>value2=or_bit()<RPAREN>{ return value.function("min",value,value2); } | <HYPOT><LPAREN>value=or_bit()<COMMA>value2=or_bit()<RPAREN>{ return value.function("hypot",value,value2); } | <DATE><LPAREN>a=string()<RPAREN>{ return new DLValue().function("date", "\"yyyy-MM-dd HH:mm:ss\"", a); } | <FDATE><LPAREN>a=string()<COMMA>b=string()<RPAREN>{ return new DLValue().function("date", a, b); } }
실행 화면입니다.
D:\work\개인\Work\android\allcalc>java -classpath javacc-6.1.2.jar javacc allcal c.jj Java Compiler Compiler Version 6.1_2 (Parser Generator) (type "javacc" with no arguments for help) Reading from file allcalc.jj . . . Note: UNICODE_INPUT option is specified. Please make sure you create the parser/ lexer using a Reader with the correct character encoding. File "TokenMgrError.java" is being rebuilt. File "ParseException.java" is being rebuilt. File "Token.java" is being rebuilt. File "SimpleCharStream.java" is being rebuilt. Parser generated successfully. D:\work\개인\Work\android\allcalc>javac calculator.java D:\work\개인\Work\android\allcalc>java calculator This is an advanced calculator based on the prior .jj embeded in eclipse Enter an expression like "2.0+3.4 " we support +,-,*,\,(),sin(),cos(),and number with fraction:PI*1<<6+80 Error:float type is not support 1<<6*PI+80 Error:float type is not support (1<<6)*PI+80 281.06192982974676
댓글 없음:
댓글 쓰기