1 8 9 15 package tests.jfun.parsec; 16 17 import jfun.parsec.*; 18 import jfun.parsec.pattern.Pattern; 19 import jfun.parsec.pattern.Patterns; 20 import jfun.parsec.tokens.Tokenizers; 21 22 public class Calculator { 23 private interface Operator{ 24 double cal(double a, double b); 25 } 26 private static Binary<Number > toMap2(final Operator op){ 27 return new Binary<Number >(){ 28 public Double map(Number i1, Number i2){ 29 return op.cal(i1.doubleValue(), i2.doubleValue()); 30 } 31 }; 32 } 33 public Parser<Number > getParser(){ 34 final Pattern digits = Patterns.range('0','9').many(1); 35 final Pattern number = digits.seq(Patterns.isChar('.').seq(digits).optional()); 36 final Parser<_> s_number = Scanners.isPattern("number", number, "number expected"); 37 38 final Parser<_> s_line_comment = Scanners.javaLineComment(); 39 final Parser<_> s_block_comment = Scanners.isBlockComment("/*","*/"); 40 final Parser<_> s_whitespace = Scanners.isWhitespaces(); 41 42 final Parser<Tok> l_number = Lexers.lexer(s_number, Tokenizers.forDecimal()); 43 final Terms ops = Terms.getOperatorsInstance("+","-","*","/", "(", ")"); 44 final Parser<_> s_delim = Parsers.sum(s_line_comment, s_block_comment, s_whitespace) 45 .many(); 46 final Parser<Tok> l_tok = Parsers.plus(ops.getLexer(), l_number); 47 final Parser<Tok[]> lexer = Lexers.lexeme(s_delim, l_tok) 48 .followedBy(Parsers.eof()); 49 50 final Operator plus = new Operator(){ 51 public double cal(double n1, double n2){ 52 return n1+n2; 53 } 54 }; 55 final Operator minus = new Operator(){ 56 public double cal(double n1, double n2){ 57 return n1-n2; 58 } 59 }; 60 final Operator mul = new Operator(){ 61 public double cal(double n1, double n2){ 62 return n1*n2; 63 } 64 }; 65 final Operator div = new Operator(){ 66 public double cal(double n1, double n2){ 67 return n1/n2; 68 } 69 }; 70 final Unary<Number > neg = new Unary<Number >(){ 71 public Double map(Number n){ 72 return -n.doubleValue(); 73 } 74 }; 75 final Parser<Tok> p_binary_ops = ops.getParser("+","-","*","/"); 76 final Parser<?> p_whitespace_mul = p_binary_ops.not(); 77 final Parser<Binary<Number >> p_plus = getOperator2(ops, "+", plus); 78 final Parser<Binary<Number >> p_minus = getOperator2(ops, "-", minus); 79 final Parser<Binary<Number >> p_mul = Parsers.sum(ops.getParser("*"), p_whitespace_mul) 80 .seq(Parsers.retn(toMap2(mul))); 81 final Parser<Binary<Number >> p_div = getOperator2(ops, "/", div); 82 final Parser<Unary<Number >> p_neg = getOperator(ops, "-", neg); 83 final Parser<Tok> p_lparen = ops.getParser("("); 84 final Parser<Tok> p_rparen = ops.getParser(")"); 85 final Parser<Number > p_number = Terms.decimalParser(new FromString<Number >(){ 86 public Number fromString(int from, int len, String s){ 87 return Double.valueOf(s); 88 } 89 }); 90 final Parser<Number >[] expr_holder = new Parser[1]; 91 final Parser<Number > p_lazy_expr = Parsers.lazy(expr_holder); 92 final Parser<Number > p_term = Parsers.plus( 93 Parsers.between(p_lparen, p_rparen, p_lazy_expr), 94 p_number 95 ); 96 final OperatorTable<Number > optable = new OperatorTable<Number >() 97 .infixl(p_plus, 10) 98 .infixl(p_minus, 10) 99 .infixl(p_mul, 20) 100 .infixl(p_div, 20) 101 .prefix(p_neg, 30); 102 final Parser<Number > p_expr = Expressions.buildExpressionParser(p_term, optable); 103 expr_holder[0] = p_expr; 104 return Parsers.parseTokens(lexer, p_expr.followedBy(Parsers.eof()), "calculator"); 105 } 106 private static Parser<Binary<Number >> 107 getOperator2(Terms ops, String op, Operator v){ 108 return getOperator(ops, op, toMap2(v)); 109 } 110 private static <T> Parser<T> getOperator(Terms ops, String op, T v){ 111 return ops.getParser(op).seq(Parsers.retn(v)); 112 } 113 } | Popular Tags |