Created
August 13, 2012 11:10
-
-
Save pfmiles/3339604 to your computer and use it in GitHub Desktop.
Code for a full-featured calculator in dropincc.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import com.github.pfmiles.dropincc.Action; | |
import com.github.pfmiles.dropincc.CC; | |
import com.github.pfmiles.dropincc.Exe; | |
import com.github.pfmiles.dropincc.Grule; | |
import com.github.pfmiles.dropincc.Lang; | |
import com.github.pfmiles.dropincc.TokenDef; | |
public class Calculator { | |
private static Exe exe = null; | |
/** | |
* <pre> | |
* calc ::= expr $ | |
* expr ::= addend (('+'|'-') addend)* | |
* addend ::= factor (('\*'|'/') factor)* | |
* factor ::= '\d+(\.\d+)?' | |
* | '(' expr ')' | |
* </pre> | |
*/ | |
static { | |
// some elements' pre-definitions in order to call the methods | |
Lang calc = new Lang("Calc"); | |
TokenDef a = calc.newToken("\\+"); | |
TokenDef m = calc.newToken("\\*"); | |
Grule expr = calc.newGrule(); | |
Grule addend = calc.newGrule(); | |
Grule factor = calc.newGrule(); | |
// grammar definition starts here | |
calc.defineGrule(expr, CC.EOF).action(new Action<Object[]>() { | |
public Double act(Object[] ms) { | |
return (Double) ms[0]; | |
} | |
}); | |
expr.define(addend, CC.ks(a.or("\\-"), addend)).action(new Action<Object[]>() { | |
public Double act(Object[] ms) { | |
Double a0 = (Double) ms[0]; | |
Object[] others = (Object[]) ms[1]; | |
for (Object other : others) { | |
Object[] opAndFactor = (Object[]) other; | |
if ("+".equals(opAndFactor[0])) { | |
a0 += (Double) opAndFactor[1]; | |
} else { | |
a0 -= (Double) opAndFactor[1]; | |
} | |
} | |
return a0; | |
} | |
}); | |
addend.define(factor, CC.ks(m.or("/"), factor)).action(new Action<Object[]>() { | |
public Double act(Object[] ms) { | |
Double f0 = (Double) ms[0]; | |
Object[] others = (Object[]) ms[1]; | |
for (Object other : others) { | |
Object[] opAndFactor = (Object[]) other; | |
if ("*".equals(opAndFactor[0])) { | |
f0 *= (Double) opAndFactor[1]; | |
} else { | |
f0 /= (Double) opAndFactor[1]; | |
} | |
} | |
return f0; | |
} | |
}); | |
factor.define("\\d+(\\.\\d+)?").action(new Action<String>() { | |
public Double act(String matched) { | |
return Double.parseDouble(matched); | |
} | |
}).alt("\\(", expr, "\\)").action(new Action<Object[]>() { | |
public Double act(Object[] ms) { | |
return (Double) ms[1]; | |
} | |
}); | |
// grammar definition end | |
exe = calc.compile(); | |
} | |
public static void main(String... args) { | |
System.out.println(exe.eval("1 +2+3+(4 +5*6*7*(64/8/2/(2/1 )/1)*8 +9 )+ 10")); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment